2

ユーザー入力を受け取って画面に出力するプログラムを作成します。

サンプル入力はabc 12 34です。

サンプル出力はですabc 12 34が、1234は整数として入力する必要があります。

サンプル入力では、私のプログラムは常にとして出力されabc 122 344ます。私は長い間取り組んできましたが、それでも理解できません。コードを確認するのを手伝ってもらえますか?ありがとう。

私のgccバージョンは4.1.2です。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char c;
    char *str = NULL;
    str = (char *)malloc(20*sizeof(char)); /*just sample code, not robust*/
    memset(str,'\0',20*sizeof(char)); 

    if(str == NULL)
    {
        fprintf(stderr,"Error: failed to allocate memory.\n"); fflush(stderr);
        return 0;
    }

    /*store user input*/
    int index = 0;
    while((c=getchar()) != '\n')
    {
        *(str+index) = c;
        index++;
    }

    int digit = 0;
    for(index = 0; *(str+index)>0; index++)
    {
        if((*(str+index)>='a') &&( *(str+index)<='z'))
        {
            fprintf(stdout,"%c",*(str+index)); fflush(stdout);
        }

        else if((*(str+index)>='0') &&( *(str+index)<='9'))
        {
            /*handling the case that a number with more than one digit*/
                    if(*(str+index+1)>='0' && *(str+index+1)<='9')
            {
                digit=10*(digit+atoi(str+index));
            }
            else
            {
                digit += atoi(str+index);   
                fprintf(stdout,"%d",digit); fflush(stdout);
                digit = 0;
            }           
        }

        else
        {   
            fprintf(stdout,"%c",*(str+index)); fflush(stdout);
        }
    }
    printf("\n");
    free(str);
    return 0;
}
4

3 に答える 3

3

使用しないでください:文字列を単一ではなく、atoiに変換します。intchar

何が起こるかを次に示します。たとえば、2桁の数値が34表示されると、最初の反復で両方の桁をにpsssesしatoi、を取得34し、それを10で乗算して、を作成し340ます。次の反復は、の累積結果のために、4を取得し、それをに喜んで追加します。340344

char数字を表すシングルをに変換する場合はint、減算を使用します。

digit = *str - '0';

さらに、複数桁の数字を処理するためのコードは、まあ、非正統的であり、理解するのが難しくなっています。次の文字が数字であることがわかったときに現在の値に10を掛ける代わりに、数字が見えたときにの値に10を掛ける必要があります。これは、前の値がである最初の桁でも機能0します。これは、ゼロの10倍がまだゼロであるためです。

if(((*str+index+1)>='0') && (*str+index+1)<='9')とそのブランチを削除し、そのブランチを次のようthenに変更する必要があります。else

digit = 10*digit + *(str+index) - '0';
if (((*str+index+1)<'0') || (*str+index+1)>'9') {
    fprintf(stdout,"%d",digit); fflush(stdout);
    digit = 0;
}
于 2012-10-26T15:40:37.320 に答える
2

あなたのための2つの簡単な変更。

まず、すでに述べたatoi()ように、文字列を取得してintを返します。1文字(0-9)を実行しているだけなので、文字「0」からそれを引くだけです。

digit=10*(digit+(*(str+index)-'0')); //instead of atoi(str+index)

なぜ「0」を引くのですか?それは数字のASCII値に帰着します。

文字「0」の値は3010であり、「1」の値は31 10であるため、次のようになります。

int a = '0' - '0'; // that's  30-30, or 0 as an int
int b = '1' - '0'; // that's  31-30, or 1 as an int

現在使用している両方の場所でこの調整を行う場合atoi()

            ...
            digit=10*(digit+atoi(str+index));
        }
        else
        {
            digit += atoi(str+index); 
            ...

変更点:

            ...
            digit=10*(digit+(*(str+index)-'0'));
        }
        else
        {
            digit += *(str+index)-'0';   
            ...

これで、コードは希望どおりに機能します。もう1つのポイントは、if// az if elseelse0-9、その他をチェックすることです。

あなたの最初のコードifとあなたelseのコードは同一であるため、そこで実行できる単純化があることを意味します。最初に全体を削除し、を1つifに変更するelse ifだけで、if実行していることとまったく同じことができます。

于 2012-10-26T16:21:06.083 に答える
1

そのためだけに使っsscanfてみませんか?このような:

sscanf(str, "%s %d %d", str1, &num1, &num2);

何らかの理由でを使用できない場合sscanfは、少なくとも文字と数字をそれぞれ使用isalpha()して確認する必要があります。isdigit()

したがって、これを使用する代わりに:

if((*(str+index)>='a') &&( *(str+index)<='z')) {
    .....
}

これを使って:

if (isalpha(*str+index)) {
    .....
}
于 2012-10-26T15:37:53.360 に答える