我是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
}
有人能指出我做错了什么,我尝试了不同的方法,似乎都没有。
答案 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。