从文件未定义行为打印的C行

时间:2019-07-06 10:42:31

标签: c string file

我制作了一个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,编译时没有错误或警告。

1 个答案:

答案 0 :(得分:2)

  

memset(result, 0, sizeof(*result));

那是错的。 *result指的是resultresultchar *,因此它指向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>