C数字代码验证器

时间:2014-02-10 10:38:41

标签: c

我是C和编程的新手,所以我研究了一下,想制作一个简单的程序来验证我国的个人数字代码。这是该计划:

#include <stdio.h>

int validateCNP(char cnp[13]);

int main(int argc, const char * argv[])
{
    char cnp[13];
    printf("Introduceti CNP-ul:\n");
    scanf("%s", cnp);
        if(validateCNP(&cnp[0]) == 1) {
    printf("CNP valid");
        } else {
            printf("CNP invalid");
        }


    return 0;
}

int validateCNP(char cnp[13]) {

    char verif[13];
    int intVerif[12], intCnp[13];
    int i, checksum = 0;
    strcpy(&verif[0], "279146358279");

    for (i = 0; i<11; i++){
        intVerif[i] = (unsigned)verif[i] - 48;
    }

    for (i=0; i<12; i++) {
        intCnp[i] = cnp[i] - 48;
    }

    for (i=0; i<11; i++) {
        checksum += intCnp[i] * intVerif[i];
    }

    checksum %= 11;

    if (checksum == intCnp[12]) {
        return 1;
    } else {

    return 0;
    }
}

示例输出

Introduceti CNP-ul:
1650116398203
(lldb) 

似乎当它将字符串转换为int数组时,它会搞砸最后一个元素

Printing description of intVerif:
(int [12]) intVerif = {
  [0] = 2
  [1] = 7
  [2] = 9
  [3] = 1
  [4] = 4
  [5] = 6
  [6] = 3
  [7] = 5
  [8] = 8
  [9] = 2
  [10] = 7
  [11] = 32767
}
Printing description of intCnp:
(int [13]) intCnp = {
  [0] = 1
  [1] = 6
  [2] = 5
  [3] = 0
  [4] = 1
  [5] = 1
  [6] = 6
  [7] = 3
  [8] = 9
  [9] = 8
  [10] = 2
  [11] = 0
  [12] = 0
}

有人能指出我做错了什么,我尝试了不同的方法,似乎都没有。

2 个答案:

答案 0 :(得分:1)

你循环从0转到10

for (i = 0; i<11; i++){
        intVerif[i] = (unsigned)verif[i] - 48;
    }

你永远不会写intVerif[11]所以它包含垃圾。

intCnp[]中的类似问题。

编辑 :(在OP的评论中)

看起来您的输入:"1650116398203"13个字母,而cnp数组需要一个额外的\0字符空格。因此,您的输入会导致数组越界,从而导致未定义的行为。

答案 1 :(得分:1)

MadHatter已经指出了你的基本错误:你的循环省略了最后一个条目。

另一个错误在于main:CNP长度为13个字符,因此您的cnp数组必须至少包含14个字符 - 您必须为终止空字符'\0'提供空间。您还应该限制要在oder中读取的字符长度,以避免缓冲区溢出:

scanf("%13s", cnp);

这里,13个表示最多读取13个字符(加上终止空字符)。

最好检查一下你的字符串是否真的有13个数字,这样你就不会处理垃圾字符了。而且你忘了满足余数为10的情况 - 在这种情况下,校验位为1。