c语言中字符串的输入验证



我试图做一个循环,不停止,直到用户输入一个字符串。例如,如果用户输入一个数字或字母,它将显示Invalid input,直到用户输入一个字符串。

但是由于一些奇怪的原因,当我运行我的代码并输入一个字符串时,程序继续循环代码块。下面是输出

#include <stdio.h>
int main() {
char name[100];
char letter[100];
lt:
printf("33[0;33m");
printf("nEnter your Name:ni.e. Migueln");
printf("33[0m");
scanf("%s", name);
if (name != letter) {
printf("33[0;31m");
printf("Invalid input");
printf("33[0m");
goto lt;
}
return0;
}

我已经尝试了goto函数来循环代码,但似乎不工作。

未初始化变量:

char letter[100];

letter在代码中未初始化使用。它的内容不确定。使用自动存储声明的变量不会隐式初始化为0。

比较字符串

:

if (name != letter)

这只比较指针地址(我认为它调用了未定义的行为),而不是这些指针所指向的内容。

C标准库提供了一个比较两个字符串的函数strcmp

注意:string.h中声明。

缓冲区溢出漏洞:

scanf("%s", name);

类似于使用gets(在限制输入方面)。scanf将很高兴地继续从stdin读取,直到它看到空白,忽略空白右侧的所有内容,(这会导致更多的问题),并可能溢出缓冲区。

您可以使用字段宽度来限制输入:

scanf("%99s", name);

或者更好,使用fgets

fgets(name, sizeof(name), stdin);

它将最多读取n - 1个字符并以空结束字符串。

旁注:fgets将在缓冲区中存储n字符,这可能不是您想要的。下面是删除它的一种方法¹:

name[strcspn(name, "nr")] = '';

scanf返回成功转换的次数:

忽略scanf的返回值违背了Henry Spencer的" the Ten Commandments for C programmer ">:

如果通知函数在事件时返回错误码困难,你应该检查代码,是的,即使检查会使代码的大小增加三倍,并在键入时产生疼痛手指,因为如果你认为这不会发生在我身上,诸神我一定会惩罚你的傲慢。

if (scanf("%99s", name) != 1) {
handle the error here..
}

使用goto:

虽然这是合法的用法,但不鼓励使用。goto不应用于此类目的。

相反,正如@ simonater建议的那样,使用while循环。


如果用户输入一个数字或字母,它会显示无效输入直到用户输入字符串。

所以要求是:

  1. 名称必须大于1个字符。
  2. 名称中不应该有任何数字。(但是我的朋友的名字有数字,甚至有特殊字符。: - ()

注意:

  • 你不能有一个char的字符串,除非char是一个空字节。

可能的解决方式:

  • 由于strlen不包含空终止符,我们可以使用它来计算字符串的长度,如果它等于1,则相应地处理错误。

  • 逐个字符遍历缓冲区,如果发现数字或特殊字符,则相应地处理错误。

[1]你可能想要阅读更多:https://codereview.stackexchange.com/q/67608

#include <stdio.h>
#include<conio.h>
#include<string.h>
int main(){
char name[100];
char letter[100]="amir";
lt:
printf("33[0;33m");
printf("nEnter your Name:ni.e. Migueln");
printf("33[0m n");
scanf("%s",name);
if(strcmp(name, letter) != 0){
printf("33[0;31m");
printf("Invalid input");
printf("33[0m");
goto lt;
}
return 0;
}

最新更新