C: gets() 跳过第一个输入
C: gets() skips the first input
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct record
{
char name[20];
char surname[20];
char telephone[20];
}Record;
typedef struct node
{
Record data;
struct node *next;
}Node;
Node *head = NULL;
void addRecord(Record s)
{
Node *newNode;
Node *n;
newNode = (Node*)malloc(sizeof(Node));
newNode->data = s;
newNode->next = NULL;
if (head == NULL)
{
// The linked list is empty
head = newNode;
}
else
{
// Traverse the whole list until we arrive at the last node
n = head;
while (n->next != NULL)
{
n = n->next;
}
n->next = newNode;
}
}
Record enterRecordDetails()
{
Record aRecord;
int len;
int valid = 0;
int valid2 = 0;
printf("ENTER THE FOLLOWING RECORD DETAILS:\n");
printf(" NAME : ");
gets(aRecord.name);
printf(" SURNAME : ");
gets(aRecord.surname);
do {
valid = 0;
valid2 = 0;
printf(" TELEPHONE NO. (8 digits): ");
gets(aRecord.telephone);
len = strlen(aRecord.telephone);
for (int i = 0; i < len; i++)
{
if (!isdigit(aRecord.telephone[i])) {
printf("You enterred an invalid number\n");
valid = 1; break;
}
}
Node *p = head;
while (p != NULL)
{
Node *next = p->next;
for (; next; p = next, next = next->next) {
if (strcmp(p->data.telephone, aRecord.telephone) == 0)
{
valid2 = 1; break;
}
}
if(p = NULL)break;
}
} while((valid == 1) || (len != 8) || (valid2 == 1));
getchar();
fflush(stdin);
return aRecord;
}
int main(void)
{
char menuOption;
do
{
system("cls");
printf("~~~ MAIN MENU ~~~\n");
printf("1. Add Telephone Record\n");
printf("2. Delete Telephone Record\n");
printf("3. Search\n");
printf("4. Display All Records\n");
printf("5. Exit\n\n");
menuOption = getchar();
fflush(stdin);
switch (menuOption)
{
case '1':
addRecordToList();
break;
case '4':
displayList();
break;
}
} while (menuOption != '5');
getchar();
return 0;
}
添加学生时,计算机要求用户输入姓氏而不是姓名。为什么程序会跳过 'Name' ?显示 'Name',但用户应改写姓氏。
首先,不要使用gets
,不安全。请改用 fgets
。
第一次调用 gets
会跳过一行的原因是在您调用 enterRecordDetails()
时缓冲区中有一个 '\n'
。通常,'\n'
是早期输入操作的遗留物,例如,使用 scanf
.
读取 int
解决此问题的一种方法是在读取int
时将字符串读取到末尾,这样连续调用fgets
就会得到实际数据。您可以在 enterRecordDetails()
函数中执行此操作:
Record enterRecordDetails()
{
Record aRecord;
printf("ENTER THE FOLLOWING RECORD DETAILS:\n");
printf(" NAME : ");
fscanf(stdin, " "); // Skip whitespace, if any
fgets(aRecord.name, 20, stdin);
printf(" SURNAME : ");
fgets(aRecord.surname, 20, stdin);
}
但是请注意,fgets
将 '\n'
保留在字符串中,只要它适合缓冲区。更好的方法是使用 scanf
,并传递限制输入长度并在 '\n'
:
处停止的格式说明符
scanf(" %19[^\n]", aRecord.name);
// ^
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct record
{
char name[20];
char surname[20];
char telephone[20];
}Record;
typedef struct node
{
Record data;
struct node *next;
}Node;
Node *head = NULL;
void addRecord(Record s)
{
Node *newNode;
Node *n;
newNode = (Node*)malloc(sizeof(Node));
newNode->data = s;
newNode->next = NULL;
if (head == NULL)
{
// The linked list is empty
head = newNode;
}
else
{
// Traverse the whole list until we arrive at the last node
n = head;
while (n->next != NULL)
{
n = n->next;
}
n->next = newNode;
}
}
Record enterRecordDetails()
{
Record aRecord;
int len;
int valid = 0;
int valid2 = 0;
printf("ENTER THE FOLLOWING RECORD DETAILS:\n");
printf(" NAME : ");
gets(aRecord.name);
printf(" SURNAME : ");
gets(aRecord.surname);
do {
valid = 0;
valid2 = 0;
printf(" TELEPHONE NO. (8 digits): ");
gets(aRecord.telephone);
len = strlen(aRecord.telephone);
for (int i = 0; i < len; i++)
{
if (!isdigit(aRecord.telephone[i])) {
printf("You enterred an invalid number\n");
valid = 1; break;
}
}
Node *p = head;
while (p != NULL)
{
Node *next = p->next;
for (; next; p = next, next = next->next) {
if (strcmp(p->data.telephone, aRecord.telephone) == 0)
{
valid2 = 1; break;
}
}
if(p = NULL)break;
}
} while((valid == 1) || (len != 8) || (valid2 == 1));
getchar();
fflush(stdin);
return aRecord;
}
int main(void)
{
char menuOption;
do
{
system("cls");
printf("~~~ MAIN MENU ~~~\n");
printf("1. Add Telephone Record\n");
printf("2. Delete Telephone Record\n");
printf("3. Search\n");
printf("4. Display All Records\n");
printf("5. Exit\n\n");
menuOption = getchar();
fflush(stdin);
switch (menuOption)
{
case '1':
addRecordToList();
break;
case '4':
displayList();
break;
}
} while (menuOption != '5');
getchar();
return 0;
}
添加学生时,计算机要求用户输入姓氏而不是姓名。为什么程序会跳过 'Name' ?显示 'Name',但用户应改写姓氏。
首先,不要使用gets
,不安全。请改用 fgets
。
第一次调用 gets
会跳过一行的原因是在您调用 enterRecordDetails()
时缓冲区中有一个 '\n'
。通常,'\n'
是早期输入操作的遗留物,例如,使用 scanf
.
int
解决此问题的一种方法是在读取int
时将字符串读取到末尾,这样连续调用fgets
就会得到实际数据。您可以在 enterRecordDetails()
函数中执行此操作:
Record enterRecordDetails()
{
Record aRecord;
printf("ENTER THE FOLLOWING RECORD DETAILS:\n");
printf(" NAME : ");
fscanf(stdin, " "); // Skip whitespace, if any
fgets(aRecord.name, 20, stdin);
printf(" SURNAME : ");
fgets(aRecord.surname, 20, stdin);
}
但是请注意,fgets
将 '\n'
保留在字符串中,只要它适合缓冲区。更好的方法是使用 scanf
,并传递限制输入长度并在 '\n'
:
scanf(" %19[^\n]", aRecord.name);
// ^