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') {