【问题标题】:Segmentation Fault on my while loop我的while循环中的分段错误
【发布时间】:2016-10-29 03:29:52
【问题描述】:

我正在尝试计算我从 argv 指定的文件中的行数和字符数。但是由于某种原因,当我点击 while 循环时出现分段错误。程序在没有 while 循环的情况下运行良好,尽管它只执行一次。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {

    if(argc != 2) {
            return 0;
    }


    FILE *fp;
    char c;
    int lines = 0;
    int chs = 0;
    fp = fopen(argv[1], "r");

    //Segmentation Fault happens here on the while loop
    while((c = fgetc(fp)) != EOF) {
            if(c == '\n') {
                    lines += 1;
            }
            else {
                    chs += 1;
            }

    }

    printf("Charaters: %d\n", chs);
    printf("lines: %d\n", lines);


    if(fp){
            fclose(fp);
    }
    return 0;
}

【问题讨论】:

  • 在进入循环之前,您还没有检查fopen() 是否成功(fp != NULL)。将 NULL 指针传递给 fgetc() 会产生未定义的行为。
  • fgetc 故意返回 int
  • 问题是我打开了一个空文件。所以我应该先检查它是否为空。

标签: c gcc segmentation-fault


【解决方案1】:
  • 您的代码需要更紧密地遵循惯用 C。
  • 您应该立即验证fopen,而不是在您已经尝试使用fp 之后。
  • fgetc 返回 int,而不是 char。这是因为它需要返回有关流状态的侧通道信息(即EOF),此信息不能用char 表示,但您可以安全地将int 值转换为char,如果值不是EOF
  • 您的代码将\r 视为常规字符,而\r\n 表示换行符(而不仅仅是一个单独的\n)是司空见惯的,您可能需要考虑如何处理不同的字符类。
  • 您的程序不处理重要的编码(即,它只会正确处理系统本机编码的文件,大概是 ASCII)。您应该使用 Unicode 库从文件中正确读取单个字符:例如,您的程序会将 UTF-8 中的代理对视为两个字符而不是 1,并且会错误地计算 UTF-16 文件。

更好:

FILE* fp = fopen( argv[1], "r" );
if( !fp ) {
    printf( "Could not open file \"%s\" for reading.\r\n", argv[1] );
    return 1;
}

int lines = 0;
int chars = 0;

int nc;
while( ( nc = fgetc( fp ) ) != EOF ) {

    char c = (char)nc;

    if     ( c == '\n' ) lines++;
    else if( c != '\r' ) chars++;
}

printf( "Characters: %d\r\nLines: %d\r\n", chars, lines );

fclose( fp );

return 0;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2022-08-02
    • 1970-01-01
    • 2010-12-18
    相关资源
    最近更新 更多