当输入小于最大长度时,使用fgets()从stdin正确读取一行时出错

时间:2019-04-05 05:29:59

标签: c

我正在编写一个函数,该函数读取用户输入并将其放入一个字符串中,然后将该字符串附加到我自己实现的字符串的链接列表中,我使用fgetc()来清理stdin并注意保留在缓冲区中的换行符,并在该函数读取的每个字符串的末尾附加所需的\0。 仅当输入行少于8个字符时,该功能才能正常运行。我不明白为什么将最大长度设置为100

操纵链表所需的所有功能都已经过测试并且可以正常工作。我尝试测试读取的字符串是否正确添加到了链表中,无论大小小于指定的最大长度,都是如此。

该问题出现在上一行输入之后的第二次迭代中,其中读取行超过7个字符。不管我尝试什么,程序都会在那一刻崩溃。我在这里完全不知所措。

此函数从stdin读取一行并将其附加到链接列表。最后,操作链表所需的所有功能,链表的实现和主要功能都在最后。

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;
    }
}

在这里列出所有使用的功能和主要功能:

#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 */;
}

我希望能够将小于最大长度的任何大小的字符串添加到链表中。

编辑:这是输入少于8个字符的字符串时的输出:

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]

如果我尝试放置更大的字符串,则程序将在第二次迭代后崩溃:(我放置了一个测试打印语句并打印了链表)

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

1 个答案:

答案 0 :(得分:3)

newNodoc()内,您使用malloc(sizeof(c))只会为c的大小创造空间,char是指向sizeof(*c)的指针,其大小为(看来) 8在您的环境中。您似乎打算为该指针引用的字符串腾出空间。但是该大小对于函数来说是未知的,strlen()将为1,也没有帮助。

如果您已经碰巧知道要存储在函数外部的长度,则可以将其知识明确地提供给函数,例如通过添加另一个参数来提供尺寸信息。
对于以0结尾的字符串,即使在函数内部,也可以使用<ion-header> <ion-tabs style="display: contents;"> <ion-tab-bar slot="top"> <ion-tab-button tab="popular"> <ion-label>SOme text</ion-label> <ion-icon name="heart"></ion-icon> <ion-badge>6</ion-badge> </ion-tab-button> </ion-tab-bar> </ion-tabs> </ion-header> ,而无需附加参数。 (感谢Johnathan Leffler。)