c - 从文件未定义行为打印的 C 行
问题描述
我制作了一个 ac 程序,它解析一种称为 rapid 的语言的源代码文件,以提取我在工作中需要记录的某些数据。提取的数据保存到 csv 文件,然后格式化为 Excel 工作表。
除了我在下面放置的这个功能之外,一切都在工作。在某些情况下,我想从从文件读取的行中删除所有空格和制表符,以便我可以将语句作为字符串存储在结构属性中。
程序没有崩溃,但是当我 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 编译器使用 codeblocks IDE,我在编译时没有错误或警告。
解决方案
memset(result, 0, sizeof(*result));
那是错的。*result
是东西result
指向。result
是char *
,所以它指向 a char
,并且 a 的大小char
是 1。所以该语句将 1 设置char
为 0。它不会将整个分配的内存块设置为零。
正如我们将看到的,它是不需要的,所以只需删除该语句。
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 标准没有定义行为是什么。具有未定义行为的程序可能不打印任何内容,可能会打印期望的结果,可能会打印不期望的结果,可能会打印垃圾字符,可能会崩溃,并且可能会挂起。
说程序产生了未定义的行为并不能告诉任何人发生了什么。相反,您应该编写程序行为的具体描述,例如“程序打印了预期的文本,后跟意外的字符”。精确输入和精确输出的复制和粘贴会很好。
推荐阅读
- c# - IsDayLightSavingTime 方法返回相同时区和相同时间的不同值
- mysql - Mysql 5.7 json 列 WHERE IN 未按预期工作
- javascript - 对特定 Discord 频道中的消息做出反应
- r - 将双倍到三倍的空格分开,并保持单个空格不变
- java - Spring批量打开MultipartFile,错误:'阅读器处于'严格'模式'
- sql - sql加入表,不提供完美的结果
- php - 发送电子邮件时防止重复 php mysql
- yocto - 在 Yocto 中,如何包含来自其他配方的头文件
- sql - Studio 3T mongodb聚合问题
- mysql - 查找学习完全相同课程 SQL 的学生列表