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

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

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

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

Q&A

解決済

3回答

9424閲覧

C言語 入力した文字列を逆にしたいが表示されない

HOTEISON_

総合スコア3

C

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

0グッド

0クリップ

投稿2021/07/02 02:07

編集2021/07/02 05:04

前提・実現したいこと

入力された文字列を逆にしたいのですが最後にprintf関数で表示されません。
例えば abcdならdcbaとなるようにしたいです。

自分が想定しているこのプログラムの動き方

scanfで入力された文字列をchar型関数strに格納。
最初のfor文で文字数をカウントし、int型変数iに格納
int型変数flagにiを2で割った余りを格納する。あまり1の時は文字数っが偶数で0のときは奇数であると判断する。
文字数が奇数のとき、つまりflag=0のとき「j番目の文字をi-j番目の文字と入れ替える」という動作を文字列の半分まで繰り返す。
文字列が偶数のとき、つまりflag=1のとき「j番目の文字をi-j番目のもじと入れ替える」という動作を文字列の半分ー1まで繰り返す。
その結果をprintf関数で出力する。

該当のソースコード

C

1#include<stdio.h> 2#define num 100 3int main() 4{ 5 char tmp,str[num]; 6 int i,j; 7 int flag 8  9printf("文字列を入力してください。:"); 10scanf("%s", str); 11 12for (i = 0; str[i] != '\0' ; i++) { 13 } 14 flag = i % 2; 15  16if (flag == 0) { 17 for (j = 0; j < i / 2; j++) { 18 tmp = str[j]; 19 str[j] = str[i - j]; 20 str[i - j] = tmp; 21          } 22 } 23 24 25 else{ 26 for (j = 0; j < i / 2; j++) { 27 tmp = str[j]; 28 str[j] = str[i - j]; 29 str[i - j] = tmp; 30 break; 31 } 32 } 33 printf("逆の%s", str); 34 return 0; 35} 36 37 38 39

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

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

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

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

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

BeatStar

2021/07/02 02:25

まず、『自分が読み書き出来る人間用の言語で、コードの内容を説明』してみてください。 つまり、『ロジックを説明せよ』です。
fana

2021/07/02 02:42

とりあえず不規則な空行多すぎて見づらい. なんの意図でこんな(わざわざ"見たくない感"を誘発するような)形で提示しているの?
HOTEISON_

2021/07/02 04:41

見づらいコードですみません。いろいろ入れた削除したりしているうちに改行が多くなってしまいました。見やすさを意識して記述します!!
guest

回答3

0

ベストアンサー

考えすぎじゃないかなー... 文字列長の奇遇は気にせんでえぇ思う。

C

1// strを反転する 2void str_reverse(char str[]) { 3 int lo = 0; 4 int hi; 5 for (hi = 0; str[hi] != '\0' ; hi++) {} // hi:文字列長 6 while ( lo < hi ) { 7 --hi; 8 char tmp = str[lo]; 9 str[lo] = str[hi]; 10 str[hi] = tmp; 11 ++lo; 12 } 13} 14 15// おためし 16 17#include<stdio.h> 18#define num 100 19 20int main() { 21 char str[num]; 22 23 printf("文字列を入力してください。:"); 24 scanf("%s", str); 25 str_reverse(str); 26 printf("逆の%s", str); 27 return 0; 28}

[お小言] なんもかんもmainに書き下すのは(ビギナによくある)悪い癖。
やりたいことは"文字列の反転"、ならば"文字列を反転する"関数を書き、
それをmainから呼び出そう。

投稿2021/07/02 02:40

編集2021/07/02 02:58
episteme

総合スコア16612

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

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

HOTEISON_

2021/07/02 05:22

関数ってこうやって書くと今知りました。知識不足ですいません。丁寧な解答ありがとうございました。
guest

0

関数の書き方を知らず、現在の知識だけで書くとすれば、

C

1#include <stdio.h> 2 3#define num 100 4 5int main(void) 6{ 7 char tmp, str[num]; 8 int i, j; 9 10 printf("文字列を入力してください。:"); 11 scanf("%s", str); 12 13 for (i = 0; str[i] != '\0'; i++) ; 14 15 for (j = 0; j < --i; j++) { 16 tmp = str[j]; 17 str[j] = str[i]; 18 str[i] = tmp; 19 } 20 printf("逆の文字列: %s\n", str); 21 return 0; 22}

投稿2021/07/02 05:36

kazuma-s

総合スコア8224

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

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

HOTEISON_

2021/07/02 05:51

たしかにこれなら自分の知識でもできると思います!!ただfor文の中で二つの変数を変化させるという発想がそもそも浮かんでこなかったためやはり皆さんに質問してよかったと思いました。 丁寧な回答ありがとうございました。
guest

0

すでに解決済みになっていますが、気になるので回答します。


Ⅰ. 基礎を理解すべし

基礎が出来てから応用が出来ます。
でも質問を見る限り、『基礎が出来ていない』気がします。

Ⅱ. 用語はちゃんと使うべし

scanfで入力された文字列をchar型関数strに格納

char型『関数』ではなく『配列』では?

関数と配列は別物です。

一応、コードと文章から『配列』であることはわかりますが、
文章だけだと回答者はわからなくなります。

場合によっては『いや、これは変数だろ』とかってわかる事もありますが、
基本的にはわかりにくい。

そうなると質問者の意図と回答者の解釈がすれ違って、頓珍漢な回答になってしまいます。

人間同士ですらこれですから、プログラミングなんてきついです。

プログラミングは「機械とのコミュニケーション」です。

なので用語はちゃんとしましょう。

Ⅲ. 可読性を上げるべし

質問にあるコードではインデント(半角スペースやTabキーでやるアレ)が滅茶苦茶です。

読めなくはないですが、読む気が失せます。

日本語で書けば、

オイラは数学が苦手なんだな。 だけど     お金は    好     きなんだな。 だから 東 京 さ出て、 お 金 を も う けるんだな。

のような感じに近いです。(内容は適当)

読む気、失せますよね?

初心者の内は仕方ないですが、会社での開発はチーム開発のようです。

そうなると複数人で開発することに。

でもそういう読みづらいものを書くとどうなるでしょうか。

仮に自分ひとりで開発するとしても、プログラムは書いて終わり……じゃなく、
保守とかもします。

一か月前の自分が書いたコードなんて忘れているのが当たり前のレベルです。
なので、読みやすいコードを書くように心がけましょう。

Ⅳ. コードを読むときは『この行が何をしているか』を考えながら読むべし

他人が書いたコード、自分が書いたコード関係なく、コードを読むときは、
一行レベルで、何をしているのかを考えながら読む』です。

たとえば、ソースコードとしてのファイルをバックアップ(あるいは単なるコピー)を取っておいて、
一行レベルでコメントにする。とかです。

実際にやってみましょうか。

C

1// 変数iの初期値: 0, 配列の中身が終端文字でない間, +1しながらループ 2for (i = 0; str[i] != '\0' ; i++) { 3 } 4 // フラグ? は、iを2で割った余りとする 5 flag = i % 2; 6  7// フラグ? が 0 (= 偶数) なら 8if (flag == 0) { 9 // 変数j の初期値: 0, j が iの2分の1 未満の間, +1 しながらループ 10 for (j = 0; j < i / 2; j++) { 11 // 変数 tmp に str[j] の値をセット 12 tmp = str[j]; 13 // str[j] は str[i - j] の値とする 14 str[j] = str[i - j]; 15 // str[i-j] は tmp の値とする 16 str[i - j] = tmp; 17 // → つまり、str[j] と str[i - j]を入れ替える 18          } 19 }

といった感じです。

これを日本語でも中国語でも英語でも韓国語でもスペイン語でもなんでもいいので、
自分が読み書きできる言語で書き下す。

C

11. ユーザ入力によって文字列を受け取り、配列 str にセット 22. 配列の長さを forを使って調べる(= 変数 i にセット) 33. (2)で得た長さを2で割ったときの余りを取得( flagにセットし、偶数・奇数を判断するため ) 44. 長さが偶数なら 5 4.1. 変数j の初期値: 0, j が iの2分の1 未満の間, +1 しながらループ 6 4.2. str[j] と str[i - j] を入れ替える 75. それ以外(= 長さが奇数)なら 8 ... 96. 結果(strの値)を出力する

と言う風にやる。(疑似コード?)

これを現実世界で、手作業でやってみる。
数学の問題とかのような感じで。

脳内でもいいです。とにかくやってみる。

そうすると、(5.1) に相当する部分が(4.1)と同じになっています。

でも質問者さんのお考えでは、『文字列の半分ー1まで繰り返す』ですよね?

計算が合いません。

このように、自分が考えたロジックとの差異を見付けるためにもこういう考え方を学ぶべきです。

Ⅴ. 『現実世界でならどうするか』を考えるべし

プログラミングは元々、『現実世界でのシミュレーション』です。

プログラムは魔法でもなんでもなく、人間が現実世界でやっていることを逐一指示されながら処理しているだけの代物である』です。

よって、『現実世界でならどうするか』を考えるのです。

そうすると、

C

1[言い換えQ] 2 3ある人(Aさん)が単語を言うので、それの逆から読んだ単語を書いてくれ。 4 5: 6point -> tniop

この場合、どうしますか?

私なら、

C

11. ホワイトボードを用意する 22. ホワイトボードに Aさんが言った単語をを書く 33. (2)の単語を後ろから読み込んで 4 3.1. 一文字ずつ余白に書いていく 54. 余白に書いた単語が結果的に答えになる

ですかね。

別に『偶数なら~』とかやらなくてもこれぐらいならできますよね。

単純にこれをやればいいだけです。

(上記はホワイトボードですが、ノートでも黒板でもなんでもいいです)

シンプルにできるならシンプルな方が望ましいです。
(アルゴリズム的に無理だったり、計算量を意識して……とかだと別ですが)

シンプル イズ ベスト!

注意!: 別に質問にあるような考え方でもいいです。(ロジックと仕様さえ合っていれば)
質問者さんなりに考えてのロジックなので問題ありません。
別にダメということではなく、あくまで私の考えです。

投稿2021/07/02 10:03

BeatStar

総合スコア4962

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問