[英]How to get empty input or only ENTER in 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]
,但是您必须同时满足以下两个条件:
scanf
返回,并 [enter]
上从stdin
删除换行符。 您还必须通过限制字符scanf
尝试放入数组中的字符来手动防止超出字符串末尾的写入。 否则, scanf
会很乐意尝试写入尽可能多的字符。 (这使像fgets
或getline
这样的面向行的输入更可取)
但是,如果考虑到所有因素,则可以使用scanf
:
#include <stdio.h>
#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'
如上所述, 面向行的输入是读取字符串的首选方式。 可用的两个主要工具是fgets
和getline
。 两者都有优点/缺点。 getline
两个主要优点是: (1)将为您分配行缓冲区, (2)返回返回缓冲区的实际字符数。
getline
一个弱点是它将读取直到内存耗尽为止的所有字符。 因此,如果将输入限制为17
个字符(16个字符+空终止符),则由您来决定执行该限制。 fgets
一个缺点是您无法知道实际读取了多少个字符。 您所知道的是fgets
读取的max length
介于1
到max length
之间,通常会提示需要调用strlen
(或遍历字符串,直到找到null终止符为止)。
fgets
和getline
都将在缓冲区中包含尾随的'\\n'
(因为它存在于文件中,或者在从stdin
读取时按[enter]
时产生)。 最好不要在字符串的末端挂断错的换行符,因此,在读取换行符后剥离它通常是一个好主意。
注意: getline
如果缓冲区最初设置将会为缓冲区分配内存NULL
.. 和 .. getline
将重新分配的缓冲区它被赋予如果是不足以容纳输入。 (当前分配大小以'n'
)。 由于getline
为您分配/重新分配,因此您有责任在不再使用内存时释放它。
考虑到所有这些因素,以下是等效的getline
实现,该实现可防止用户通过在提示符处按[enter]
来保留空字符串:
#include <stdio.h>
#include <stdlib.h>
#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'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.