【发布时间】:2014-05-10 14:26:09
【问题描述】:
所以我真的很困惑。我必须用 C 编写一个程序,它基本上是一个通讯录,因此我必须从用户那里获取多个字符串(姓名、ID、电话等)
一开始我尝试只使用scanf(),但有时它会与换行符'\n' 混淆。经过一番谷歌搜索,我最终使用scanf() 获取单个字符或整数(用户回答是或否问题,或从菜单中选择一个操作)和fgets() 读取地址簿的字段。但是,在使用scanf() 之后,我还必须多次使用fflush(stdin),正如我所见,这里不建议这样做。此方法按预期工作。
那么从用户那里读取字符串的最佳方式是什么? fflush(stdin) 不提供便携性吗?这是一项任务,所以我也必须考虑可移植性,因为我将在另一台计算机上执行我的代码。
提前谢谢你。
编辑:这就是我到目前为止所得到的。请原谅一些用另一种语言(阿尔巴尼亚语)写的词。我相信你能理解这是怎么回事。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void regjistrim();
void kerkim();
void modifikim();
void fshirje();
void rradhitje();
void display();
#define EMRI 50
#define MBIEMRI 50
#define ID 20
#define TEL 20
#define EMAIL 25
typedef struct addressbook
{
char emri[EMRI];
char mbiemri[MBIEMRI];
char id[ID];
char tel[TEL];
char email[EMAIL];
} addressbook;
FILE* Addressbook;
int main(void)
{
char input[2];
int choice;
printf("----------------ADDRESS BOOK----------------");
printf("\n\n\t1 - Regjistrimi i ri\n");
printf("\n\t2 - Kerkim\n");
printf("\n\t3 - Modifikim\n");
printf("\n\t4 - Fshirje\n");
printf("\n\t5 - Rradhitje\n");
printf("\n\t6 - Afishim i address book\n");
printf("\n\t0 - Exit\n");
fgets(input, 2, stdin);
sscanf(input, "%d", &choice);
while (choice < 0 || choice > 6)
{
printf("\nShtypni nje numer nga 0 - 6: \n");
fgets(input, 2, stdin);
sscanf(input, "%d", &choice);
}
switch (choice)
{
case 1:
regjistrim();
break;
case 2:
kerkim();
break;
case 3:
modifikim();
break;
case 4:
fshirje();
break;
case 5:
rradhitje();
break;
case 6:
display();
break;
case 0:
exit(0);
break;
}
return 0;
}
//Regjistron nje qytetar ne addressbook
void regjistrim()
{
char answer;
addressbook entry;
do
{
Addressbook = fopen("Addressbook.txt", "a+");
printf("\nShtypni emrin: ");
fgets(entry.emri, EMRI, stdin);
printf("\nShtypni mbiemrin: ");
fgets(entry.mbiemri, MBIEMRI, stdin);
printf("\nShtypni ID-in: ");
fgets(entry.id, ID, stdin);
printf("\nShtypni nr. telefoni: ");
fgets(entry.tel, TEL, stdin);
printf("\nShtypni email-in: ");
fgets(entry.email, EMAIL, stdin);
fprintf(Addressbook, "Emri: %sMbiemri: %sID: %sNr. telefoni: %sEmail: %s\n", entry.emri, entry.mbiemri, entry.id, entry.tel,entry.email);
fclose(Addressbook);
printf("\nShtypni y/Y neqoftese doni te regjistroni person tjeter: ");
fgets(answer, 1, stdin);
}
while(answer == 'y' || answer == 'Y');
}
【问题讨论】:
-
并非不推荐
fflush(stdin)。在这种情况下,刷新输入流是 error (它会导致未定义的行为)。只需使用fgets()独占,然后解析字符串。不要尝试将解析和用户输入阶段结合起来。 -
我支持user3477950的观点。我想补充一点,一般来说
scanf不被认为是读取无法保证结构的输入的好方法。这是非常危险的,并且很难或根本不可能安全地读取输入。我不确定是否有任何 best 方法。如果你想正确地做到这一点,你最终会得到一些库,或者将所有内容作为字符串读取并稍后解析缓冲区。 -
抱歉,我似乎无法理解解析是什么。另外,我将如何使用
fgets()从用户那里获取一个 int? -
@user3484582 在这种情况下,“解析”意味着弄清楚输入的内容。伪代码应为 1。获取输入行。 2. 判断该行是否包含整数。
-
@user3484582 我看到的一个问题是 fgets 的输入缓冲区应该足够大以容纳整行(例如,所有字符加上一个 '\n' 加上一个 '\0')。不建议使输入缓冲区仅包含 2 个字符。我会制作一个大约 10000 个字符或其他内容的缓冲区。当你得到一行时,将相关字符复制到你的结构中