c - C 中的字符串验证 : Trying to ask for a new string when the old one has an invalid character

标签 c string validation input

我的这段代码有一个小故障,不知道如何修复它。

我想一次读取一个输入的随机字符字符串。

一旦读取到无效字符,我希望程序停止读取字符串并提示用户输入新字符串。

无论字符串长度如何,程序也最多只能读取和存储 5 个字符,除非在 5 个字符限制之前达到字符串结尾。

代码:

    int check; //1 = invalid char in string, 2 = otherwise
    char c;
    char seq[5]; 

    do{     printf("Enter a string of only "+" and "-" \n");

            for(i=0; c!=EOF || i<5 ; i++){
                    scanf("%c",&seq[i]);
                    if((seq[i] != '\x2b') || (oseq[i] != '\x2d')){
                            printf("invalid sequence, try again\n");
                            check=1;
                            break;
                    }
                    check=2;
            }

    }while(check==1);

请帮忙,我知道这是一个简单的解决方案,但它就是不来找我,我已经搜索/尝试了一切。

我应该补充一点,这段代码会继续读取,并且每次到达无效字符时都会打印出来,而不让用户输入新字符,直到到达字符串末尾。

最佳答案

考虑一下当前的 for 循环将要做什么:

        for(i=0; c!=EOF || i<5 ; i++){

对于从 0 开始的 i,当 c 不是 EOF 或 i 小于 5 时运行。

因此,如果 c 不是 EOF,则 i 为 0, 1, 2, 3, 4, 5, 6, 7, ... 1000,因为只要“c != EOF”,我们的代码就会忽略 i。

访问 seq[1000] 不是您想要的。

此外,就 c 而言,for 循环的初始迭代会检查 c != EOF 但您从未将 c 初始化为值。这是未定义的行为,c 可以是任何东西,因此您的循环可能会运行,也可能永远不会运行 c 碰巧以与 EOF 定义相同的值开始。

我建议您简化为:

        for(i=0; i<5 ; i++){

然后将有效性检查保留在循环内,如果 c 是 EOF 或其他无效值,请使用 break 退出 for 循环并保持 for(...) 条件简单。此更改将解决 for 循环的两个问题。

除此之外,您还表示其目的是最多存储 5 个字符。在 C 中,如果您打算将字符数组视为字符串,则必须为尾随空终止字符留出空间,因此始终使用 N + 1 作为数组大小。如果您打算稍后打印它,则应该使用 seq[6] ,并确保将字符串的最后一个字符(在读取最后一个字符之后)设置为 0(或“\0”) .

根据您的无限循环问题,您被老初学者使用 scanf() 的运气所困扰,这是一个糟糕的输入函数。我已经用 C 语言编码了 20 年,说实话,我在 19 年前就忘记了如何有效地使用 scanf,因为它不适合大多数输入需求(我喜欢它的兄弟 printf,但那是另一个故事了)。 scanf() 将准确扫描您所要求的内容,但如果它不处理输入,则不会扫描该输入。如果您考虑一下当您输入一个字符并按回车键时,您实际上输入了 2 个字符(在 UNIX 上计算\n 或在 Windows/DOS 上计算\r\n 3 个)。在您的情况下,您每次迭代都会缓冲额外的字符。

您可以在 scanf() 调用后使用类似的方法清除输入缓冲区。

while ((ch = getchar()) != '\n' && ch != EOF); 

但我避免使用 scanf() 并直接使用 fgets() 或 getchar() 。应避免使用 scanf()。所有 C 程序员都是从在学校学习 scanf() 开始的,然后他们最终了解到除格式化文件之外的任何内容都应避免使用它。

关于c - C 中的字符串验证 : Trying to ask for a new string when the old one has an invalid character,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26076991/

相关文章:

Android 重启命令 - 谁调用reboot_main()?

c - 将字符串的内容解析为子字符串

c - VC++ 2010 中的内联汇编错误

ruby - 单引号 Ruby 字符串——不一致的转义

javascript - 如果服务器端验证失败,则在 OnClick 事件中显示警报

c++ - core_c.h的OpenCV包含错误

java - 如何在 Java 中比较字符串?

php - php中的随机字符串列表

wpf - 从标签中删除 WPF 验证装饰

php - 如何使用 SQL/PHP 验证日期的日期和月份是否在范围内