[英]C Using char* in fscanf causing error Segmentation fault: 11
我是 C 的新手,在使用fscanf
从 a.txt 文件中读取所有字符串时遇到了一个问题。
代码如下:
#include <stdlib.h>
#include <stdio.h>
int main() {
FILE *spIn;
char *numIn;
spIn = fopen("data.txt", "r");
if (spIn == NULL) {
printf("Can't Open This File \n");
}
while ((fscanf(spIn, "%s", numIn)) == 1) {
printf("%s\n", numIn);
};
fclose(spIn);
return 1;
}
这会引发错误: Segmentation fault: 11
。
txt文件的原始数据为:
1 2 345 rrtts46
dfddcd gh 21
789 kl
整数、字符串、空格和换行符的混合。
至少 4 种可能导致某种故障的候选未定义行为 (UB)。
fscanf(spIn,"%s",numIn)
。fopen()
失败,代码也会调用fscanf()
。fopen()
失败,代码也会调用fclose()
。fscanf(spIn,"%s",numIn))
没有宽度限制,比gets()
差。 文本文件实际上没有字符串( '\0'
终止的数据)也没有int
,它们有行(各种带有'\n'
终止的字符)。
要读取一行并保存为字符串,请使用fgets()
。 不要使用fscanf()
来读取数据行。
#include <stdlib.h>
#include <stdio.h>
int main() {
FILE *spIn = fopen("data.txt", "r");
if (spIn == NULL) {
printf("Can't Open This File \n");
} else {
char buf[100];
while (fgets(buf, sizeof buf, spIn)) {
printf("%s", buf);
}
fclose(spIn);
}
}
char* numIn
是一个指针,它是未初始化的,你不能真正在其中存储任何东西,你需要为其分配 memory 或使其指向某个有效的 memory 位置:
#include<stdlib.h> // for malloc
char* numIn = malloc(100); // space for 99 char + null terminator byte
//...
while ((fscanf(spIn, "%99s", numIn)) == 1)
{
printf("%s\n",numIn);
};
或者:
char str[100];
char *numIn = str;
在这个小代码中没有什么意义,你可能应该让numIn
一个固定大小的数组开始:
char numIn[100];
请注意,您应该在*scanf
中使用宽度说明符以避免缓冲区溢出。 但这仍然有一个问题,它将逐字读取,而不是逐行读取。
查看您的输入文件,使用fgets
似乎是一个更好的选择,它可以读取完整的行,包括空格:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *spIn;
char numIn[100];
spIn = fopen("data.txt", "r");
if (spIn != NULL)
{
while ((fgets(numIn, sizeof numIn, spIn)))
{
numIn[strcspn(numIn, "\n")] = '\0'; // removing \n
printf("%s\n", numIn);
}
fclose(spIn);
}
else
{
perror("Can't Open This File");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
由于fgets
还解析\n
字符,我将使用strcspn
删除它。
尽管您确实验证了fopen
的返回值,但即使无法打开,执行也会继续,但我也解决了这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.