#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char line[80];
FILE *in = fopen("spooky.csv", "r");
FILE *file1 = fopen("ufos.csv", "w");
FILE *file2 = fopen("disappearances.csv", "w");
FILE *file3 = fopen("others.csv", "w");
while (fscanf(in, "%79[^\n]\n", line) == 1) {
if (strstr(line, "UFO"))
fprintf(file1, "%s\n", line);
else if (strstr(line, "Disappearance"))
fprintf(file2, "%s\n", line);
else
fprintf(file3, "%s\n", line);
}
fclose(file1);
fclose(file2);
fclose(file3);
return 0;
}
此代码返回分段错误的运行时错误。
我在什么硬件上编译这个程序有关系吗?我使用的是带有 Intel Core i7(第 7 代)的 Fedora 38(工作站)。
该问题与
fscanf
格式无关:如错误消息中所示,内部函数 s
的参数 __vfscanf_internal
具有值 0x0
,指示为 FILE *
参数传递了一个空指针.
您应该检查
fopen
是否无法打开文件,并使用有意义的错误消息报告此情况。
另请注意以下备注:
in
。fgets()
代替 fscanf()
格式。fscanf
格式将无法转换 spooky.csv 中的初始空行,如果它是实际的 CSV 文件,则不应发生这种情况。\n
将导致换行符与下一行中的任何初始空白一起被消耗,这可能不是有意的。使用
%79[^\n]%*[\n]
可以避免这种情况,但会消耗后续的空行。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fopen_check(const char *filename, const char *mode) {
FILE *fp = fopen(filename, mode);
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
exit(1);
}
return fp;
}
int main(void) {
char line[80];
FILE *in = fopen_check("spooky.csv", "r");
FILE *file1 = fopen_check("ufos.csv", "w");
FILE *file2 = fopen_check("disappearances.csv", "w");
FILE *file3 = fopen_check("others.csv", "w");
fscanf(in, "%*[\n]"); // skip initial empty lines
while (fscanf(in, "%79[^\n]%*[\n]", line) == 1) {
if (strstr(line, "UFO"))
fprintf(file1, "%s\n", line);
else
if (strstr(line, "Disappearance"))
fprintf(file2, "%s\n", line);
else
fprintf(file3, "%s\n", line);
}
fclose(in);
fclose(file1);
fclose(file2);
fclose(file3);
return 0;
}