• ベストアンサー

C言語で、入力された、文字列を逆に並べるプログラム。

タイトルのとおりのプログラムをつくりたいんです。 例えば、abcと入力したら、cbaと返してくれるものです。 条件として、ポインタを使えと言われています。 自分で書いたソースは、 0: #include<stdio.h> 1: char re(char *s); 2: main() 3: { 4: char s[10]; 5: gets(s); 6: re(s); 7: printf("%s\n",s); 8: } 9: 10: char re(char *s){ 11: char c[10]; 12: 13: c[9]=s[0]; 14: c[8]=s[1]; 15: c[7]=s[2]; 16: c[6]=s[3]; 17: c[5]=s[4]; 18: c[4]=s[5]; 19: c[3]=s[6]; 20: c[2]=s[7]; 21: c[1]=s[8]; 22: c[0]=s[9]; 23: 24: return c[10]; } C言語を勉強し始めたばかりで、なかなか思うようにかけないでいます。 文字列を入力するのは、4行目~7行目で大丈夫だと思うんですよ。 文字列を逆に並べる、関数 re(char *s)を作れずにいます。 配列s[10]に入っている、文字を最後から取り出して、c[10]にいれていけば、ひっくり返ると思っているんですが、作れません。 13行~21行目の作業も、whileかforでループさせるべきなのもわかってるんですが、条件をどうしたらいいか分からずに作れずにいます。今のソースのまま実行しても、入力したまま出力してしまいます。 さらに、ポインタも今日はじめて勉強して、うっすらと知ってるくらいなので、アドレスとかが、イメージできないでいます。 ながくなってすいません。アドバイスいただきたいです。よろしくおねがいします。

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

  • ベストアンサー
  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.3

char re(char *s) → void re(char *s)に変更して。 void re(char *s) {  char *p;  p=s+strlen(s)-1;  while(s<p){   c=*s;   *s=*p;   *p=c;   s++;   p--;  } } これでどうでしょうか? pの初期値は末尾の文字の位置です。 先頭と末尾の文字を順番に入れ替えながら内側に進めます。

sin11
質問者

お礼

できました!!なんとか、ピンときました。 一つだけあやふやなのが、 >p=s+strlen(s)-1; この部分なんですが、1をひているのは、sに"abcde"と入っているとしたら、 s="abcde*"と文字の最後を表す何かが入っていて、strlen(s)=6になるから、1引いてるってことでいいんですよね? ありがとうございました。

その他の回答 (4)

回答No.5

>p=s+strlen(s)-1; この部分なんですが、1をひているのは、sに"abcde"と入っているとしたら、 s="abcde*"と文字の最後を表す何かが入っていて、strlen(s)=6になるから、1引いてるってことでいいんですよね? 違います。文字列の長さが1だとしましょう。 そのとき p と s が一致しなければなりません。 --- >for(p = &buf[strlen(buf)-1];p != buf;p--) printf("%C",*p); の部分は、どんな働きをしているんでしょうか? たとえば、bufに"abcdefg"が入ってると仮定しておしえてもらえませんか? 贅沢いって申し訳ないんですが、ポインタがしっくりきてないんで、なかなか理解できません。 p が指している文字をプリントしています。 --- >fgets(buf,100,stdin); は配列buf[100]に文字をいれてるんですよね。stdinとは、何なのでしょうか?自分の持ってる参考書に載ってないのでわかりませんでした。 標準入力、ぶっちゃけていえばキーボードからの入力です。

sin11
質問者

お礼

何度も回答していただいてありがとうございます。 完璧ではないですけど、ほぼ理解できました。ポインタがわかるようにがんばってみます。

回答No.4

> void re(char *s){ > int i,j=10; // [1] > for(i=0;i<=j;i++){ > s[j]=s[i]; // [2] > j--; > } >} > としてみました。何がいけないんでしょうか? [1] j は'本当に'10ですか? 3文字入力されても10でいいのですか? [2] これで'本当に'入れ替わりますか?

sin11
質問者

お礼

再び回答していただいてありがとうございます。 No.3のかたの回答みてので、 >[1] j は'本当に'10ですか? >3文字入力されても10でいいのですか? >[2] これで'本当に'入れ替わりますか? の意味が理解できました。 >[1] j は'本当に'10ですか? strlenを使って数えるということだったんですね。 >[2] これで'本当に'入れ替わりますか? これは、ほんとに基本でしたね(-_-;) 1回違うのにいれといて、入れ替えて、また戻してとしなければいけなかったんですね。 なんとかプログラム完成しました。自分だけじゃ、絶対おもいつかなかったです。これから、精進したいです。 あと、後学のために、No.2のかたの補足をおしえてもらいたいです。 本当にありがとうございました。

  • hogeta
  • ベストアンサー率14% (4/28)
回答No.2

#include <stdio.h> #include <string.h> void reverse(char *buf) { char *p; for(p = &buf[strlen(buf)-1];p != buf;p--) printf("%c",*p); printf("\n"); } int main() { char buf[100]; fgets(buf,100,stdin); reverse(buf); } こんなんでよろしい? わからなかったら,またしつもんしてください。

sin11
質問者

補足

自分なりに、ソースを読んで見たんですがわからないところがあるので、しつもんさせてください。 >for(p = &buf[strlen(buf)-1];p != buf;p--) printf("%C",*p); の部分は、どんな働きをしているんでしょうか? たとえば、bufに"abcdefg"が入ってると仮定しておしえてもらえませんか? 贅沢いって申し訳ないんですが、ポインタがしっくりきてないんで、なかなか理解できません。 >fgets(buf,100,stdin); は配列buf[100]に文字をいれてるんですよね。stdinとは、何なのでしょうか?自分の持ってる参考書に載ってないのでわかりませんでした。 こちらもよろしくお願いします。

回答No.1

i = 0; /* 最初の文字の位置 */ j = N; /* 最後の文字の位置、Nはあなたが求める */ i < j である間、[1]-[3]を繰り返す [1] s[i] と s[j] を入れ替える [2] i = i + 1; /* ひとつ進む */ [3] j = j - 1; /* ひとつ戻る */

sin11
質問者

お礼

さっそくの回答ありがとうございます。

sin11
質問者

補足

アドバイスいただいたとおりに直してみたんですが、入力されたまま出力してしまいます。ソースは #include<stdio.h> void re(char *s); main() { char s[10]; gets(s); re(s); printf("%s\n",s); } void re(char *s){ int i,j=10; for(i=0;i<=j;i++){ s[j]=s[i]; j--; } } としてみました。何がいけないんでしょうか? もう1度アドバイスいただけるとうれしいです。よろしくお願いします。

関連するQ&A