验证长度为11的整数并以0开头

时间:2015-12-26 22:43:02

标签: c

我试图创建一个验证移动入口的功能,手机号码必须从0开始,并且是11个数字(例如01281220427)。

我想确保程序获得正确的输入。

这是我的尝试:

setInterval

现在,如果我不使用

#include <stdio.h>
#include <strings.h>


void integerValidation(char x[15]);

int main(int argc, char **argv)
{
    char mobile[15];
    integerValidation(mobile);
    printf("%s\n\n\n", mobile);
    return 0;
}


void integerValidation(char x[15]){
    char input[15];
    long int num = -1;
    char *cp, ch;
    int n;
    printf("Please enter a valid mobile number:");
    while(num<0){
        cp = fgets(input, sizeof(input), stdin);
        if (cp == input) {
        n = sscanf(input, "%ld %c", &num, &ch);
        if (n!=1) {printf("ERROR! Please enter a valid mobile number:");
            num = -1;
        }
        else if (num<0)
            printf("ERROR! Please enter a valid mobile number:");
        else if ((strlen(input)-1)>11 || (strlen(input)-1)<11 || strncmp(&input[0], "0", 1) != 0){
            printf("ERROR! Please enter a valid mobile number:");
            num = -1;
        }
        }
    }

    long int i;
    i = strlen(input);
    //Because when I try to print it out it prints a line after number.
    strcpy(&input[i-1], "");
    strcpy(x, input);

}

数组在数字后打印一个新行,除了我的之外还有什么好处?以及如何使此功能优化和缩短?

提前致谢!

修改 我的问题是:1。为什么输入数组最后会打印一个新行? 2.如何缩短此代码? 编辑结束。

3 个答案:

答案 0 :(得分:1)

如果您坚持使用sscanf(),则应以这种方式更改格式:

int integerValidation(char x[15]) {
    char input[15], c;

    printf("Please enter a valid mobile number:");
    while (fgets(input, sizeof(input), stdin)) {
        if (sscanf(input, "%11[0123456789]%c", x, &c) == 2
         && x[0] == '0' && strlen(x) == 11 && c == '\n') {
            // number stored in `x` is correct
            return 1;
        }
        printf("ERROR! Please enter a valid mobile number:");
    }
    x[0] = '\0';  // no number was input, end of file reached
    return 0;
}

%12[0123456789]解析最多11个必须为数字的字符。 %c读取以下字符,该字符应为尾随'\n'。 我验证两种格式都已匹配,并且号码以0x[0] == '0')开头,并且正好有11位数字。

答案 1 :(得分:0)

您正在查看换行符,因为fgets()会一直读取,直到收到EOF或换行符。换行符存储在缓冲区中,之后字符串以'\0'终止。

另一种方法是直接使用另一个空字节覆盖换行符:input[i-1] = '\0'(基本上与解决方案完全相同,但保存函数调用)。

对于长度为1的strncmp检查也是如此,您可以直接检查input[0] == '0'。请注意,您必须与&#39; 0&#39;进行比较。 (char)在这里,不是&#34; 0&#34; (字符串)。

我看到的其他一些事情:

您还可以在sscanf的格式字符串中保留%c(无论如何您都不会评估它,因为您要检查1作为返回值),这也消除了对char ch

此外,您将char x[15]作为参数传递给您的函数。这有点误导,因为实际传递的是一个指向char数组的指针(尝试使用sizeof(x),您的编译器很可能会发出关于sizeof()返回的char *大小的警告。 / p>

你可以做的是抛弃你使用的char数组输入作为临时缓冲区,并使用作为参数移交的缓冲区。为了保存这个,你应该使用第二个funcion参数来指定传递给函数的缓冲区的大小,这将产生如下函数头:

void integerValidation(char *input, size_t len);

有了这个,你必须使用len而不是sizeof(输入)。以下问题提供了更详细的原因:C: differences between char pointer and array 由于您不再使用临时缓冲区,因此可以删除对strcpy()的最终调用。

还有很多检查数字长度/格式。你可以节省一些: 如果您使用%lu而不是%ld,则不会转换任何已签名的数字,从而节省了对num&lt; 0。 您正在检查读取的数字的长度是否为&lt; 11或&gt; 11 - 为什么不检查!= 11?

你在输入缓冲区上调用了strlen()三次(或者仍然使用了返工11的返工检查两次) - 调用它一次是有意义的,将长度保存在变量中并使用该变量从那时起,因为你没有改变通话之间的字符串。

答案 2 :(得分:0)

已经有一个公认的答案,但是对于它的价值,这是另一个答案。

我对您的代码进行了一些更改,首先通过定义电话号码长度和任意更大的字符串长度来避免“魔术数字”。然后没有必要将数组x[15]传递给函数,因为它不考虑它的长度,也可以使用更简单的*x指针。接下来,我将失败的所有原因归还给调用者,这更简单。而不是试图将电话号码视为数字条目(注意:字母,空格,连字符,逗号和#有时也可能是电话号码的一部分)我坚持使用字符串。另一个原因是,如果将条目转换为某个大小的int,则所需的前导零将消失。我删除newline使用输入行读取的尾随fgets(),结果就是这样。

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

#define MAXLEN 11
#define STRLEN (MAXLEN+10)

int integerValidation(char *x);

int main(int argc, char **argv)
{
    char mobile[STRLEN];
    while (!integerValidation(mobile))      // keep trying
        printf("Invalid phone number\n");
    printf("%s\n\n\n", mobile);             // result
    return 0;
}

int integerValidation(char *x)
{
    int i, len;
    printf("Please enter a valid mobile number:");
    if(fgets(x, STRLEN, stdin) == NULL)     // check bad entry
        return 0;
    x [ strcspn(x, "\r\n") ] = 0;           // remove trailing newline etc
    if((len = strlen(x)) != MAXLEN)         // check length
        return 0;
    if(x[0] != '0')                         // check leading 0
        return 0;
    for(i=1; i<len; i++)                    // check all other chars are numbers
        if(!isdigit(x[i]))
            return 0;
    return 1;                               // success
}