C isdigit()输入测试有效电话号码
我想创建一个算法,检查用户是否输入了有效的电话号码(仅限数字)。该程序应不断提示用户输入电话号码,直到完全正确为止。我想到了以下几点 程序限制:必须使用malloc(realloc可以),phoneNum必须是指针而不是数组,需要时执行C isdigit()输入测试有效电话号码,c,C,我想创建一个算法,检查用户是否输入了有效的电话号码(仅限数字)。该程序应不断提示用户输入电话号码,直到完全正确为止。我想到了以下几点 程序限制:必须使用malloc(realloc可以),phoneNum必须是指针而不是数组,需要时执行 int main (void) { int i, flag; char* phoneNum; phoneNum = NULL; phoneNum = malloc(sizeof(char)); do{
int main (void)
{
int i, flag;
char* phoneNum;
phoneNum = NULL;
phoneNum = malloc(sizeof(char));
do{
printf("Phone Number: ");
fgets(phoneNum, sizeof(phoneNum) * 10, stdin);
phoneNum[strcspn(phoneNum, "\n")] = 0;
flag = 1;
for (i = 0; i < strlen(phoneNum); i++){
if(isdigit(phoneNum[i]) == 0){
flag = 0;
break;
}
}
} while (flag == 1);
printf("Valid Number: %s", phoneNum);
return 0;
}
预期产出:
Phone Number: 12345
Valid Number: 12345
Phone Number: abcdefg
Phone Number: hijklmn
Phone Number: 123456
Valid Number: 123456
感谢所有帮助我提出以下解决方案的用户,如果您遇到这个问题,这里是解决方案
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main (void)
{
int i, flag;
char* phoneNum;
phoneNum = malloc(11);
if (phoneNum == NULL){
printf("Not Enough Memory!\n");
}
do{
printf("Phone Number: ");
fgets(phoneNum, 11, stdin);
printf("<You entered: %s>\n", phoneNum); //check to see if program received user input.
phoneNum[strcspn(phoneNum, "\n")] = 0;
flag = 1;
for (i = 0; i < strlen(phoneNum); i++){
if(isdigit(phoneNum[i]) == 0){
flag = 0;
break;
}
}
} while (flag == 0);
printf("Valid Number: %s", phoneNum);
free(phoneNum);
return 0;
}
#包括
#包括
#包括
#包括
内部主(空)
{
int i,旗帜;
char*phoneNum;
phoneNum=malloc(11);
如果(phoneNum==NULL){
printf(“内存不足!\n”);
}
做{
printf(“电话号码:”);
fgets(phoneNum,11,stdin);
printf(“\n”,phoneNum);//检查程序是否收到用户输入。
phoneNum[strcspn(phoneNum,“\n”)]=0;
flag=1;
对于(i=0;i
首先也是最重要的问题是,您使用
phoneNum = malloc(sizeof(char));
然后,在不检查分配是否成功的情况下,在获取输入的同时,使用
fgets(phoneNum, sizeof(phoneNum) * 10, stdin);
这显然是内存溢出。这导致了
如果以后不想realloc()
,则需要通过malloc()
提供要分配的所需内存的确切大小
另外,请记住,在使用fgets()
扫描输入时,您需要自己处理尾随的换行符
也就是说,根据您的要求,您的逻辑似乎是错误的。一旦用户输入了所有数字(正确),就应该停止循环,否则继续循环。因此,您需要将逻辑更改为
- 将标志初始化为
0
- 如果找到非数字,请将标志设置为
。(你已经在做了)1
- 循环基于
(您也已经这样做了)标志==1
phoneNum = malloc(sizeof(char));
仅为一个字符创建空间:
|1|
您正在尝试写入一个包含11个字符的字符串:1+电话号码
|1|5|5|5|2|2|2|4|4|4|4|
…带有1位数字的空格。但根据电话号码的输入方式,电话号码字符串可能需要以下内容:
- 10位数的空格
- 前面1的空格
- 换行符的空格(如果使用
等读取输入)fgets()
- 空字符的空格
- 为电话号码留出适当的标点
|1|5|5|5|2|2|2|4|4|4|4|\n|\n|\0|
|1|.|5|5|5|.|6|6|6|.|1|2|3|4|\n|\0|
或者这个:
|1|(|5|5|5|)|6|6|6|-|1|2|3|4|\n|\0|
或者这个:
|1|5|5|5|2|2|2|4|4|4|4|\n|\n|\0|
|1|.|5|5|5|.|6|6|6|.|1|2|3|4|\n|\0|
即使处理电话号码适当的标点((,),-,.
)超出范围,为大小合理的字符串分配额外内存也不会错,例如为安全起见为80或更多。只要在完成后将其释放,就可以创建更多的空间
将内存分配更改为:
phoneNum = malloc(80);//11 digit phone number, plus \n plus NULL Plus user unpredictability.
其他故障已被排除,但由于您设置了
flag = 0;
// ...
} while (flag == 1);
经过错误的数字测试。请试一试
} while (flag == 0);
根据OP的评论进行编辑。这是我的测试版本。关于有符号/无符号测试,有一个编译器警告,我对分配内存的方式很松懈(而且您对fgets
的使用也很松懈),但是示例的目的显示了我所做的事情——主要是您的确切代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (void)
{
int i, flag;
char* phoneNum;
phoneNum = malloc(20);
do{
printf("Phone Number: ");
fgets(phoneNum, 20, stdin);
phoneNum[strcspn(phoneNum, "\n")] = 0;
flag = 1;
for (i = 0; i < strlen(phoneNum); i++){
if(isdigit(phoneNum[i]) == 0){
flag = 0;
break;
}
}
} while (flag == 0);
printf("Phone Number: %s", phoneNum);
return 0;
}
不要忘记,
fgets
在字符串中包含一个尾随的newline
,如果它出现在输入中的话。这包括在strlen
@WeatherVane的返回值中,所有正确的建议,先生,都是无用的,除非分配了适当的内存。:)@苏拉沃什:我知道你的答案,但OP也需要知道这一点。@WeatherVane绝对,毫无疑问。:)通常,在打印字符串printf(“有效数字:”,phoneNum)时,用括号将文本包围起来,以清楚地标识意外的空白(空格、新行)代码>`我的malloc不是只创建了1个字节吗,然后在我的fgets中,我将它乘以10,从而创建了10个字节吗?(根据我的理解,我显然错了)。此外,我的局部变量在我的do循环中被初始化为flag=1,程序总是进入该循环。我是否也应该在do循环之外初始化它?@shrimpay 1)不,只是乘以大小不会重新调整内存,您需要通过提供大小来分配内存,或者需要重新分配内存。2) 忽略未初始化的部分,误读代码。@ChrisTurner需要设置标志,它会通知您是否输入了全数字电话号码。@ChrisTurner然后,您将使用一个不确定的值来点击UB。@shrimpay刚刚添加了一点逻辑,看看这是否有帮助。malloc(11)
和(sizeof)之间有什么区别(char)*11)
?因为sizeof(char)=1,…1*11==11。没有区别。这是一种简化。对于其他类型,例如int
,或float
,sizeof(type)变得更重要了。@chux-同意。好的观点。我在回答中都提到了。谢谢。谢谢,对于这个作业,我们只需要担心这个格式1234567
,但是对于下一个,我将回到这个线程,因为我们需要这个格式(xxx)xxx-xxxxx
感谢所有关于内存的帮助,我仍在尝试调试一些问题,但对于阅读本文的所有人,我非常感谢。@shrimpay-不客气。所有答案中都有一些非常好的建议,请确保向上单击任何有帮助的建议,如果其中一个回答您的问题特别好,请单击“接受”按钮ck标记。即使输入了有效的电话,循环现在也不会退出。在我的测试版本中会这样做(使用正确的记忆)