简体   繁体   English

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

[英]C line printed from file undefined behavior

I have made ac program that parses through the source code file of a language called rapid to extract certain data that I will need to document at work. 我已经制作了一个ac程序,该程序可以解析一种称为Rapid的语言的源代码文件,以提取某些在工作中需要记录的数据。 the data extracted is saved to a csv file that is then formatted into an excel worksheet. 提取的数据将保存到csv文件,然后将其格式化为excel工作表。

Everything is working except for this function that I have put below. 除了我在下面介绍的该功能之外,其他所有功能都可以正常工作。 In certain scenarios I was wanting to remove all of the spaces and tabs from a line read from a file so that I can store the statement as a string, in a struct attribute. 在某些情况下,我想删除从文件读取的行中的所有空格和制表符,以便将语句作为字符串存储在struct属性中。

The program isn't crashing, but when I printf() the new line with the whitespace removed, some other characters get printed out to. 程序没有崩溃,但是当我用空白删除新行printf()时,其他一些字符被打印出来。

Example "cmd.exe" , "PowerShell\\v1.0\\Modules", "igh\\AppData\\LocaloYSφo¡" 示例“ cmd.exe”,“ PowerShell \\ v1.0 \\ Modules”,“ igh \\ AppData \\LocaloYSφo¡”

If I do Printf("%s\\n", currentLine); 如果我做Printf("%s\\n", currentLine); It prints fine 打印效果很好

When I use printf("%s\\n", removeWhiteSpace(currentLine)); 当我使用printf("%s\\n", removeWhiteSpace(currentLine)); I get the undefined behavior. 我得到未定义的行为。

Here is the function 这是功能

/******************************************************************
*   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;
}

Also, I am using fgets() to get the line from the file, and the size for the buffer is at 1000. 另外,我正在使用fgets()从文件中获取行,并且缓冲区的大小为1000。

The unwanted characters don't exist in the text file, at least not visible anyways. 不需要的字符在文本文件中不存在,至少不可见。

Thank you for your time, and if you need the text file or the rest of the program I can provide it, but it is lengthy. 谢谢您的时间,如果您需要文本文件或程序的其余部分,我可以提供,但是它很长。

Also, I'm using codeblocks IDE using the GCC compiler, I have no errors or warnings when I compile. 另外,我使用的是GCC编译器的代码块IDE,编译时没有错误或警告。

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

That is wrong. 那是错的。 *result is the thing result points to. *resultresult指向的东西。 result is char * , so it points to a char , and the size of a char is 1. So that statement sets one char to zero. resultchar * ,使其指向一个char ,和大小char为1这样的语句设置一个char为零。 It does not set the entire block of allocated memory to zero. 不会将分配的内存的整个块设置为零。

As we will see, it is unneeded, so just delete that statement. 正如我们将看到的,它是不需要的,因此只需删除该语句即可。

result[strlen(result)] = '\\0';

This statement is useless. 这句话没用。 strlen works by finding the first null (zero) character in an array. strlen通过查找数组中的第一个空(零)字符来工作。 So strlen(result) would report where the first null character is. 因此strlen(result)将报告第一个空字符在哪里。 Then result[strlen(result)] = '\\0'; 然后result[strlen(result)] = '\\0'; would set that character to zero. 会将该字符设置为零。 But it is already zero. 但这已经是零。 So this statement can never accomplish anything. 因此,此声明永远无法完成任何事情。 More than that, though, it does not work because the memset above failed to set the memory to zero, so there may be no null character inside the allocated memory to find. 不仅如此,它还行不通,因为上面的memset无法将内存设置为零,因此在分配的内存中可能没有空字符可以查找。 In that case, the behavior is not defined by the C standard. 在这种情况下,行为不是由C标准定义的。

However, there is no need to use strlen to find the end of the string. 但是,无需使用strlen查找字符串的结尾。 We know where the end of the string should be. 我们知道字符串的结尾应该在哪里。 The object j has been counting the characters written to result . 对象j一直在计算要写入result的字符。 So just delete this line too and use: 因此,也只需删除此行并使用:

result[j] = '\0';

When I use printf("%s\\n", removeWhiteSpace(currentLine)); 当我使用printf("%s\\n", removeWhiteSpace(currentLine)); I get the undefined behavior. 我得到未定义的行为。

That does not make any sense. 那没有任何意义。 “Undefined behavior” is not a thing. “未定义的行为”不是问题。 It is a lack of a thing. 这是缺少的东西。 Saying something has “undefined behavior” means the C standard does not define what the behavior is. 说某事具有“未定义的行为”意味着C标准未定义行为是什么。 A program that has undefined behavior may print nothing, it may print a desired result, it may print an undesired result, it may print garbage characters, it may crash, and it may hang. 具有未定义行为的程序可能不会打印任何内容,可能会打印所需的结果,可能会打印不希望的结果,可能会打印垃圾字符,可能会崩溃并挂起。

Saying a program produced undefined behavior does not tell anybody what happened. 说一个程序产生未定义的行为并不能告诉任何人发生了什么。 Instead, you should have written a specific description of the behavior of the program, such as “The program printed the expected text followed by unexpected characters.” A copy-and-paste of the exact input and the exact output would be good. 相反,您应该对程序的行为进行了特定的描述,例如“程序打印了预期的文本,后跟意外的字符。”复制并粘贴准确的输入和准确的输出会很好。

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

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