C - read line from stdin with fgets() in function

2019-09-20 00:18发布

问题:

I'm trying to read line from stdin with fgets(), I want to use fgets() in my function, which I think is the problem. The string could be max 1024 chars long. When I run this code I get "Segmentation fault (core dumped)"

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

#define MAX_SIZE 1025

void print_fgets();

int main()
{
    print_select();
    return 0;
}

void print_select()
{
    char *str;
    int length;

    while (fgets( str, MAX_SIZE, stdin)!=NULL)
    {
        length=strlen(str);

        if (length==MAX_SIZE-1 && str[length-1]!='\n')
        {
             printf("Error, line overeached buffer!\n");
             return 1;
        }

        if (str[length-1]=='\n')
             str[length-1]='\0';
        printf("%s\n", str);
    }
}

回答1:

The problem is that you try to write to the location that the str pointer points to. Initially it will point to some garbage address (due to char *str not being initialized).

You can try a stack based solution instead by changing:

/* This is just a pointer */
char *str;

to:

/* This is a character array (on the stack) of size MAX_SIZE, initialized to zero */
char str[MAX_SIZE] = {0};

Or if you want to allocate memory dynamically for the array, do this instead:

char *str;
str = calloc(1, MAX_SIZE);
if (str == NULL) {
    /* Failed to allocate memory */
}

... Your code

free(str);  /* You should always free dynamically allocated memory when you are done with it */
str = NULL; /* It's a good practice to point your pointer to NULL after it's free'd */

Don't forget things like array index starting with 0 and goes to MAX_SIZE - 1 (in your case) and NUL termination (strings must end with it).



回答2:

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

#define MAX_SIZE 1025

int print_select();  /* Use correct name (instead of print_fgets()) */

int main()
{
    print_select();
    return 0;
}

int print_select()  /* Fix. Dhould return int if you have a return <int> statement. */
{
    char str[MAX_SIZE];  /* Initialize static memory. */
    int length;

    while (fgets( str, MAX_SIZE, stdin)!=NULL)
    {
        length=strlen(str);
        if (length==MAX_SIZE-1 && str[length-1]!='\n')
        {
             printf("Error, line overeached buffer!\n");
             return 1;
        }
        if (str[length-1]=='\n')
        {
             str[length-1]='\0';
        }
        printf("%s\n", str);
    }
    return 0;  /* Function may not be returning an int. Return it in those cases. */
}


标签: c function fgets