2

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
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • What is the exact result of the execution? What does the program print on the screen? Are there compiler warnings / errors? Please list them. – virolino Apr 05 '19 at 05:32
  • This "I use fgetc() to clean the stdin" and this `flushstdin(stdin);` are at conflict. Do not attempt to flush input. – Yunnosch Apr 05 '19 at 05:37

1 Answers1

3

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, e.g. 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.)

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Or, for a string, you can use `strlen()` to determine its length. – Jonathan Leffler Apr 05 '19 at 05:48
  • @JonathanLeffler Of course. I will add that. Missed it. – Yunnosch Apr 05 '19 at 05:49
  • wow such a easy mistake, I knew I had something to do with a pointer size as it was too alike it size, thank you very much! now I will see what happened with the -m32 command as it seems its not working, now I saw your comment about the flush function and wanted to ask is there a better way to do it? I used it to clean after scanf's newline – Enrique Cisneros Apr 05 '19 at 06:09
  • That comment sounds like a contradiction. Please elaborate. If the problem of this question is solved, please consider making a new question, with a [mcve] for the changed code and the (changed, I think) problem. You will get answers by others, I will be afk for several hours. – Yunnosch Apr 05 '19 at 06:40