Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c gets/fgets不工作_C_List_Fgets - Fatal编程技术网

c gets/fgets不工作

c gets/fgets不工作,c,list,fgets,C,List,Fgets,get在函数neuePerson中不起作用, 当它在for循环中时,它就工作了,但后来我改变了它,现在编译器说它不是未定义的 我用fgets尝试了它,现在没有警告,但它仍然忽略fgets,因此我无法在控制台中写入任何内容 在main函数的get工作。我有点困惑…:o #include <stdio.h> #include <stdlib.h> #include <time.h> #include "readline.h" //typedef struct P

get
在函数
neuePerson
中不起作用, 当它在
for
循环中时,它就工作了,但后来我改变了它,现在编译器说它不是未定义的

我用
fgets
尝试了它,现在没有警告,但它仍然忽略
fgets
,因此我无法在控制台中写入任何内容

main
函数的
get
工作。我有点困惑…:o

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "readline.h"

//typedef struct Person {
//    char name[50];
//    char unit;
//    int number;
//} Person;

typedef struct person {
    char name[50];
    char unit;
    int number;
    struct person *next;
} Person;

void neuePerson(Person *firstPerson) {
    time_t t; 
    time(&t);
    srand((unsigned int)t);
    while (firstPerson->next != 0)
        firstPerson = firstPerson->next;
    printf("Gib  einen Namen ein \n");
    fgets(firstPerson->name, 50, stdin);                        
    firstPerson->number = rand() % 99 + 1; 
    firstPerson->unit = rand() % 3 + 65;
    firstPerson->next = (Person*)malloc(sizeof(Person));
    firstPerson = firstPerson->next;
    firstPerson->next = 0;
}

void ausgabe(Person *anfang) {
    while (anfang->next != 0) {
        printf("Name: %s", anfang->name);
        printf("   Abteilung: %c", anfang->unit);
        printf("   Tel.Nummer: %i\n", anfang->number);
        anfang = anfang->next;
    }
}

int main() {
    Person* pers1 = (Person*)malloc(sizeof(Person));
    //Person* test = (Person*)malloc(sizeof(Person));
    //gets(test->name, 50);
    //printf("%s", test->name);
    pers1->next = 0;
    char z = 'n';
    while (z != 'e') {
        printf("[n]eue Person, [a]usgabe,  [e]nde");
        z = getchar();
        if (z == 'n') neuePerson(pers1);
        else if (z == 'a') ausgabe(pers1);
    }
}
#包括
#包括
#包括
#包括“readline.h”
//typedef结构人{
//字符名[50];
//炭单元;
//整数;
//}人;
typedef结构人{
字符名[50];
炭单元;
整数;
结构人*next;
}人;
void neuePerson(个人*第一人称){
时间;
时间&t;
srand((无符号整数)t);
while(第一人称->下一步!=0)
第一个人=第一个人->下一个;
printf(“Gib einen Namen ein\n”);
fgets(第一人称->姓名,50,标准输入);
第一人称->数字=兰德()%99+1;
第一人称->单位=rand()%3+65;
第一个人->下一个=(个人*)malloc(个人大小);
第一个人=第一个人->下一个;
第一人称->下一个=0;
}
无效ausgabe(人*anfang){
同时(安防->下一步!=0){
printf(“名称:%s”,安防->名称);
printf(“Abteilung:%c”,安防->单位);
printf(“电话号码:%i\n”,安防->号码);
安防=安防->下一步;
}
}
int main(){
Person*pers1=(Person*)malloc(sizeof(Person));
//人员*测试=(人员*)malloc(人员大小);
//获取(测试->名称,50);
//printf(“%s”,测试->名称);
pers1->next=0;
char z='n';
而(z!=“e”){
printf(“[n]eue Person,[a]usgabe,[e]nde”);
z=getchar();
如果(z='n')neuePerson(pers1);
如果(z='a')为空(pers1);
}
}
问题来自标准输入的行缓冲:

您可以使用
getchar()
读取
main
中的选项,但在键入enter键后,字节将返回到程序中。只返回行中的初始字符,其余字符保留在流中

随后使用
fgets()
读取人名时,它返回一个空行,因为它获取的
\n
仍在流中。与流行的观点相反,
fflush(stdin)
不是解决方案,因为它有未定义的行为。更好的解决方案是这样阅读选项:

int main() {
    Person *pers1 = (Person*)malloc(sizeof(Person));
    pers1->next = NULL;
    pers1->unit = 0;
    pers1->name[0] = '\0';
    for (;;) {
        int z, c;
        printf("[n]eue Person, [a]usgabe,  [e]nde ");
        z = c = getchar();
        while (c != EOF && c != '\n')
            c = getchar();
        if (z == EOF || z == 'e')
            break;
        else
        if (z == 'n')
            neuePerson(pers1);
        else
        if (z == 'a')
            ausgabe(pers1);
    }
}

您应该改进列表处理:空列表应该仅为
NULL
,在列表末尾保留未初始化的虚拟结构挂起是不正确的。您可以通过将指向列表头的指针传递到
neuePerson

来处理列表头的更新。我同意chqrlie的回答;此外,在退出主while循环后,不要忘记在释放列表:

int main()
{
   /** your While loop */

   Person *nextp = pers1;
   do {
       free(nextp);
       nextp = nextp->next;
   } while (nextp != NULL);
}
最好将链表逻辑与其他逻辑分开。当你的程序变得更大时,你会很高兴你现在这样做了


另外,首先,请与成为朋友。

因为您询问了GET和FGET,所以我可以引用手册页中的内容:

永远不要使用get()。由于无法在不事先知道数据的情况下判断GET()将读取多少个字符,并且由于GET()将继续存储超过缓冲区末尾的字符,因此使用GET()非常危险。它被用来破坏计算机安全。改用fgets()

在回答您的问题之前,我将冒昧地将您的代码重新编写到最小集。您正在测试GET,因此我可以在GET之后删除所有内容,以及在GET之前未调用的代码中的所有内容。我也会把你打给fgets的电话从neuePerson转到main。我还将避免使用堆内存,更进一步,我相信您能够找到正确使用堆的方法。最后,我真的不喜欢使用没有退出代码的未初始化结构或主例程,所以我也会这样做。看起来是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "readline.h"

typedef struct person{
    char name[50];
    char unit;
    int number;
    struct person* next;
} Person;

int main() {
    Person _pers1, *pers1 = &_pers1;
    char z = 'n';

    memset(pers1, 0, sizeof(Person));

    while (z != 'e') {
        z = getchar();
        pers1->name = fgets(pers1->name, 50, stdin);
    }

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "readline.h"

typedef struct person{
    char name[50];
    char unit;
    int number;
    struct person* next;
} Person;

int main() {
    Person _pers1, *pers1 = &_pers1;
    char z[50];

    memset(pers1, 0, sizeof(Person));
    memset(z, 0, sizeof(char) * 50);

    while (z[0] != 'e') {
        fgets(z, 50, stdin);
        fgets(pers1->name, 50, stdin);
    }

    return 0;
}

他有一些缺点。看“e”以外的值更为正确。我建议使用0、EOF、“\n”和“\r”。但是你唯一可以事先知道的是0,因为你设置了它。在我看来,最好是通过测试和使用您的代码来发现其他代码需要添加,而不是在出现问题之前“厨房洗涤”您的代码。

永远不要使用gets。这是一个危险的功能,请更具体一些。“不起作用”永远不是一个充分的描述。你是如何得出结论说它“不起作用的”?它会崩溃吗?是否出现错误的输出?是不是。。?准确描述预期行为和实际行为,包括您已经完成的任何调试结果。不要用
/**/
注释代码,或者在每行上使用
/
注释,或者使用
\if 0
/
\endif
@chqrlie:这是从哪里来的<代码>/*您在这里的注释*/是完全有效的C代码。最近才(相对而言)在“普通”C中添加了一行
/
。@Jongware:这是一条建议。用
/*
注释代码容易出错,可读性较差。如果代码包含C注释,则可能导致难以找到的bug(我已经看到了很多)<代码>/注释得到大多数C编译器的支持,16年来一直是标准的一部分。我个人更喜欢
#if 0
/
#endif
对。
    while (z[0] != 'e') {