我的C程序:
- 接受参数并将其转换为字符串;以及
- 预先安排了一个日期。
我通过一个循环使用C的int数组来表示字符串,从而删除标点符号和大写字母。
当我键入时:
./cprog -md I am cre,ating a .md file
字符串
我期待:
2023_12_15_i_am_cre_ating_a__md_file.md
型
我正在接收:
'2023_12_15_'$''\002'i_am_cre_ating_a__md_file.md'
型
我删除标点符号通过:
for ( int arg = 0; arg < argc; arg++ ){
for ( int let = 0; let < strlen(argv[arg]); let++ ){
if ( !ispunct( argv[arg][let] ) ){
argv[arg][let] = tolower( argv[arg][let] );
} else {
argv[arg][let] = 95;
}
}
strcat( filename, argv[arg] );
}
型
我通过以下方式获取日期:
time_t rawtime = time(NULL);
struct tm *ptm = localtime(&rawtime);
char filename_date[12];
char result[ strlen(filename_date) + strlen(filename) ];
strftime( filename_date, sizeof(filename_date), "%Y_%b_%d", ptm );
sprintf( result, "%s_%s.md", filename_date, filename );
strcpy( filename, result );
create_md( filename );
型
75%的时间以上的代码工作。
25%的情况下,我不知道为什么,代码会在日期和字符串之间产生”'$''\002'。
我认为这是一个开始字符串字符。
如何阻止文件显示为:
'2023_12_15_'$''\002'i_am_cre_ating_a__md_file.md'
型
2条答案
按热度按时间roqulrg31#
有几个问题,都与内存分配有关。
字符串
strlen
的工作方式是阅读内存,直到看到空字节。filename_date
未初始化,这意味着它可能包含任何旧垃圾。strlen(filename_date)
将读取垃圾,直到它碰巧看到空字节。它不知道有多少内存已分配给filename_date
,如果需要,它将继续阅读超过12个字节。它可以返回从0到非常大的任何数字。如果filename_date
包含所有空值,则strlen(filename_date)
将为0,result
将太小而无法同时容纳这两个值filename_date
和filename
导致未定义的行为。你可以使用
sizeof(filename_date)
来解决这个问题。这是第一个问题,这是第二个问题
型
您正在将
result
的内容复制到filename
中,但result
可能包含一个大于filename
为其分配的内存的字符串。这也将导致未定义的行为。您可以通过将
filename
单独保留并将result
直接传递到create_md()
来解决这个问题。代码中可能存在其他内存问题。使用memory sanitizer可以帮助找到这些问题。
0kjbasz62#
我能够调试我的问题。
我使用“ispunct()”遍历char数组以确定内容是否为alpha。然而,我将开始字符串和结束字符串标记从多个字符串复制到一个字符串中。
切换到“if(variable >= 'a' && variable <= 'z')”允许我正确地构建字符串并控制空字符在字符串中的时间。
(感谢所有参与对话的人。您的改进也是成功的一部分)。