- ベストアンサー
単語逆順コピープログラム
入力された文字列を逆から表示するというプログラムを作成しているのですがなかなかうまくいきません。僕の作成したプログラムを載せておくので間違いの指摘をお願いします。 出力例(一部) 入力文字列:[ pen. a is This ] 出力文字列:[This is a pen.] ---------コードここから--------- #include <stdio.h> #include <string.h> /* マクロの定義 */ #define BUF 1024 int main(void){ char in[BUF]; /* 入力された文字列を保存する */ char out[BUF]; /* input の内容を単語逆順にして保存する */ int wordcount = 0; /* 単語数 */ char *in_ptr, *out_ptr; /* それぞれの文字列の文字を指すポインタ */ int wsp[128], wep[128]; /* 単語の先頭の添え字と単語末の添え字を保存する配列 */ int i, j; printf("入力された英単語列を単語逆順にします\n"); printf("入力:"); fgets(in, sizeof(in), stdin); sscanf(in, "%c", &in); /* \nを\0に書き換える */ in_ptr = in + strlen(in) - 1; *in_ptr = '\0'; /* 単語数カウント */ printf("文字数のカウント開始\n"); in_ptr = in; if(*in_ptr != ' '){ wordcount++; } for(in_ptr = in; *in_ptr != '\0'; in_ptr++){ if(*in_ptr != ' ' && *(in_ptr - 1) == ' '){ wordcount++; } } printf("文字数のカウント終了: %d単語\n", wordcount); printf("\n単語逆順処理開始\n"); for(i = 0; i < wordcount; i++){ for(in_ptr = in; *in_ptr != '\0'; in_ptr++){ if(*in_ptr != ' ' && *(in_ptr - 1) == ' '){ wsp[i] = *in_ptr; } if((*in_ptr - 1) != ' ' && (*in_ptr == ' ' || *in_ptr == '\0')){ wep[i] = *in_ptr; } } } out_ptr = out; for(i = wordcount - 1; i <= 0; i--){ for(*in_ptr = wsp[i]; *in_ptr <= wep[i]; in_ptr++){ *out_ptr = *in_ptr; out_ptr++; } } printf("単語逆順処理終了\n"); printf("\n入力文字列:[%s]\n", in); printf("出力文字列:[%s]", out); return 0; } ---------コードここまで---------
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>僕の作成したプログラムを載せておくので間違いの指摘をお願いします。 「警告」他をつぶしたものを載せておくので、参考にして下さい。 (入力した文字列の末尾が空白の場合・・?) ☆質問者様のソースの不具合は主に、int wsp[128], wep[128]; の使い方と、*(in_ptr - 1) の後方参照です。 #include <stdio.h> #include <string.h> /* マクロの定義 */ #define BUF 1024 int main(void){ char in[BUF]; /* 入力された文字列を保存する */ char out[BUF]; /* input の内容を単語逆順にして保存する */ int wordcount = 0; /* 単語数 */ char *in_ptr, *out_ptr; /* それぞれの文字列の文字を指すポインタ */ char wsp[128][16]; // 単語を保存する配列 int i, j=0; printf("入力された英単語列を単語逆順にします\n"); printf("入力:"); fgets(in, sizeof(in), stdin); /* \nを\0に書き換える */ in_ptr = in + strlen(in) - 1; *in_ptr = '\0'; /* 単語数カウント */ in_ptr = in; while( ' ' == *in_ptr ) in_ptr++; // 頭のスペース削除 for( ; *in_ptr; in_ptr++ ){ if( ' ' == *in_ptr ){ // デリミタ while( ' ' == *in_ptr ) in_ptr++; // 連続スペース削除 wsp[wordcount++][j] = '\0'; j=0; } wsp[wordcount][j++] = *in_ptr; wsp[wordcount][j] = '\0'; } wordcount++; printf("文字数のカウント終了: %d単語\n", wordcount); printf("\n単語逆順処理開始\n"); out_ptr = out; for(i = wordcount - 1; i >= 0; i--){ for(j = 0; wsp[i][j]; j++){ *out_ptr = wsp[i][j]; out_ptr++; } if( i ){ *out_ptr = ' '; out_ptr++; } *out_ptr = '\0'; } printf("単語逆順処理終了\n"); printf("\n入力文字列:[%s]\n", in); printf("出力文字列:[%s]", out); return 0; } +++++++++++++++++++++++++++++++++++++++++++++++++++++ #include <stdio.h> #include <string.h> #define BUF 1024 void main( void ) { char in[ BUF ] = "pen. a is This\n"; char out[ BUF / 32 ][ 32 ], *p, *cTokn; int i, iWordCount = 0; printf( "%s\n", in ); p = in; while( NULL != ( cTokn = strtok( p, " \n" ) ) ){ // 切り分け strcpy( out[ iWordCount++ ], cTokn ); // 格納 p = 0x00; } for( i = ( iWordCount - 1 ); i >= 0; i-- ){ printf( "%s ", out[ i ] ); } printf( "\n" ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
その他の回答 (1)
- lailai2580
- ベストアンサー率64% (16/25)
まず、 sscanf(in, "%c", &in); これが何をしたいのか分かりません。 for(in_ptr = in; *in_ptr != '\0'; in_ptr++){ if(*in_ptr != ' ' && *(in_ptr - 1) == ' '){ wordcount++; } } ここで、最初のループの時にin_ptr-1が何を指すのか分からなくなっているような気がします。 for(i = 0; i < wordcount; i++){ for(in_ptr = in; *in_ptr != '\0'; in_ptr++){ if(*in_ptr != ' ' && *(in_ptr - 1) == ' '){ wsp[i] = *in_ptr; } if((*in_ptr - 1) != ' ' && (*in_ptr == ' ' || *in_ptr == '\0')){ wep[i] = *in_ptr; } } } ここでwsp[i]とwep[i]に入れるべき値は*in_ptrではなく、 配列inの添え字ではありませんか? out_ptr = out; for(i = wordcount - 1; i <= 0; i--){ for(*in_ptr = wsp[i]; *in_ptr <= wep[i]; in_ptr++){ *out_ptr = *in_ptr; out_ptr++; } } forループの初期化で*in_ptr = wsp[i]をすると もと配列を破壊しているかと思われます。 というより、j=wsp[i],in_ptr=&in[wsp[i]];j<=wep[i];j++,in_ptr++ではないかと思います。 蛇足ではありますが、strtokなどの関数を調べると幸せになれるかもしれません。