我制作了一个c程序,该程序可以解析一种称为Rapid的语言的源代码文件,以提取某些我需要在工作中记录的数据。提取的数据将保存到一个csv文件,然后将其格式化为excel工作表。
除了我在下面介绍的此功能之外,所有其他东西都在工作。在某些情况下,我想删除从文件读取的行中的所有空格和制表符,以便将语句作为字符串存储在struct属性中。
该程序没有崩溃,但是当我printf()删除了空格的新行时,其他一些字符被打印出来。
示例“ cmd.exe”,“ PowerShell \ v1.0 \ Modules”,“ igh \ AppData \LocaloYSφo¡”
如果我这样做Printf("%s\n", currentLine);
,它可以正常打印
使用printf("%s\n", removeWhiteSpace(currentLine));
时出现不确定的行为。
这是功能
/******************************************************************
* Takes a string as input, returns it without tabs or spaces
* Used to put whole line into the additional commands
* Attribute
******************************************************************/
static char* removeWhiteSpace(char* string)
{
int i;
int j;
int len = strlen(string);
char ch;
char* result = malloc(sizeof(char)*len+1);
memset(result, 0, sizeof(*result));
j=0;
for (i=0; i<len; i++)
{
ch = string[i];
if ((ch != ' ') && (ch != '\t'))
{
result[j] = ch;
j++;
}
}
result[strlen(result)] = '\0';
return result;
}
此外,我正在使用fgets()从文件中获取行,并且缓冲区的大小为1000。
不需要的字符在文本文件中不存在,至少至少不可见。
谢谢您的时间,如果您需要文本文件或程序的其余部分,我可以提供,但是很长。
此外,我正在使用GCC编译器使用代码块IDE,编译时没有错误或警告。
答案 0 :(得分:2)
memset(result, 0, sizeof(*result));
那是错的。 *result
指的是result
。 result
是char *
,因此它指向char
,并且char
的大小是1。因此该语句将一个char
设置为零。不会将分配的内存的整个块设置为零。
我们将看到,它是不需要的,因此只需删除该语句即可。
result[strlen(result)] = '\0';
此语句无用。 strlen
通过查找数组中的第一个空(零)字符来工作。因此strlen(result)
将报告第一个空字符的位置。然后result[strlen(result)] = '\0';
将该字符设置为零。但这已经是零。因此,此声明永远无法完成任何事情。不仅如此,它还行不通,因为上面的memset
无法将内存设置为零,因此分配的内存中可能没有空字符要查找。在这种情况下,行为不是由C标准定义的。
但是,不需要使用strlen
查找字符串的结尾。我们知道字符串的结尾应该在哪里。对象j
已对写入result
的字符进行计数。因此,也只需删除此行并使用:
result[j] = '\0';
使用
printf("%s\n", removeWhiteSpace(currentLine));
时出现不确定的行为。
那没有任何意义。 “未定义的行为”不是问题。这是缺少的东西。说某事具有“未定义的行为”意味着C标准未定义行为是什么。具有未定义行为的程序可能什么也不打印,可能会打印所需的结果,可能会打印不希望的结果,可能会打印垃圾字符,可能会崩溃并挂起。
说一个程序产生未定义的行为不会告诉任何人发生了什么。相反,您应该对程序的行为进行了特定的描述,例如“程序打印了预期的文本,后跟意外的字符。”复制并粘贴准确的输入和准确的输出会很好。 / p>