C言語

文字列を逆順に出力させる-C言語

どーもたかぽんです。

先日ちょっとC言語で入力された文字列を逆順に出力させるって言う時にあんまり触ってなかったのでうっ!?ってなってしまいました。

アルゴリズムは頭の中にありましたが細かな部分がなんとも。。。

復習不足を感じたので書いておきます!

 

やりたいことは、文字列へ英字を入力した場合に、逆順でその文字列を出力させることです。

例えば、Hello World!なら、!dlroW olleHになります。

 

考え方はいたって簡単。

文字列配列の一番後ろから順番に一個づつ出力させるだけです。

以下コードです。

 

 

以下、出力です。

lengthの値やそのまま出力の箇所は別に必要はないけど一応つけときました。

次に、scanfを用いてユーザーに入力された文字列を逆順表示しようと思います。

 

 

以下、出力です。

あ、tskaponになってるのはあれです・・・。ただのミスですw

実際に僕が入力したのがTskapondesu!の部分です。

最後はしっかりと逆順になってますね。

まぁ、変更した点はほんの少しです。

文字配列strの定義の箇所を少し変え、scanfを付け加えました。

とりあえずアルファベットに関しては実現できたかな。

ただ、このままだと問題点もたくさんありますね。

例えばscanfを使っているのですが、”Hello World!”と入力した場合正しく表示されません。

うん。

これの原因なんですが、どうやらscanfを使った入力の場合、”Hello World!”という文字列を入れると、半角スペースは無視されてしまい、その箇所には何も無いから、終端文字”\0″として認識されてしまうようです・・・。

そのせいで、scanfでの入力は”Hello\0″だなっ!ってなってるんですね・・・。

だからWorld!の箇所が結果に出力されていません。

困りましたね・・・。

それじゃあ、scanfに少し工夫をしていきます。

InputString_rev.cのscanfを上記のように書き換えます。

できました。ちゃんと空白も含めて逆順表示されています。

scanf(“%[^\n]”);

の”%[^\n]”は、改行文字“\n”以外の文字を文字として読み取ると言う意味です。

今まで半角スペースが文字として認識されず、何もないものだと無視されてしまっていました。

こうすることで、今まで文字として認識されていなかった半角スペースも文字として認識されるようになりました!!!

 

さて、次です!まだまだ終わりませんよ?:(;゙゚’ω゚’):

 

scanfを入力として使う場合、事前に格納領域を決めています。

上記例だと20ですね。(char str[20])の箇所です。

これを超えた入力がきた場合どうなるのでしょうか・・・?

123456789a123456789b12345という文字列を入力しました。lengthからもわかりますが、25文字ですね。

すると、挙動は問題なさそう・・・ですが、最後に ”Abort trap: 6” というエラーメッセージが出てます・・・。

ここでの問題は想定数よりも多く入力を受け付けてしまっているということです。

今回は入力が少なかったので挙動は問題ないようにみえていますが(エラーメッセージはもちろんでていますが)、バッファオーバーフローしてしまうかもしれません。

そこで、ちゃんと想定された文字数のみ入力を受け付けるようにしていきます。

再度、InputString_rev.cのscanfを上記のように書き換えます。

いい感じにできました。

入力は5文字余分に入れていますが、出力ではb(20文字目)で止まっています。

さて、完璧!!!と思うかもしれませんが、もうひと押しです・・・。

こちらのコードを実行してみましょう。

少し多めに変えてきたので全部載せ直しておきます。

文字列配列をもう一つ用意して、1度目のscanfが終了した後にもう一度scanfを実行し、その時の結果を確認しています。

入力は”123456789a123456789bHello!”とし、20文字目以降は”Hello!”としました。

入力が一度しか行えませんでした・・・。

入力をしてEnterを押すと二つ目のscanfの入力ができず、そのままscanfのstr2に1度目のscanで取りきれなかった残りの部分が入ってしまっています・・・。

str2 = Hello!の部分ですね・・・。

2度目の入力が勝手に1度目の入力の残りで行われてしまいました・・・。

2度scanfを使用しなければ直接的な影響はないかもしれませんが、なにかが裏で残っているのは気持ち悪いですし・・・。

それにない方が絶対に良い!

と言うわけで、どうするか・・・。

再度少しscanfをいじってみましょう。

以下出力です。

 

1度目の入力はさっきと同じ”123456789a123456789bHello!”です。

その後Enterを押すと、引き続き2度目の入力を要求されました。

2度目の入力は”Takapon”です。

もしも入力が残ってしまっていたら、str2がHello!Takaponとなりそうですが、ちゃんとTakaponとなっています。

もちろん、2度目の入力もちゃんとでき、1度目の入力の残りも無いようです!

やりました!

“%*[^\n]%*c”これを追加しました。”%*[^\n]”は、さっきとは逆で、”\n”以外は読み飛ばす(処理はするけど、strには入れない!)で、”%*c”は一文字だけ飛ばす!と言う意味です。

残る文字はこうなります。

~~~~(20文字)~~~ “Hello!\n”

最後にEnterを押すので最後には”\n”が入ります。

“%*[^\n]”で”\n”まで読み飛ばしてきましたが、最後に”\n”が残っていますね。

これを無視しなければいけないので、”%*c”で一文字だけ飛ばすという動作を行います。

なので、”%20[^\n]%*[^\n]%*c”がすることは、

 

  1. まず頭から最大20文字、\n以外の文字を読み込む!(\nがあったらその時点で読み込み終了)。
  2. そして次に、\n以外の文字は全部無視する!(長めの入力の場合、20文字目以降、最後のEnterまでの文字列を全て無視)。
  3. 最後に、一文字無視!(この時点で、\nしか残っていないはずなので、\nを無視)

 

という流れになります。

ちなみに、”%*c”はもちろん他の文字にも適応できます。

例として以下のプログラムを実行してみました。

これの出力はこうなります。

頭の一文字消えてますね。

少し脱線しましたが、これでとりあえずは満足かなと思います。(もっといい方法もありそうですが・・・

とりあえず、最後にいらない部分を抜いて整理をした、”入力された英数字による文字列を逆順で出力する”プログラムを載せておきます。

想定入力文字数は各自で都度、設定してください。

 

はい、というわけで、今回は入力された英数字の文字列を逆順に出力しました。

C言語は3〜4年ほど学んだのですが、お恥ずかしながら先日、char str[20];に対してstr = “*****”;と入力させようとしてなんでエラーなのぉ!!!!

ってつまづいてましたw

ブランクがあると基本的なところでもあれ?ってなっちゃうんですね・・・。

たまにはしっかり触らないと・・・。

そして、軽い気持ちで調べ始めましたが、奥が深いですね・・・・。

scanfだけでもいろんな用法が・・・。

学校でもそこまで学んでなかったので、scanfスペースとれんのかぃ!変なの残るんかぃ!!!ってなりながら調べてましたw

最終的には・・・scanf・・・おまえ・・・おもったより・・・すごかったんだな・・・!ってw

これからもこんな感じのちょっと遊び感覚でいろんなことやっていけたら面白そうです!

やってて新しく知ることや、自分で手を加えていくのが楽しかったですw

(できたからといって何にもならないんですけどもw)

ではでは!また!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください