如何获取空输入或仅在C中输入

嗨,我对这个简单的C代码有困难,因为我对它很新。

当我尝试从中获取空值或获取用户只是按Enter键而不键入任何内容。 尝试了一些变化,仍然没有工作

这段代码如下:

char user_input[17] = {'\0'}; printf("Type something: "); prompt = scanf("%s", user_input); if (prompt <= 0) { printf("You didn't type anythingt!\n"); return 1; } 

也:

 char user_input[17] = {'\0'}; printf("Type something: "); scanf("%s", user_input); if (user_input[0] == '\0') { printf("You didn't type anything!\n"); return 1; } 

在这个论坛上有很多变化,它们都没有为我工作……我错过了什么?

问题是你的scanf()调用在遇到一个不仅仅是空格的字符串之前不会返回。 您应该使用fgets() ,因为它也可以防止溢出。

例:

 char s[80]; fgets(s, sizeof s, stdin); if(s[0] == '\n') { puts("line is empty"); } 

您可以阻止用户只使用scanf[enter] ,但您必须同时:

  1. 检查scanf返回,然后
  2. 仅在[enter]上从stdin删除换行符。

您还必须通过限制scanf尝试放入数组中的字符来手动阻止写入超出字符串结尾的操作。 否则, scanf会愉快地尝试写入输入的字符数。 (这使得面向行的输入更像fgetsgetline

但是,如果你考虑到这一切,你可以做你正在尝试使用scanf

 #include  #define MAXS 17 void fflush_stdin(); int main () { char user_input [MAXS] = {0}; /* always initialize your variables */ while (printf ("\n Type something (16 char or less): ") && scanf ("%16[^\n]%*c", user_input) < 1) { printf (" pressing [enter] doesn't count...\n"); fflush_stdin(); } printf ("\n You entered: '%s'\n\n", user_input); return 0; } /* simple function to strip '\n` from stdin */ void fflush_stdin() { int c; while ((c = getchar()) != '\n' && c != EOF); } 

使用/输出

 $ ./bin/scanfbasic1 Type something (16 char or less): pressing [enter] doesn't count... Type something (16 char or less): pressing [enter] doesn't count... Type something (16 char or less): 12345678901234567890 You entered: '1234567890123456' 

getline解决方案

如上所述, 面向行的输入是读取字符串的首选方式。 可用的两个主要工具是fgetsgetline 。 两者都有优点/缺点。 getline两个主要优点是它(1)将为您分配行缓冲区, (2)它返回读入缓冲区的实际字符数。

getline一个弱点是它将读取所有被释放到内存耗尽点的字符。 因此,如果您将输入限制为17 (16个字符+空终止符),则由您来强制执行限制。 fgets一个弱点是你无法知道实际读取了多少个字符。 所有你知道的是fgets读取介于1max length之间的位置通常会提示需要调用strlen (或迭代字符串直到找到null终止符。)

fgetsgetline都将在缓冲区中包含尾部'\n' (因为它存在于文件中,或者当从stdin读取时按[enter]时生成)。 将杂散的换行符悬挂在字符串的末尾并不是一个好主意,因此在读取后删除换行符通常是个好主意。

注意:如果缓冲区最初设置为NULL ,则 getline将为缓冲区分配内存..如果不足以保持输入, getline将重新分配缓冲区。 (分配的当前大小保持在'n' )。 由于getline为您分配/重新分配,因此您负责在不再使用内存时释放内存。

考虑到所有这些因素,以下是一个等效的getline实现,它通过在提示符处按[enter]来阻止用户留下空字符串:

 #include  #include  #define MAXS 17 int main (void) { char *ln = NULL; /* getline requires block allocated by malloc */ size_t n = 0; /* initial size of buffer, if ln NULL, n ignored */ ssize_t nchr = 0; /* getline return - number of chars actually read */ while (printf ("\n Type something (16 char or less): ") && ((nchr = getline (&ln, &n, stdin)) <= 1)) { printf (" pressing [enter] doesn't count...\n"); } while (nchr > 0 && (ln[nchr-1] == '\n' || ln[nchr-1] == '\r')) ln[--nchr] = 0; /* strip newline or carriage rtn */ if (nchr > MAXS - 1) /* to enforce limit, check length */ ln[MAXS - 1] = 0; /* if exceeds limit, null-terminate */ printf ("\n You entered: '%s'\n\n", ln); if (ln) free (ln); /* free memory allocated by getline */ return 0; } 

使用/输出

 $ ./bin/getlinebasic_noenter Type something (16 char or less): pressing [enter] doesn't count... Type something (16 char or less): 12345678901234567890 You entered: '1234567890123456'