如何在C中获取空输入或仅输入ENTER [英] How to get empty input or only ENTER in C
问题描述
由于我对此很陌生,因此我在使用这种简单的C代码时遇到了麻烦.
Hi I'm having trouble with this simple C code since i'm very new to it.
当我尝试从中获取空值或获得用户是否仅按ENTER而没有键入任何内容时. 尝试了几种变体,但仍然无法使用
When I try to get empty value from or get if the user only hit ENTER without typing anything. Tried few variations and still not working
代码段如下:
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;
}
这个论坛上有很多变化,没有一个对我有用... 我想念什么?
There is many variations on this forum none of them worked for me... What am I missing?
推荐答案
您可以阻止用户仅按scanf
键并按[enter]
键,但是您必须同时执行以下操作:
You can prevent the user from just pressing [enter]
with scanf
, but you must both:
- 检查
scanf
返回,然后 - 仅在
[enter]
上从stdin
剥离换行符.
- check the
scanf
return, and - strip the newline from
stdin
on[enter]
alone.
还必须通过限制字符scanf
尝试放入数组中的字符来手动防止超出字符串末尾的写入.否则,scanf
会很乐意尝试输入尽可能多的字符. (这使得像fgets
或getline
这样的面向行的输入更可取)
You must also manually prevent writing beyond the end of your string by limiting the characters scanf
attempts to put in your array. Otherwise, scanf
will happily try and write as many characters as are entered. (which makes line-oriented input like fgets
or getline
preferable)
但是,如果考虑到所有这些因素,则可以使用scanf
进行尝试:
However, if you take that all into consideration, you can do what it looks like you are attempting with 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'
getline解决方案
如上所述,面向行的输入是读取字符串的首选方式.可用的两个主要工具是fgets
和getline
.两者都有优点/缺点. getline
的两个主要优点是(1)将为您分配行缓冲区,而(2)将返回读取的实际字符数缓冲区.
getline Solution
As mentioned above, line-oriented input is the preferred manner for reading strings. Two of the primary tools available are fgets
and getline
. Both have strengths/weaknesses. Two of the primary strengths of getline
is that it (1) will allocate the line buffer for you, and (2) it returns the actual number of characters read into the buffer.
getline
的一个缺点是它将读取直到内存耗尽为止的所有字符.因此,如果将输入限制为17
(16个字符+空终止符),则由您来决定执行该限制. fgets
的一个缺点是您无法知道实际读取了多少个字符.您所知道的是fgets
在1
和max length
之间的某个位置读取,通常会提示需要调用strlen
(或遍历字符串,直到找到空终止符为止).
A weakness of getline
is it will read all characters it is given up to the point of memory exhaustion. So if you are limiting your input to 17
(16 chars + null-terminator), it is up to you to enforce the limit. A weakness of fgets
is that you have no way of knowing how many characters were actually read. All you know is fgets
read somewhere between 1
and max length
generally prompting the need to call strlen
(or iterate over the string until the null-terminator is found.)
fgets
和getline
都将在缓冲区中包含尾随的'\n'
(因为它存在于文件中,或者当从stdin
读取时按[enter]
时产生的).最好不要在字符串的末端挂断错的换行符,因此在读取换行符后将其删除通常是个好主意.
Both fgets
and getline
will include the trailing '\n'
in the buffer (as it exists in the file, or as produced when you press [enter]
when reading from stdin
). It is never a good idea to leave stray newlines hanging off the ends of your strings, so it is generally a good idea to strip the newline after it is read.
注意:如果该缓冲区最初设置为NULL
.. 和,则getline
将为该缓冲区分配内存.getline
将重新分配该缓冲区如果不足以容纳输入,则给出该值. (当前的分配大小在'n'
中保持).由于getline
为您分配/重新分配,因此您有责任在不再使用内存时释放它.
note: getline
will allocate memory for the buffer if the buffer is initially set to NULL
..and.. getline
will reallocate the buffer it is given if it is insufficient to hold the input. (the current size of the allocation is maintained in 'n'
). Since getline
allocates/reallocates for you, you are responsible for freeing the memory when it is no longer in use.
考虑到所有这些,以下是等效的getline
实现,该实现可防止用户通过在提示符下直接按[enter]
来保留空字符串:
Taking all that into consideration, the following is an equivalent getline
implementation that prevents the user from leaving an empty string by simply pressing [enter]
at the prompt:
#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'
这篇关于如何在C中获取空输入或仅输入ENTER的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!