C程序中的分段错误(核心转储)以制作直方图

segmentation fault (core dumped) in C program to make histogram

我正在尝试编写一个显示直方图的程序。每次我 运行 时,我都会收到分段错误(核心转储)。我正在读取一个包含数字的文件,并试图找到每个数字的出现并从中打印直方图。我四处张望,但似乎无法找到为什么会这样。请告诉我为什么。

输入random.txt

1405413042132140413140

期望输出

0 ****
1 ******
2 ** 
3 ***
4 ******
5 *
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    int n = 1001; 
    int a[n];
    int opt;

    FILE *f;
    if(argc == 5){
        f = fopen(argv[5], "r");
    }
    else if(argc == 4){
        f = fopen(argv[4], "r");
    }
    else if(argc == 3){
        f = fopen(argv[3], "r");
    }
    else if(argc == 2){
        f = fopen(argv[2], "r");
    }
    else if(argc == 1){
        f = fopen(argv[1], "r");
    }
    else if(f == NULL){
        printf("ERROR: File Not Found\n");
        return 1;
    }
}

由于数组索引从 0 开始,argv 中的最后一个参数是 argv[argc-1]。您的代码试图使用 argv[argc] 作为文件名,但此元素始终包含一个空指针,这会在您调用 fopen().

时导致分段错误

您还应该注意所有 if 语句中的模式,它允许您将它们全部组合成一行。

int main(int argc, char *argv[]){
    int n = 1001; 
    int a[n];
    int opt;
    struct options opts = {60, '*', 3, '\n'};
    while((opt = getopt(argc, argv, "s:m:c:w:n") != -1)){
        switch(opt){
        case 's':
            opts.scale = atoi(optarg);
            break;
        case 'm':
            opts.c = optarg[0];
            break;
        case 'w':
            opts.width = atoi(optarg);
            break;
        case 'n':
            opts.bars = 0;
            break;
        default:
            fprintf(stderr, "Valid options are s,m,c,w,n\n");
            exit(1);
        }
    }
    
    if (argc < 2) {
        printf("ERROR: filename is required\n");
        return 1;
    }
    FILE *f = fopen(argv[argc-1], "r");
    if (f == NULL){
        printf("ERROR: File Not Found\n");
        return 1;
    }
    
    count(f, a, n);
    max(n, a);
    histogram(n, a, &opts);
}