通过atoi转换的复制字符串传递0

时间:2011-08-17 06:40:58

标签: c

这个工具如果准备就绪,应该计算出一个人的年龄。它获得systemdate并询问用户是否有生日。然后它将输入的字符串拆分为“年”(bjahr),“月”(bmonat)和“日”(btag),将重要字符复制到新字符串中。在此之后,它通过atoi将它们转换为int值。

检查一切都很顺利,我打印出来。但问题就出现了。今年工作正常,但“intmonat”和“inttag”似乎是0。 我找不到错误,请你帮帮我吗?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string.h>

int main ()
{
    SYSTEMTIME time;
    GetSystemTime (&time);

char name[20], bday[10], bjahr[4], bmonat[2], btag[2]; 

int year = time.wYear;
int month = time.wMonth;
int day = time.wDay;
int intjahr, intmonat, inttag;

printf("\n\n today is the: %i.%i.%i \n\n",day,month,year);
printf(" please insert Birthdate (dd.mm.jjjj).\n\n");

gets(bday);

strncpy(bjahr , &bday[6], 5);
strncpy(btag  , &bday[0], 1);
strncpy(bmonat, &bday[3], 1);

intjahr  = atoi(bjahr) ;
intmonat = atoi(bmonat);
inttag   = atoi(btag)  ;

printf("\n\n jahr %i \n\n",intjahr);
printf(" monat %i \n\n",intmonat);
printf(" tag %i \n\n",inttag);        

system("PAUSE");

}

我是德国人,这就是为什么有些词可能不是英语,希望无关紧要。

2 个答案:

答案 0 :(得分:2)

您的变量太短:例如,您希望本月有两个字符,但您还需要考虑终止字符串的\0。此外,您只是每天和每月复制一个字符而不是空终止它。所以它应该是:

char name[20], bday[11], bjahr[5], bmonat[3], btag[3];

...

gets(bday);

strncpy(bjahr , &bday[6], 4);
bjahr[4] = 0;
strncpy(btag  , &bday[0], 2);
btag[2] = 0;
strncpy(bmonat, &bday[3], 2);
bday[2] = 0;

但更好的解决方案是使用scanf代替,您应该阅读并熟悉它。例如,它可以轻松帮助您正确解析1.2.2000之类的输入。

此外,当前具有固定大小数组的解决方案很容易产生缓冲区溢出(只需输入abcdefghijklmnopqrst)。你应该这样做:

fgets(bday, sizeof(bday), stdin);

答案 1 :(得分:1)

你的strncpy略有偏离,你想要这样,所以你可以捕获正确的数字位数:

strncpy(bjahr , &bday[6], 4);
strncpy(btag  , &bday[0], 2);
strncpy(bmonat, &bday[3], 2);

另外,你的缓冲区应该稍大一点,以适应atoi要求的NULL终止符(我将对齐为4的倍数只是为了更好地匹配编译堆栈分配器将要做的事情),你可以自己添加,或者通过预先调整缓冲区来实现:

char name[20] = {0}, bday[10] = {0}, bjahr[8] = {0}, bmonat[4] = {0}, btag[4] = {0};

但是,使用sscanf

scanf之类的内容会做得更好