如何解决 C 中文件 i/o 的分段错误

问题描述 投票:0回答:4

我读取了有 911 行的输入文件,并希望在对每一行进行一些更改后将这 911 行复制到输出文件中。

运行此程序时出现分段错误。我怎样才能找出为什么会发生这种情况?

#include<stdio.h>
void main()
{
    int i;
    FILE *fin,*fop;char* str;
    fin=fopen("atk561011.txt","r");
    if(fin=NULL) printf("ip err");
    fop=fopen("svmip.txt","w");
    if(fop=NULL) printf("op err");
    for(i=1;i<=911;i++)
    {
        fgets(str,150,fin);
        if((i>300&&i<=360)||(i>600&&i<=660)) 
            str[7]='1';
        else 
            str[7]='0';
        fputs(str+7,fop);
        putc('\n',fop);
    }
    fclose(fin);
    fclose(fop);
}
file segmentation-fault
4个回答
4
投票

首先,这是错误的:

if(fin=NULL)

应该是:

if (fin == NULL)

(当然,

fop
也是如此)。如果您没有成功打开文件 - 不要只是打印错误,退出,因为您要读取什么?请记住,
printf
的输出是缓冲的,如果出现段错误,您根本不会看到它,即使它在故障之前运行。

另一件事:你不为

str
分配内存,而是用
fgets
写入它。

还有一件事:从文件中读取预定义数量的行可能是一个坏主意。最好从输入中读取,直到文件结尾,或者读取所需的行数。


1
投票

您没有为指针 str 分配任何空间。

将其更改为 char str[/*Max Length 您期望 150? */] 或分配缓冲区。

与此同时,您的代码正在遍历内存 - 因此出现分段错误。


1
投票

这是应该执行此操作的更正代码。

#包括
#定义 MAX_BUF 150
无效主()
{
    整数我;
    文件 *fin,*fop;char* str;
    str = malloc((MAX_BUF * sizeof(char)) + 1);
    如果(str==NULL){
       printf("内存不足
”);
       退出(-1);
    }
    fin=fopen("atk561011.txt","r");
    if(fin == NULL){
        printf("ip 错误");
        退出(-2);
    }
    fop=fopen("svmip.txt","w");
    如果(fop == NULL){
        printf("操作错误");
        退出(-3);
    }
    对于(i=1;i<=911;i++)
    {
        fgets(str,150,fin);
        if((i>300&&i<=360)||(i>600&&i<=660)) 
            str[7]='1';
        else 
            str[7]='0';
        fputs(str+7,fop); 
        // What is that for? should it be
        // fputs(str, fop); ????? 
        // since you're outputting the 7'th character (1/0)?
        putc('\n',fop);
    }
    fclose(fin);
    fclose(fop);
    if (str != NULL) free(str);
}

我添加了逻辑检查以确保文件是否存在,以继续处理。如果不这样做将会导致代码崩溃。因为在原始代码中,如果输入失败或输出失败,您将打印“ip err”,但继续进入

for
循环,这将使执行在这种情况下失败,因为它仍在尝试失败时从不存在的文件句柄读取。

编辑:请参阅代码中上面的注释。您是否尝试根据 300-360 和 600-660 范围内的

i
条件值将 1/0 输出到输出文件中。你能澄清一下吗?应该是这样吗

fputs(str[7], fop);

希望这有帮助, 此致, 汤姆.


0
投票

fin=NULL 和 fop=NULL 都应该使用“等于”运算符。 您将 fin 和 fop 设置为 NULL,而不是检查错误的返回值。

© www.soinside.com 2019 - 2024. All rights reserved.