我正在编写一个程序,逐行读取文本文件并删除每行中的特定单词,然后将新行打印到另一个文本文件。
我一直在Zeus中遇到分段错误,但我的代码在Visual Studio中运行得很好。我需要在Zeus上运行这个程序,所以我必须找出问题所在。我发现我的一行代码导致了这个问题。请在下面查看。
#include <stdlib.h>
#include <stdio.h>
int main()
{
FILE *myfile;
FILE *des; //store edited text file
char buf[101]; //store line by line
int pos; //the position of the deleted word
char deleted[100] = ""; //store deleted words
char input[100] = ""; //take input file name
char output[100] = ""; //take output file name
printf("Enter the name of the input file: ");
// scanf(" %s", &input);
printf("Enter the name of the output file: ");
//scanf(" %s", &output);
myfile = fopen("Lab6_bad.txt", "r"); //read file
des = fopen("Lab6_good.txt", "w"); //open a file for writing
//check if the text file exists
if (myfile == NULL)
{
printf("The file does not exist.\n");
exit(0);
}
//read text file line by line using fgets()
while (fgets(buf, sizeof(buf), myfile) != NULL)
{
char newline[101] = ""; //store the new line
printf("%s", buf);
buf [sizeof(buf)] ='\ 0'; //终止
//prevent reading the line twice
if (buf[0] == '\n')
{
break;
}
printf("%s", buf);
printf("Enter position of word to delete (Start counting at 0). Enter -1 to skip deletion: ");
scanf(" %d", &pos);
printf("\n");
//not edit a line
if (pos == -1)
{
fprintf(des, "%s\n", buf);
continue;
}
char *token;
int count = 0; //record the current token's position
token = strtok(buf,“”); //获取第一个令牌。问题发生在这里!看起来Zeus不会自动添加'\ 0',所以我在上面添加一行(粗线),但它仍然不起作用
while (token != NULL)
{
if (count == pos)
{
strcat(deleted, token);
strcat(deleted, " ");
}
else
{
strcat(newline, token);
strcat(newline, " ");
}
token = strtok(NULL, " ");
count++;
}
fprintf(des, "%s\n", newline);
}
fclose(myfile);
fclose(des);
printf("%s", deleted);
}
答案 0 :(得分:0)
fgets()
将null终止存储行读取的缓冲区。
您的陈述:buf[sizeof(buf)] = '\0';
实际上会调用未定义的行为!你将NUL字符存储在数组末尾之外。
相反,您不会测试scanf(" %d", &pos);
的返回值。如果标准输入未解析为数字,则会返回0
或可能EOF
并且pos
未初始化,从而导致行为不正确。
更重要的是:您将所有已删除的单词连接到该数组deleted
,但从不检查缓冲区溢出。如果删除太多单词,缓冲区最终会变得太小,并且将调用未定义的行为。