简体   繁体   中英

Error when using fgets() to properly read a line from stdin when the input is less than the max length

I'm writing a function that reads user input and puts it in a string that is then appended to a string's linked list implemented by myself,I use fgetc() to clean the stdin and take care of the newline left in the buffer and also append the \\0 needed at the end of every string read by the function. The function works OK only if the input line is less than 8 characters. I don't understand why as I set the max length to be 100

All the functions needed for manipulating the linked list are already tested and working. I tried testing if the read string is properly added to the linked list and it is, no matter what the size if it is less than the max length specified.

The problem arises in the second iteration after a previous input where the read line is more than 7 characters. The program then in that moment crashes, no matter what I try. I'm totally at a loss here.

This is the function that reads a line from stdin and appends it to the linked list. All the necessary functions to manipulate the linked list, the implementation of the linked list and the main function are at the end.

void LeerLista(Lista L) {
    char temp[100];
    int x, i = 1;
    printf("introduzca la cantidad de strings deseados:\n");
    scanf("%d", &x);
    flushstdin(stdin); // flush the stdin function defined below
    while (i <= x) {   
        printf("introduzca la sentencia nro %d (max 100 caracteres):\n",i);
        if (fgets(temp, sizeof(temp), stdin) != NULL) {   
            if (temp[strlen(temp) - 1] == '\n') {   
                temp[strlen(temp) - 1] = '\0';
                addCab(temp, L);    // add at the head node of the linked list
            } else {
                printf("error de entrada limite maximo excedido, intente de nuevo");
                --i;
            }
        } else {
            printf("error en lectura, intente de nuevo");
            --i;
        }
        ++i;
    }
}

Here I list all the used functions and the main function:

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

typedef struct nodoc {
    char *key;
    struct nodoc *sig;
} Nodoc;

typedef struct cab {
    Nodoc *alpha;
} Cab;

typedef Cab* Lista;

int main(void) {
    Lista L = newLista();
    LeerLista(L);
    printLista(L);
    getchar();
    return 0;
}

Lista newLista() {
    Lista L = malloc(sizeof(Cab));
    L->alpha = NULL;
    return L;
}

Nodoc *newNodoc(char *c, Nodoc *sig) {
    Nodoc *p = malloc(sizeof(Nodoc));
    p->key = malloc(sizeof(c));
    strcpy(p->key, c);
    p->sig = sig;
    return p;
}

void addCab(char *k, Lista L) {
    Nodoc *p = newNodoc(k, L->alpha);
    L->alpha = p;
}

void flushstdin(FILE *where) {
    int ch;
    while (((ch = fgetc(where)) != '\n') && (ch != EOF))
        /* void */;
}

I expect to be able to add strings to the linked list of any size less than the max length.

EDIT: here is the output when I input strings that are less than 8 characters long:

introduzca la cantidad de strings deseados:
3
introduzca la sentencia nro 1 (max 100 caracteres):
1234567
introduzca la sentencia nro 2 (max 100 caracteres):
1234567
introduzca la sentencia nro 3 (max 100 caracteres):
1234567

[1234567, 1234567, 1234567]

if I try to put a bigger string, the program crashes after the second iteration: (I put a test print statement and printed the linked list)

introduzca la cantidad de strings deseados:
3
introduzca la sentencia nro 1 (max 100 caracteres):
12345678
this is a test printing linked list:
[12345678]introduzca la sentencia nro 2 (max 100 caracteres):
1234567

Inside newNodoc() you use malloc(sizeof(c)) which only creates room for the size of c , which is a pointer to char and itself has a size of (it seems) 8 in your environment. You seem to intend to make room for the string referred to by that pointer. That size is however not known to the function, sizeof(*c) would be 1 and not helpful either.

In case you already happen to know the length of the to store outside of the function anyway you could provide that knowledge to the function explicitly, eg by adding another parameter to provide the size info.
For the case of 0-terminated strings, however you can use strlen() , even inside the function, without an additional parameter. (Thanks Johnathan Leffler.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM