这是我的atm机器的代码。它首先要求用户输入卡号,然后是Pin,然后是有效期。
char card_number[16];
memset(card_number,0,16);
char pin[4];
memset(pin,0,4);
char exp_date[5];
memset(exp_date,0,5);
printf("Enter Card number \n");
//scanf ("%s",&card_number);
fgets (card_number, 16, stdin);
printf("Enter pin\n");
//scanf ("%s",&pin);
fgets (pin, 4, stdin);
printf("Enter expiry date\n");
//scanf ("%s",&exp_date);
fgets (exp_date, 5, stdin);
char data[25];
memset(data,0,25);
char reply[25];
memset(reply,0,25);
int i = 0;
for(i=0;i<25;i++)
{
if(i<16)
{
data[i] = card_number[i];
}
if(i>=16 && i<20)
{
data[i] = pin[i-16];
}
if(i>=20 && i<25)
{
data[i] = exp_date[i-20];
}
}
printf("data: %s",data);
它不需要输入引脚。它只打印出存储在数据数组中的前15个字符。没有其他的。我的代码有什么问题?
答案 0 :(得分:2)
问题在于此代码段之后
if(i<16)
{
data[i] = card_number[i];
}
数组data
还包含从'\0'
和函数card_number
printf
printf("data: %s",data);
输出所有字符,直到遇到此终止零,忽略其后的所有其他字符,
另一个问题可能是,如果您为阵列输入了恰好16个字符
card_number
然后新行字符仍将在输入缓冲区中。在这种情况下,fgets
的第二次调用将只读取此新行字符。在这种情况下,您应该将数组放大一个字符。
你应该写
#include <string.h>
//...
card_number[ strcspn( card_number, "\n" ) ] = '\0';
pin[ strcspn( pin, "\n" ) ] = '\0';
exp_date[ strcspn( exp_date, "\n" ) ] = '\0';
strcpy( data, card_number );
strcat( data, pin );
strcat( data, exp_date );
或者,如果您不想从字符串中删除新行字符,则排除这些语句
card_number[ strcspn( card_number, "\n" ) ] = '\0';
pin[ strcspn( pin, "\n" ) ] = '\0';
exp_date[ strcspn( exp_date, "\n" ) ] = '\0';
并仅使用
strcpy( data, card_number );
strcat( data, pin );
strcat( data, exp_date );
此外,无需致电memset
。这可以由编译器本身完成。只需声明像
char card_number[16] = { '\0' };
或
char card_number[17] = { '\0' };
^^^^
使用魔术数字是一个坏主意。最好像
这样编写fgets( card_number, sizeof( card_number ), stdin);
答案 1 :(得分:1)
读取用户输入的数组不足以容纳您放入的数据。每个数组需要一个额外字节来保存终止空字节。
char card_number[17];
memset(card_number,0,sizeof(card_number));
char pin[5];
memset(pin,0,sizeof(pin));
char exp_date[6];
memset(exp_date,0,sizeof(exp_date));
答案 2 :(得分:1)
card_number
的最后一个字符始终为char
,其值为零('\0'
) - 这就是fgets()
的作用。你的循环将复制该值。 %s
格式会在遇到它时停止。
您的代码需要在复制时考虑'\0'
(在所有字符串中)的存在,并确保复制最后一个(以避免使用%s
的未定义行为)。
如果您希望在用户点击ENTER之前输入完全16
个字符,并且数组的长度为16
,则需要调用fgets()
两次(以获取两个单独的部分中的总输入)或缓冲区需要17
个字符或更多。 fgets()
不会删除换行符(如果存在),因此您的代码需要处理它。阅读fgets()
的文档。