繁体   English   中英

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

[英]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] ,但是您必须同时满足以下两个条件:

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

您还必须通过限制字符scanf尝试放入数组中的字符来手动防止超出字符串末尾的写入。 否则, scanf会很乐意尝试写入尽可能多的字符。 (这使像fgetsgetline这样的面向行的输入更可取)

但是,如果考虑到所有因素,则可以使用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解决方案

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

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

fgetsgetline都将在缓冲区中包含尾随的'\\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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM