Why am I getting a segmentation fault?

jon*_*hua 3 c arrays pointers segmentation-fault

I'm trying to write a program that takes in a plaintext file as it's argument and parses through it, adding all the numbers together and then print out the sum. The following is my code:

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

static int sumNumbers(char filename[])
{
    int sum = 0;
    FILE *file = fopen(filename, "r");
    char *str;

    while (fgets(str, sizeof BUFSIZ, file))
    {
        while (*str != '\0')
        {
            if (isdigit(*str))
            {
                sum += atoi(str);
                str++;
                while (isdigit(*str))
                    str++;
                continue;
            }
            str++;
        }
    }

    fclose(file);

    return sum;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Please enter the filename as the argument.\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("The sum of all the numbers in the file is : %d\n", sumNumbers(argv[1]));
        exit(EXIT_SUCCESS);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

And the text file I'm using is:

This a rather boring text file with some random numbers scattered throughout it.

Here is one: 87 and here is another: 3

and finally two last numbers: 12 19381. Done. Phew.

When I compile and try to run it, I get a segmentation fault.

cod*_*ict 14

您没有为缓冲区分配空间.
指针str只是一个悬空指针.因此,您的程序有效地将从文件读取的数据转储到您不拥有的内存位置,从而导致分段错误.

你需要:

char *str;
str = malloc(BUFSIZ); // this is missing..also free() the mem once done using it.
Run Code Online (Sandbox Code Playgroud)

要不就:

char str[BUFSIZ]; // but then you can't do str++, you'll have to use another 
                  // pointer say char *ptr = str; and use it in place of str.
Run Code Online (Sandbox Code Playgroud)

编辑:

还有另一个错误:

while (fgets(str, sizeof BUFSIZ, file))
Run Code Online (Sandbox Code Playgroud)

第二个论点应该BUFSIZ不是sizeof BUFSIZ.

为什么?

因为第二个参数是要读入缓冲区的最大字符数,包括空字符.既然sizeof BUFSIZ4你可以阅读最大高达3字符到缓冲区.这就是为什么19381被读为193,然后81<space>.