質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

7062閲覧

C言語 ポインタを用いた文字列の反転

keeen

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/06/17 11:58

C言語のポインタを使って文字列(Winter)を逆から表示させたいです。
以下のプログラムで実行すると、エラーは出ませんが出力結果が
retnir UX}?1??k?? UX}?
のような、変な物が表示されます。retniまでは正しく表示されているのになぜWだけがおかしくなってしまうのか分かりません。

C言語

1int main(void){ 2 char s[7], *p_s; 3 strcpy(s, "Winter"); 4 p_s = s; 5 while(*p_s != '\0'){ 6 //最後の文字になるまで繰り返す(文字列の最後を知るため) 7 *s = *p_s; 8 p_s++; 9 } 10 11 while(*p_s != '0'){ 12 //最後の文字から順に表示していく 13 printf("%c",*p_s); 14 p_s--; 15 } 16 17 printf("\n"); 18 return 0; 19} 20

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

このコードには3つ問題があって、ひとつは、文字列末尾を探すループの中で、
*s = *p_s;
としていること。つまり、文字列末尾へ向かって動くp_sにある文字を、文字列先頭を指すsの内容に代入している。文字列先頭の文字はループ一回ごとに書き換えられ、最終的には文字列の末尾(ヌル文字の直前)にある'r'に書き換えられる。対策は、この行を丸ごと削除

そもそも、文字列の末尾の位置を探すなら、p_sの初期値を設定している部分で、
p_s = s + strlen(s) - 1;
と書けば済む話だが、逆順表示の先頭がヌル文字になる問題を修正した後で治すことにする。

さて、次は逆順に表示していく部分だが、2つめの問題は、この時点でp_sが文字列終端のヌル文字を指していることだ。このため、先頭に「何か」が画面に表示される。対策は逆順表示前にp_sの値を1減らす

3つめの問題は、逆順表示のwhileループの継続条件が間違っていることだ。当然のことだが、ヌル文字は文字列の終端にだけ付いており、文字列の先頭には付いていない。対策は、文字列の先頭を示すsとp_sの値を比較する式に変更

C

1#include <stdio.h> 2#include <string.h> 3 4int main(void) { 5 char s[7], *p_s; 6 strcpy(s, "Winter"); 7 p_s = s + strlen(s) - 1; 8 9 while (p_s >= s) { 10 printf("%c", *p_s); 11 p_s--; 12 } 13 14 printf("\n"); 15 return 0; 16}

投稿2020/06/17 12:30

編集2020/06/17 12:33
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keeen

2020/06/17 12:57

細かい説明ありがとうございます。*s = *p_sを消して2つ目のwhileの条件をp_s >= s にすることでretniWと表示することができました。
guest

0

こんな感じでどうでしょうか。

C

1#include <string.h> 2#include <stdio.h> 3 4int main(void){ 5 char *s = "Winter"; 6 for (char *p = s + strlen(s) - 1; p >= s; --p) { 7 printf("%c", *p); 8 } 9 printf("\n"); 10 return 0; 11}

もともとのソースコードが'\0'でなく'0'になっていたことも問題なのですが、文字列の最後には'\0'という番兵がつくのですが文字列の最初には付かないのですよね。だから文字列の開始アドレスと比較してやる必要があります。

[2020.6.17 追記]
ソースコード間違ってました。Daregadaさんのソースコードを参考にして直しました。ありがとうございます。

投稿2020/06/17 12:45

編集2020/06/17 13:47
anndonut

総合スコア667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keeen

2020/06/17 13:03

forを使うことでコードが短くて見やすくなりますね。 異なった考え方を教えてくださってありがとうございます。勉強になりました。
Daregada

2020/06/17 13:36

紛らわしい名前ですまないが、微妙に綴りが違っている(笑)
anndonut

2020/06/17 13:48

Daregadaさん、お名前を間違えてしまい申し訳ありませんでしたっ
guest

0

while(*p_s != '0'){

このwhileの条件文が意味不明です。
その文字列の中には'0'の文字は存在してません

なぜWだけがおかしくなってしまうのか分かりません。

コードをよく見ましょう。
あなたのコードの中で、そこの文字を書き換えてしまっています

投稿2020/06/17 12:03

編集2020/06/17 12:17
y_waiwai

総合スコア87800

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keeen

2020/06/17 12:54

1番目の文字は配列の番号で0なので条件も0にすれば良いと思い込んでいました。確かに' 'は文字を表す物なので0というのはおかしいですよね。おかげで無事解決できました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問