isdigit()输入有效电话号码的测试

时间:2017-03-17 17:41:42

标签: c

我想创建一个算法,检查用户是否输入了有效的电话号码(仅限数字)。程序应该一直提示用户输入一个电话号码,直到它是严格的数字。我想出了以下内容。

程序限制:必须使用malloc(realloc没问题),phoneNum必须是指针而不是数组,do-while required。

    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;
    }

然而,isdigit似乎不起作用,我不确定是什么问题。任何帮助,将不胜感激。这是当前/预期的输出。没有编译问题。

电流输出:

Phone Number: 12345678
Valid Number: 12345678

Phone Number: abcdefg
Valid Number: abcdefg

Phone Number: 1234abcd
Valid Number: 1234abcd

预期产出:

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;
    }

3 个答案:

答案 0 :(得分:3)

首要问题是,您使用

分配内存
 phoneNum = malloc(sizeof(char));

然后,甚至没有检查分配成功,在接受输入时,你使用

 fgets(phoneNum, sizeof(phoneNum) * 10, stdin);

显然是内存溢出。这会导致undefined behavior

如果您以后不想malloc(),则需要提供通过realloc()分配的所需内存的确切大小。

另外,请记住,在使用fgets()扫描输入时,您需要自己处理尾随换行符。

那就是说,根据你的要求,你的逻辑似乎是错误的。一旦用户输入了全位数(这是正确的),你应该停止循环,否则,保持循环。因此,您需要将逻辑更改为

  • 将标记初始化为0
  • 如果找到非数字,请将标记设置为1。 (你已经在做了)
  • 循环基于flag == 1(你也已经在做)

See a modified version online

答案 1 :(得分:2)

声明:

phoneNum = malloc(sizeof(char));

仅为一个字符创建空间:

|1|

您正在尝试写一个包含11个字符的字符串:1 +电话号码......

|1|5|5|5|2|2|2|4|4|4|4|

...有1位数的空格。但是,根据电话号码的输入方式,电话号码字符串可能需要以下内容:

  • 10位数的空格
  • 前一个空格
  • 换行符的空格(如果使用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|

即使处理适当的标点符号(,),-,.)的电话号码超出范围,为合理大小的字符串分配额外内存也不错,例如80或更多注意安全。只要你在完成时释放它,创造更多空间就没有害处。

将内存分配更改为:

phoneNum = malloc(80);//11 digit phone number, plus \n plus NULL Plus user unpredictability.

答案 2 :(得分:1)

已经回答了其他错误,但由于您设置了

,因此您的循环条件也是错误的
    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;
    }

计划会议:

F:\Work\CTEST>test
Phone Number: 12345678
Phone Number: 12345678
F:\Work\CTEST>