繁体   English   中英

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

[英]C line printed from file undefined behavior

我已经制作了一个ac程序,该程序可以解析一种称为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,编译时没有错误或警告。

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

那是错的。 *resultresult指向的东西。 resultchar * ,使其指向一个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标准未定义行为是什么。 具有未定义行为的程序可能不会打印任何内容,可能会打印所需的结果,可能会打印不希望的结果,可能会打印垃圾字符,可能会崩溃并挂起。

说一个程序产生未定义的行为并不能告诉任何人发生了什么。 相反,您应该对程序的行为进行了特定的描述,例如“程序打印了预期的文本,后跟意外的字符。”复制并粘贴准确的输入和准确的输出会很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM