1

私はcを初めて使用し、奇妙な状況に陥っています。文字列入力として取得した日付を更新しようとしていますが、コードは

typedef struct Employee
{
char fname[20];
char lname[20];
int eme_id;
int emr_id;
char department[20];
int age;
char join_date[20];
float bsal;
float pol_value;
char pol_start_date[20];
char pol_end_date[20];
float premium;
float pre_payment;
char pre_pay_date[20];
int pre_status;/* 0 then not paid 1 then paid*/
float bonus;
}Employee;


char *update_date(char *dat)
{

char *result = NULL;
printf(dat);
result = strtok( dat, "/" );
int date[3];
int i=0;
while( result != NULL ) {
    printf( "result is \"%s\"\n", result );
    date[i] = atoi( result );
    printf( "%d\n", date[i] );
    i++;
    result = strtok( NULL, "/" );
}

if(date[1]!=12)
{
    date[1]++;
}
else
{
    date[1]=1;
    date[2]++;
}

char a[20];
char b[20];
char c[20];
char d[20];
sprintf(a, "%d", date[0]);
sprintf(b, "%d", date[1]);
sprintf(c, "%d", date[2]);

strcpy (d,a);
strcat (d,"/");
strcat (d,b);
strcat (d,"/");
strcat (d,c);

printf(d);
return d;
}

ここでは、この関数は正常に機能していますが、別の関数のように側で呼び出すと

while(fread(&eme,recsize_eme,1,fq)==1)
            {

                char *hell;
                hell = update_date(eme.pre_pay_date);
                printf("%s",hell);
            }

今、それはいくつかの任意のテキストを出力します..:/誰か助けてください

4

2 に答える 2

2

最初のコードでは

char d[20];
... ... 
return d;

「d[20]」はスタック上にあります。スタック上のデータへのポインタを返しています。update_date()が返すとすぐに、そのローカル変数はすべて無効になります。

2番目に、戻る前にd []の値を出力するので、問題はありません。

strok()はおそらく避けるのが最善です。渡す文字列を変更し、静的な状態を維持します。どちらも重大な落とし穴であり、多くの場合、微妙なバグを引き起こします。

ここにいくつかの代替実装があります。(もちろん、本番コードでは、最初に日付/時刻を解析するコードを記述しないようにする必要があります。これを行うためのOSおよびライブラリ関数があります。多くの微妙な点があります)。

// Scanf can do parsing for you
int date[3];
int n;
n = sscanf(dat, "%d/%d/%d", &date[0], &date[1], &date[2]);
if (n == 3) 
{
    // OK, we got 3 integers...
}


// atoi() stops on non-digits, use it instead of strtok
char *result = dat;
int date[3];
int i = 0;
while (i < 3 && result)
{
    date[i++] = atoi(result);
    result = strchr(result, '/');
    if (result)
    {
        ++result; // Skip the '/'
    }
}
于 2012-11-04T04:13:27.613 に答える
1

これはあなたの質問とは関係ありませんが、代わりに次のことに注意してください。

char a[20];
char b[20];
char c[20];
char d[20];
sprintf(a, "%d", date[0]);
sprintf(b, "%d", date[1]);
sprintf(c, "%d", date[2]);

strcpy (d,a);
strcat (d,"/");
strcat (d,b);
strcat (d,"/");
strcat (d,c);

これを簡単に行うことができます:

char d[20];
sprintf(d, "%d/%d/%d", date[0], date[1], date[2]);

安全になりたい場合は、次を使用しますsnprintf

char d[20];
snprintf(d, sizeof d, "%d/%d/%d", date[0], date[1], date[2]);

そうすることで、一時バッファを取り除き、 を使用する非効率性を排除しstrcatます。strcatを使用するときはいつでも、関数は文字列の先頭から開始し、末尾を見つけてからソース文字列をコピーする必要があることに注意してください。

于 2012-11-04T05:27:10.230 に答える