C 读取字符串的最佳方式是什么?
所以我真的很困惑。我必须用C语言编写一个程序,它基本上是一个地址簿,因此我必须从用户名、ID、电话等中获取多个字符串 刚开始我试着只使用scanf,但有时它会把换行符“\n”弄糟。在谷歌搜索之后,我最终使用scanf获取单个字符或int,用户可以回答yes或no问题,或者从菜单和fgets中选择一个操作来读取地址簿的字段。然而,在使用scanf之后,我还不得不多次使用fflushstdin,正如我所看到的,这里不推荐使用scanf。这种方法达到了预期的效果 那么,从用户那里读取字符串的最佳方式是什么?fflushstdin不提供可移植性吗?这是一项任务,所以我也必须考虑可移植性,因为我将在另一台计算机上执行我的代码 先谢谢你 编辑:这是我到目前为止得到的。请原谅一些用另一种语言阿尔巴尼亚语写的单词。我相信你能理解发生了什么C 读取字符串的最佳方式是什么?,c,string,C,String,所以我真的很困惑。我必须用C语言编写一个程序,它基本上是一个地址簿,因此我必须从用户名、ID、电话等中获取多个字符串 刚开始我试着只使用scanf,但有时它会把换行符“\n”弄糟。在谷歌搜索之后,我最终使用scanf获取单个字符或int,用户可以回答yes或no问题,或者从菜单和fgets中选择一个操作来读取地址簿的字段。然而,在使用scanf之后,我还不得不多次使用fflushstdin,正如我所看到的,这里不推荐使用scanf。这种方法达到了预期的效果 那么,从用户那里读取字符串的最佳方式是
#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');
}
使用scanf,您可以像这样清除换行符。此外,我还包括FGET
此外,此代码还演示了可以对输入的每个函数设置的限制
最佳可能有点主观,但我发现 做一个单独的函数来读取数字会让事情变得复杂 如果你不是绝对需要的话,可以简单一点,避免使用scanf
int readNumber(int min, int max)
{
char number[32];
do
{
if ( fgets( number, sizeof(number), stdin ) != NULL )
{
// note that if 'number' is not a number atoi returns 0
int n = atoi(number);
if ( n>= min && n <= max )
{
return n;
}
}
printf( "please enter a valid value between %d and %d\n", min, max );
}
while ( 1 );
return -1; // never reached
}
不建议使用fflushstdin。在这种情况下,刷新输入流是错误的,它会导致未定义的行为。只需专门使用fgets,然后解析字符串。不要尝试将解析和用户输入阶段结合起来。我支持用户3477950的视图。我想补充一点,一般来说,scanf不被认为是读取结构不保证的输入的好方法。这是相当危险的,而且很难或根本不可能安全地读取输入。我不确定是否有最好的办法。如果您想正确地执行此操作,您将得到一些库,或者以后将所有内容作为字符串读取并解析缓冲区。另外,如何使用fgets从用户处获取int?@user3484582在这种上下文中,解析意味着找出输入的内容。伪代码应该是1。获取输入行。2.找出该行是否包含整数。@user3484582我看到的一个问题是fgets的输入缓冲区应该足够大,以容纳整行字符,例如所有字符加上一个“\n”加上一个“\0”。不建议将输入缓冲区设置为仅2个字符。我会制作一个大约10000个字符的缓冲区。当你得到一行时,把相关的字符复制到你的结构中。这很好,但看起来像是一个草图解决方案。可以用getch?@user3484582来吃后面的换行符吗?是。@user3484582,如果您对答案满意,请告诉我,这样我就可以注销,而不用担心了是的,正如我之前所说,它工作得很好,但现在我正试图找到一种只使用FGET的方法。谢谢您的帮助。@user3484582我不知道接受这个答案是否更好,因为它对您来说没问题,并为您的程序开始一个新问题,
int readNumber(int min, int max)
{
char number[32];
do
{
if ( fgets( number, sizeof(number), stdin ) != NULL )
{
// note that if 'number' is not a number atoi returns 0
int n = atoi(number);
if ( n>= min && n <= max )
{
return n;
}
}
printf( "please enter a valid value between %d and %d\n", min, max );
}
while ( 1 );
return -1; // never reached
}