【问题标题】:How to use scanf() to capture only Strings如何使用 scanf() 仅捕获字符串
【发布时间】:2017-07-25 05:48:29
【问题描述】:

您好,我是 C 的新手,我正在尝试使用下面的字符数组类型来捕获用户的输入。我如何防止或转义数字字符。我只想捕获字符串。

char str_input[105];

在尝试过

scanf("%[^\n]s",str_input);
scanf("%[^\n]",str_input);
scanf("%[^0-9]",str_input);
scanf("%[A-Zaz-z]",str_input);
str_input = fgetc(stdin);

以上都不适合我。

输入

2

黑客

预期输出

Hce akr

int main() {
    char *str_input;
    size_t bufsize = 108;
    size_t characters;

    str_input = (char *)malloc(bufsize * sizeof(char));
    if (str_input == NULL)
    {
        perror("Unable to allocate buffer");
        exit(1);
    }

    characters = getline(&str_input,&bufsize,stdin);
    printf("%zu characters were read.\n",characters);
    int i;
    int len = 0;

    for (i = 0, len = strlen(str_input); i<=len; i++) {
        i%2==0? printf("%c",str_input[i]): 'b'; 
    }
    printf(" ");

    for (i = 0, len = strlen(str_input); i<=len; i++) {
        i%2!=0? printf("%c",str_input[i]): 'b'; 
    }
    return 0;
}

错误

solution.c: In function ‘main’:
solution.c:21:5: warning: implicit declaration of function ‘getline’ [-Wimplicit-function-declaration]
     characters = getline(&str_input,&bufsize,stdin);

【问题讨论】:

  • 使用- 来表示字符范围是实现定义的特性。
  • 通常你首先得到输入然后扫描它。 fgetc 得到一个字符,但您似乎想要一个字符串。我进一步了解您想拒绝输入数字。这意味着告诉用户类似Wrong input. Please re-enter 的信息,这意味着一个循环,直到你得到正确的输入。
  • 读取整行(使用fgets)然后手动循环字符串以确保它只有letters(可能还有spaces)?
  • @PaulOgilvie 是的,我尝试了一个循环,但没有成功。我什至试过 while(isalpha(str_input)){................} 它没有用
  • 提示:使用 strspn() 查找仅包含属于某个集合的字符的初始子字符串的长度。

标签: c arrays char scanf


【解决方案1】:

如果您使用的是 Linux,我会使用 getline() 函数来获取整行文本,然后对其进行验证。如果它不是有效的输入,我会在一个循环中要求用户一次又一次地输入一行文本,直到你的输入是可以接受的。

如果不使用 Linux,那么最好的选择可能是重新实现 getline()。如果您发现可以接受有限大小的缓冲区,也可以使用 fgets()。我不认为有限大小的缓冲区是可以接受的,所以我更喜欢 getline()。

getline() 按照其手册页中解释的方式使用:http://man7.org/linux/man-pages/man3/getdelim.3.html

基本上,您的循环应该类似于:

char *buf = NULL;
size_t bufsiz = 0;
while (1)
{
    if (getline(&buf, &bufsiz, stdin) < 0)
    {
        handle_error();
    }
    if (is_valid(buf))
    {
        break;
    }
    printf("Error, please re-enter input\n");
}
use_buffer(buf);
free(buf);

【讨论】:

  • getline() 不会转义数值
  • @ARTHURDECKER 这将是“如果输入无效...”的一部分
【解决方案2】:

这是不可能的。数字也是字符串。但是您可以设置循环来查找数字并打印错误。像这样:

 char *str = "ab234cid20kd", *p = str;
while (*p) { // While there are more characters to process...
    if (isdigit(*p)) { // Upon finding a digit, ...
        printf("Numbers are forbidden");
        return 0;
    } else {
        p++;
    }
}

【讨论】:

  • 可怜的字符串字面量,连const的荣誉都没有。
【解决方案3】:

由于您的缓冲区大小有限,因此使用fgets(3) 就可以了。 fgets() 在读取行失败时返回 NULL,并在缓冲区末尾附加一个换行符。

就防止数字字符进入缓冲区而言,您可以简单地创建另一个缓冲区,并且只向其中添加非数字字符。您可以从原始缓冲区中删除数字字符,但如果您仍然掌握 C 的基础知识,这可能是一个乏味的过程。另一种方法是使用 getchar(3) 读取单个字符输入,这将允许您评估每个字符并简单地忽略数字。这种方法是迄今为止最容易实现的。

由于您要求提供使用fgets() 的示例,这里是一些示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define INPUTSIZE 108

int main(void) {
    char str_input[INPUTSIZE], characters[INPUTSIZE];
    size_t slen, char_count = 0;

    printf("Enter input:\n");
    if (fgets(str_input, INPUTSIZE, stdin) != NULL) {

        /* removing newline from fgets() */
        slen = strlen(str_input);
        if (slen > 0 && str_input[slen-1] == '\n') {
            str_input[slen-1] = '\0';
        } else {
            fprintf(stderr, "Number of characters entered exceeds buffer size\n");
            exit(EXIT_FAILURE);
        }

        /* checking if string is valid */
        if (*str_input == '\0') {
            fprintf(stderr, "No input found\n");
            exit(EXIT_FAILURE);
        }

        printf("Buffer: %s\n", str_input);

        /* only adding non-numbers */
        for (size_t i = 0; str_input[i] != '\0'; i++) {
            if (!isdigit(str_input[i])) {
                characters[char_count++] = str_input[i];
            }
        }

        /* terminating buffer */
        characters[char_count] = '\0';

        printf("New buffer without numbers: %s\n", characters);
    }

    return 0;
}

示例输入:

Enter input:
2ttt4y24t4t3t2g

输出:

Buffer: 2ttt4y24t4t3t2g
New buffer without numbers: tttytttg

更新:

您可以使用这种更简单的方法来忽略非数字字符:

char str_input[INPUTSIZE];
int ch;
size_t char_count = 0;

while ((ch = getchar()) != EOF && ch != '\n') {
    if (!isdigit(ch)) {
        if (char_count < sizeof(str_input)) {
            str_input[char_count++] = ch;
        }
    }
} 

str_input[char_count] = '\0';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 2022-09-24
    • 2012-10-06
    • 1970-01-01
    • 2017-04-03
    • 2021-07-08
    相关资源
    最近更新 更多