名前を逆に表示して結合するプログラムの間違い

このQ&Aのポイント
  • 入力した名前を逆順に表示し、結合するプログラムのソースコードにはいくつかの誤りがあります。
  • ソースコードの誤りを修正することで、正しい実行結果を得ることができます。
  • 修正すべき箇所は、文字列の長さを取得する処理や文字列の逆順を取得する処理などです。
回答を見る
  • ベストアンサー

どこが間違っているのでしょうか

どこが間違っているのでしょうか First nameとSecond nameを入力したら、 それぞれの文字の順番を逆に表示し、 最後にそれらを結合するプログラムを作りたいのですが、 以下のように作ったら、実行結果が Inverted first word: Inverted second word: Result: しか表示されません(最初の名前を記入させるところまでは大丈夫ですが)。 ソースコードのどこが間違っているかを教えてください。 ソースコードは次のとおりです。 #include <stdio.h> #include <string.h> int main(void) { int i,j; char first[21]; char second[21]; int f; int s; char FIRST[21]; char SECOND[21]; char result[41]; printf("Input a first word within 20 letters:"); scanf("%s",first); printf("Input a second word within 20 letters:"); scanf("%s",second); f=strlen(first); i=0; while (first[f]!='\0'){ FIRST[i]=first[19-i]; i++; } FIRST[20]='\0'; s=strlen(second); j=0; while (second[s]!='\0'){ SECOND[j]=second[19-j]; j++; } SECOND[20]='\0'; strcpy(result,SECOND); strcat(result,FIRST); printf("Inverted first word:%s\n",FIRST); printf("Inverted second word:%s\n",SECOND); printf("Result:%s\n",result); return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

> f=strlen(first); > while (first[f]!='\0'){ > FIRST[i]=first[19-i]; strlenで取得したfをそのままwhileの継続条件に投げているので即座に終了します。 ここの継続条件はfirst[i]!='\0'でしょう。 secondについても同様。 またFIRST及びSECONDは初期化されていないので何が入っていても不思議はありません。 そのため、first, secondが20文字に満たない場合は先頭部分に入力した文字列以外の何かが入ります。 ちゃんと先頭から文字列分だけ入るようにしましょう。 #こっちはコード例は挙げません

gezigezi
質問者

お礼

回答ありがとうございます。

その他の回答 (2)

回答No.3

回答を記述中に#1の方とダブってしまいましたが 何も表示されない理由は以下の箇所にあります。 f=strlen(first); i=0; while (first[f]!='\0'){ FIRST[i]=first[19-i]; i++; } FIRST[20]='\0'; (1) 標準関数strlenは文字列の'\0'の位置を検索し、文字列の先頭からの相対アドレスを返します。 (2) そのため、while (first[f]!='\0') は常にFALSE(偽)となります。 (3) 従ってwhileのブロックは実行されません。 (4) whileのブロック、FIRST[i]=first[19-i];も間違っています。 for (f = strlen(first), i = 0; f > 0; FIRST[i++]=first[--f]); FIRST[i] = '\0'; と書けばよいのです。 あと、回答ではないのですが全体的に無駄な処理やメモリの使用が多すぎます。また標準入力がコンソール以外の場合にも対処していません。 先頭の入力の箇所は、以下の例のようにすればすっきりするでしょう。動作の解説はしませんから、自分で考えてみてください。他の有意義な指摘は#2のAsanoNagiさんのおっしゃるとおりです。 const char Input_messege[] ="Input your %s name (max 20 letters)"; const char Input_name_char[2] = {"last", "first"}; char *Input_letters[2]; Input_letters[0] = SECOND; Input_letter[1] = FIRST; for (i = 1 ; i >= 0; i--) {  char *name_ptr, name_letter[21];  *(name_ptr = Input_letter[i]) = '\0';  //名前の入力。文字列の入力に成功するまで繰り返す。 {    int cont;   do {    printf(Input_messege, Input_name_char[i])    if ((cont = scanf("%20s", name_letter)) == EOF) goto InputError;   } while (cont != 1);  }  //文字のコピー  {   int name_len;   name_len = strlen(name_letter);   do {    *name_ptr++ = name_letter[--name_len];   } while (name_len > 0);  }  *name_ptr = '\0';  //不要な文字の読み捨て  (   int c;   while ((c = getchar()) != '\n')    if (c == EOF) break;  } } InputError:

gezigezi
質問者

お礼

回答ありがとうございます。

回答No.2

最大の原因は、誰かが書いたか以前使ったかという、似たような問題の答えをそのまま貼り付けていることでしょう。 FIRST[i]=first[19-i]; というコードと、f=strlen(first); というコードは明らかに別の問題から引っ張ってきたコードです。 また、FIRST[20]='\0'; というコードがなぜ必要なのかわかりますか? (なぜ、20なのかとか) 既に正しい回答は付いていますが、あとは、 first = 'N' 'a' 'm' 'e' '\0' とか、紙に書いて FIRST = 'e' 'm' 'a' 'N' '\0' に入れ替えるには、「何番目を何番目に持って行ったらいいか」と、「文字の長さが変わったときに、それはどういう影響を受けるか」を考えるのが良いと思います。 あと、本題とは直接関係ありませんが、first と FIRST という安易な名前の付け方は、好ましくありません。 どちらが、最終結果なのか、一目でわかりますか? 大文字が最終結果というのもありですが、result は小文字ですし。 char first_input[21]; char first_result[21]; とか、意味を反映させた変数名が好ましいです。 もう少し進んで構造体を使えるようになったら、 struct namePairType { char first[21]; char last[21]; }; struct namePairType input, result; という書き方も良いと思います。 最後におまけ。 文字列の連結は、(特に指定がない限り)sprintf を使うのが簡単です。 strcpy(result,SECOND); strcat(result,FIRST); は、 sprintf(result, "%s %s", SECOND, FIRST); だけで済みます(間にスペースも入れました) そもそも、最終結果を単に表示するだけでよいのなら、 printf("Result:%s %s\n", SECOND, FIRST); も良いかと思います。

gezigezi
質問者

お礼

回答ありがとうございます。

関連するQ&A

  • プログラミング(配列と関数の引数)

    a : ABCDE a : ABCDEFGH Len : 8 a : FGHIJ a : FGH a : FGH, c : FGH 上記のように表示されるプログラムを作りたいのですが、なかなかできません。下記のようなプログラムを作ったのですがどこが間違っているのかよくわかりません。分かる方、指摘をお願いします。 #include <stdio.h> void my_strcpy(char s[], char t[]); int my_strlen(char s[]); void my_strcat(char s[], char t[]); int main(){ char a[10]; char b[10] = "ABCDE"; char c[] = "FGH"; int len; my_strcpy(a, b); printf("a : %s\n", a); my_strcat(a, c); printf("a : %s\n", a); len = my_strlen(a); printf("Len : %d\n", len); my_strcpy(a, "FGHIJ"); printf("a : %s\n", a); a[3] = '\0'; printf("a : %s\n", a); if(strcmp(a, c) == 0){ printf("a : %s, c : %s\n", a, c); } int i, s, t; my_strcpy(a, b + 2); printf("a : %s\n", a); void my_strcpy(char s[], char t[]){ for (i = 0; t[i] != '\0'; i++){ s[i] = t[i]; } s[i] = '\0'; } int my_strlen(char s[]){ int i; for (i = 0; s[i] != '\0'; i++); return i; } void my_strcat(char s[], char t[]){ int i, j; for (i = 0; s[i] != '\0'; i++); for (j = 0; t[j] != '\0'; i++, j++){ s[i] = t[j]; } s[i] = '\0'; } }

  • ポインタ勉強中です。しかも実行するとおかしいです。

    <本に載ってたソース> #include<stdio.h> #include<string.h> int main() { char msg[20]; char *str=NULL; int i; int cnt; str=&msg[0]; printf("文字を入力してください"); scanf("%s",&str); cnt=strlen(msg); str=msg+cnt; for(i=cnt;i>=0;i--){ printf("%c",*(str--)); } printf("\n"); return 0; } char *str=NULL;は、ポインタstrを空にするということでしょうか? いつもながらstrlenとsizeofが混じります。 sizeofがバイトの大きさで、strlenが、文字数でしたっけ?

  • abcdとキーボードで打ったらdcbaと表示されるプログラム

    C言語に関しては初心者です。 メイン関数は変更せずに行います。 /* reverse.c: reverse a given string */ #include <stdio.h> #include <string.h> void reverse(char *); /* プロトタイプ宣言 */ int main(void) { char str[100]; scanf("%s", str); reverse(str); printf("%s\n", str); return (0); } void reverse(char *s) { char n; int i; char str; n = strlen(str) - 1; for(i=0,i++,i<=100) { s[i] = *s[n-i]; printf("%s\"s[i]); } }

  • 数式を読みこんで答えをかえすプログラム

    C言語で、「キーボードから入力された数式(加法、減法限定)の答えをかえすプログラム」をつくりたいのですが。。。 ※4+35+287-43など #include<stdio.h> #include<string.h> #define NUM 40 int main(void){ char str[NUM]; int i, result, x; printf("Please input an expression:\n"); scanf("%s", str); x = strlen(str); result = 0; for(i=0; i<=x; i++){ if((str[i] == '+') || (str[i] == '-')){ // printf(","); } printf("%c", str[i]); } } printfで+と-を「,」で区切って、それをヒントにそれぞれ配列の中に入れるのかな、というところまでは出来たのですが。。。 解り易い解説をつけて下さるとありがたいです。よろしくお願いします。

  • プログラムのことで

    次のプログラムの変数の説明と処理の流れを素人でも理解できるように説明してもらえないでしょうか。 #include <stdio.h> #define MAX 128 int str_comp(char nx[], char ny[]){ int i, j, k=0; for(i=0; i<=MAX; i++){ if( nx[i]=='\0' ){ return 0; } else if( nx[i]==ny[0] ){ for( j=0; nx[i]==ny[j]; j++ ){ i++; } if( ny[j]=='\0' ){ return 1; } } } } int main(void) { char namex[MAX}; char namey[MAX}; int n; int i; printf("文字列x(64文字まで)? "); scanf("%s",namex); printf("文字列y(64文字まで)? "); scanf("%s",namey); n=str_comp(namex,namey); if(n==1){ printf("'%s'に'%s'は含まれます\n",namex,namey); } else if(n==0){ printf("'%s'に'%s'は含まれません\n",namex,namey); } return 0; } 実効結果 文字列x(64文字まで)? Katatsumuri  文字列y(64文字まで)? ta 'Katatsumuri'に'ta'は含まれます. エラーは出ないはずです。 よろしくお願いします。

  • C言語の文字列の取り扱いが分かりません

    こんにちは。 C言語で分からないことがあり、質問させていただきました。 学校で、文字列の取り扱いを習いました。 そこで質問なんですが、以下のソースコードをstrcpy , strcat , strcmp , strlen を使わずに書くことってできないですか? 先生に質問したところ、ポインタとかいうのを使うのだそうですが、それを使わずに書くことってできるんですか?もしよろしければお願いします。 以下のプログラムですが、ユーザーから2つの文字列を受けて、そこから4つの文字列関数を使ってみましょう、というやつです。実行結果も貼っておきますね。 #include <string.h> #include <stdio.h> int main(void) { char str1[80], str2[80]; int i; printf("INPUT 1st word-line. : "); gets(str1); printf("INPUT 2nd word-line. : "); gets(str2); /*文字列(word-line)の長さを確認します。*/ printf("%s is %d moji long.\n", str1, strlen(str1)); printf("%s is %d moji long.\n", str2, strlen(str2)); /*文字列を比較します。*/ i = strcmp(str1, str2); if (!i) printf("two word-lines are same length.\n"); else if (i < 0) printf("%s is smaller than %s.\n", str1, str2); else printf("%s is bigger than %s.\n", str1, str2); /*十分なスペースがあるのなら、str2をstr1の最後に結合させます。*/ if((strlen(str1) + strlen(str2)) < 80 ){ strcat(str1, str2); printf("%s\n", str1); } /*str2をstr1にコピーする*/ strcpy(str1, str2); printf("%s %s\n", str1, str2);

  • ポインタと配列

    次のソースで、結果表示でポインタを使いたいのですが、うまくいきません。1件しか表示されないのです。 ポインタの扱いがおかしいのだと思いますが、どうしたらよいでしょうか? #include <stdio.h> #include <string.h> int search(char key[256],FILE *fp,char *result[256][256]); main(void) { FILE *fp; int rep,n,i; char x[256],key[256],*result[256][256]; printf("検索キーワードを入力してください。\n" "キーワード>"); gets(key); if((fp=fopen("personal.txt","r"))==NULL) { printf("ファイルをオープンできません\n"); exit(1); } printf("=====検索結果=====\n"); n=search(key,fp,result); for(i=0;i<n;i++) { printf("%s\n",result[i]); } printf("検索結果:%d件です。\n",n); fclose(fp); } int search(char key[256],FILE *fp,char *result[256][256]) { int n=0; char *p,word[256],*name; while((p=fgets(word,256,fp))!=NULL) { if(strstr(word,key)!=NULL) { name=strtok(p," "); strcpy(result[n],name); n++; } } return n; } 実行すると、下の警告がでます。 illegal pointer combination(param)

  • Cのプログラムがどうしても動きません

    Cを勉強中なのですが、以下のプログラムがうまくいきません。 (studentは構造体で定義した型です。) iが0でない5の倍数の時にreallocでメモリを増やそうと思ったのですが、 「21行目」(reallocの行)で記述エラーを発見しました。 「lvalue」を付け忘れています。 と表示されます。 どこが間違っているのでしょうか?教えてくださいm(_ _)m #include<stdio.h> typedef struct{ char name[20]; int year; char sex[6]; }student; void read_data(int,student*); void write_data(int,student*); int main(void){ student data[5]; int i=0,j=0; do{ read_data(i,data); i++; if(i%5==0 && i!=0){ data=realloc(data,(sizeof(student))*(i+5)); } }while(data[i-1].year!=-1); } for(j=0;j<i-1;j++){ write_data(j,data); } free(heap); return 0; } void read_data(int i,student *data){ printf("%d人目\n",i); printf("名前?\n",i); scanf("%s",(data[i].name)); printf("年齢?\n",i); scanf("%d",&(data[i].year)); printf("性別?\n",i); scanf("%s",(data[i].sex)); return; } void write_data(int j,student *data){ printf("%d人目\t",j+1); printf("名前:%s\n",data[j].name); printf("年:%d\n",data[j].year); printf("性:%s\n",data[j].sex); return; }

  • おみくじプログラムですがじっこうできません。

    #include<stdio.h> int main() { int i; char data[5][10]={"大吉","小吉","吉","凶","大凶"}; printf("1~5の間の整数を入力:"); scanf("%d",&i); while(i<1&&i>5){ printf("入力値が不適切です。\n"); printf("1~5でお願いします。\n"); scanf("%d",&i); } printf("%s\n",data[5][i-1]); return 0; } 自分で考えてみたのですが、どうしたらいいかわかりません。

  • 文字を逆転させて表示させるプログラミングなのですが・・・。

    #include<stdio.h> int main() { char moji[80]; char hantai[80]; int i; int j; int n; printf("半角文字列を入力:"); scanf("%s",moji); for(n=0;moji[n]!='\0';n++); for(i=n-1,j=0,i>=0;i++;j--){ hantai[j]=moji[i]; } hantai[j]='\0'; printf("反対から:%s\n",hantai); return 0; } 反対からが表示されません。 考えたのですがわかりません。