mac终端报告分段故障

问题描述 投票:1回答:2

我们应该从提供的文件中提取字符串,输出符合预期,但它最终会报告分段错误,我不知道为什么。

    #include<stdio.h>
    #include<string.h>

    int main(int argc, char *argv[]){
        char str[100];
        char f;
        int len = 0;
        FILE *file;
        file = fopen(argv[1],"r");
        //read only here, so use "r"
        if(file==NULL){
            printf("The file doesn't exist.\n");
            return 1;
        }
        while(feof(file)==0){
            //if feof returns 0 it means it havent reaches the end yet
            fread(&f,sizeof(f),1,file);//read in the file
            //printabel character between 32 and 126
            if(f>=32&&f<=126){
                str[len] = f;
                len++;
                continue;//keep doing it(for ->while)
            }
            if(strlen(str)>3){
                //a string is a run of at least 4
                printf("The output is:%s\n",str);
                len=0;//reset
                memset(str, 0, sizeof(str));
                //reset the str so it wont get too big(overflow)
            }
        }
        //close the file and return
        fclose(file);
        return 0;
    }
c segmentation-fault
2个回答
1
投票

这不是真的

   while(feof(file)==0){
        //if feof returns 0 it means it havent reaches the end yet

这是一个非常常见的错误。

如果你有Not read past the end of file,则返回0。它的微妙但重要的细节。您上次阅读的内容可能已经读到文件末尾但未过去。这意味着实际上没有数据可供阅读,但feof()仍将返回0。

这就是您必须测试读取操作的结果的原因。

fread(&f,sizeof(f),1,file);

如果返回零,那么您无法读取任何内容。

这就是为什么你应该构造你的循环来测试读取的结果(而不是feof())。

while (fread(&f,sizeof(f),1,file) == 1)
{
     // You have successfully read an object from the stream
}

1
投票

您的代码有一些基本错误:

  • Why is while ( !feof (file) ) always wrong?
  • 你不检查fread是否返回0,这意味着不能读取更多的字符,但你继续你的算法
  • str不是'\0'终止的,strlen(str)>3在第一次迭代中产生未定义的行为,并且可能在第一次迭代中被评估为真。然后,由于同样的原因,printf也会产生未定义的行为。
  • 不要直接使用ASCII码,难以阅读,你必须在ASCII表中查看32是什么以及什么是126.更好地使用字符常量 if(f>= ' ' && f <= '~'){ ... } 这更容易阅读,您可以立即获得代码的意图。

所以程序可以像这样重写:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]){
    char str[100];
    char f;
    int len = 0;
    FILE *file;
    file = fopen(argv[1],"r");
    //read only here, so use "r"
    if(file==NULL){
        printf("The file doesn't exist.\n");
        return 1;
    }

    memset(str, 0, sizeof str);

    while(fread(&f, sizeof f, 1, file) == 1)
    {
        if(f >= ' ' && f <= '~')
        {
            str[len++] = f;
            continue;
        }

        if(strlen(str) > 3) // or if(len > 3)
        {
            printf("The output is: %s\n", str);
            len = 0;
            memset(str, 0, sizeof str);
        }
    }

    fclose(file);
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.