文字列を逆順に表示したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
うーる

文字列を逆順に表示したい

#1

投稿記事 by うーる » 1年前

[1] 質問文
 [1.1] 文字列を入力し、それを逆にしたものを表示したい。
 [1.2]

コード:

#include<stdio.h>

main()
{
    char moji1[10];
    char moji2[10];
    int i,n;

    printf("mojiretsu:");
    scanf("%s",moji1);
    printf("n:");
    scanf("%d",n);

    for(i=0;i<n;i++)
    {
       moji1[i]=moji2[n-1-i] ;  
       moji1[n]=moji2[n]
    }

    printf("%s\n",moji2);
}
 [1.3]
mojiretsu:aiueo
n:5
ここまでは出るのですが、そのあとにmoji2が出力されません。

 [1.4] 今何がわからないのか、知りたいのか

そもそも
moji1[0]がmoji2[4]
moji1[1]がmoji2[3]
...
moji1[n-1]がmoji2[0]
に対応できているのか。

なぜなんの文字列も帰ってこないのか

[2] 環境  
 [2.1] OS : Windows
 [2.2] コンパイラ名 : gcc

アバター
usao
記事: 1887
登録日時: 11年前

Re: 文字列を逆順に表示したい

#2

投稿記事 by usao » 1年前

他者に「なぜ」とか言い出す前に,
「何を」やっているのかを説明すべきではあるまいか?

> 文字列を入力し、それを逆にしたものを表示したい

という話において,nなる値を入力させていることは完全に意味不明である. nとは何なのか?
nが何らかの役割を持つのであれば,
「文字列と整数値(n)とを入力し,…(何かしらnの値に基づいた処理がどうのこうの)」
とか何とか正確に述べよ.
(「まともに動いてないコード」だけから「何らかのまともな意味」を察しろ,というのは無理があるとは思わないのか?)

おそらく主たる処理の実装部に該当すると思われる for の箇所で何をやってるのか(やっているつもりなのか)に関する説明も不可欠だ.
「何を」とは,すなわち,あなたが採用しているアルゴリズムを説明せよ,という意味だ.
読み手はあなたと同様の天才とは限らないのだから,いきなり

コード:

 moji1[i]=moji2[n-1-i] ; 


とかいう,せっかく入力した moji1 の一部を,未初期化と見える moji2 の一部に書き換えてしまうことの 意味/意義/正当性/etc を把握することは極めて困難だったりするからだ.

---

まとめると,

・本当はどんな処理をやるという話なのか? というのがわからんし,
・それに対してあなたがどんなアルゴリズムを実装しているつもりなのか? というのもわからん.

なので,まともな説明が必要と見える.

うーる

Re: 文字列を逆順に表示したい

#3

投稿記事 by うーる » 1年前

お返事ありがとうございます。

やりたいこととしてはこれです.

scanf を使って文字列を入力し、char 型配列 moji1 に代入する。
文字数 n を入力する。
配列を制御しつつ、moji1 の文字列をさかさまにして moji2 に代入する。
moji1 を moji2[n-1-i]に代入する。(i=0,...,n-1) 
moji1[n] を moji2[n] に代入する.
printf で moji2 の中身を出力する

これをやるためにfor文のなかで、
配列moji1のmoji1[0]にあたる箇所を
配列moji2のmoji2[n-1]に、

配列moji1のmoji1[1]にあたる箇所を
配列moji2のmoji2[n-2]に、

配列moji1のmoji1[2]にあたる箇所を
配列moji2のmoji2[n-3]に、

というようにmoji2の内容をmoji1と逆順に収容して、
それを後のprintfで表示しようとしています。

nは文字数を入れることによって配列のどの位置まで文字が入っているかを指定しようとしています。

うーる

Re: 文字列を逆順に表示したい

#4

投稿記事 by うーる » 1年前

というようにmoji2の内容をmoji1と逆順に収容して、



moji1をmoji2に逆順に代入して

アバター
usao
記事: 1887
登録日時: 11年前

Re: 文字列を逆順に表示したい

#5

投稿記事 by usao » 1年前

そこまでご自身で説明を書いてみて,コードの間違いに気づきませんか?

要は,あなたの for の処理とは,
「配列 moji2 の内容を更新する処理」なのであり,
その処理においては,配列 moji1 の内容を変更する必要はありませんし,するべきでもありません.

であれば,
代入文の左辺側に moji1 が来ている時点で何もかも間違っているということになるでしょう.

---

いきなり for で書くのが困難なのであれば,ステップを経てみるべきです.
例えば,最初はとりあえず文字列の長さを何らかの値に固定した世界の上で,且つ「for を用いない形で」書いてみるべきです.

コード:

//とりあえず文字数を 5 文字に固定した世界で考える
char moji1[6] = "12345";
char moji2[6];

//まずは愚直に全部書き並べてみようよ.
moji2[0] = moji1[4];
moji2[1] = moji1[3];
moji2[2] = moji1[2];
moji2[3] = moji1[1];
moji2[4] = moji1[0];
moji2[5] = '\0';
こういうのを一度実際にやってみれば,forで書けそうな法則性が明確に見えてくるでしょう.

これを for を用いた形に書き換えたとしても,処理内容(アルゴリズム)自体が変わるわけではないのですから
そこに実装される代入文というのは,常に「左辺が moji2 の要素であり,右辺が moji1 の要素である」という形になるでしょう.

それができたら,「5文字」限定ではなく「n文字」に一般化した形にするだけです.

アバター
usao
記事: 1887
登録日時: 11年前

Re: 文字列を逆順に表示したい

#6

投稿記事 by usao » 1年前

> これを for を用いた形に書き換えたとしても,処理内容(アルゴリズム)自体が変わるわけではないのですから
そこに実装される代入文というのは,常に「左辺が moji2 の要素であり,右辺が moji1 の要素である」という形になるでしょう.

また,forループの中に代入文が複数個並ぶような形にもならないでしょう.
(あえて 素直じゃない/ひねくれた/etc な形の実装をしない限りは)

アバター
usao
記事: 1887
登録日時: 11年前

Re: 文字列を逆順に表示したい

#7

投稿記事 by usao » 1年前

オフトピック
(forを使わずに)たくさん書き並べてみること は低レベルすぎて馬鹿馬鹿しいと思いますか?

「自分は馬鹿ではないのだから,いきなり最終形の実装を作れるのだ!」と思って実際にやってみたら→できなかった
のであれば,
より 低レベルな/馬鹿馬鹿しい と思える形に立ち返って考え直してみることは,間違いを見つけるのに有用な手段となり得ます.

そういうことを,まずは(人に訊く前に,当たり前のこととして)やるべきです.

うーる

Re: 文字列を逆順に表示したい

#8

投稿記事 by うーる » 1年前

お返事ありがとうございます。

基本に立ち返って簡単なところからやるというのは盲点でした。
次回からそのようにさせていただきたいと思います。

プログラミングではイコールの左側に右側を入れるのですね、私が使用していた教材にはその旨が書いていなかったので気が付けませんでした、ありがとうございます。

for文やscanfを使用しない形で逆順にすることができたのでこれを利用してコードを書いてみようと思います。

ありがとうございました!

アバター
usao
記事: 1887
登録日時: 11年前

Re: 文字列を逆順に表示したい

#9

投稿記事 by usao » 1年前

> プログラミングではイコールの左側に右側を入れるのですね、私が使用していた教材にはその旨が書いていなかったので気が付けませんでした、ありがとうございます。

これは冗談なのかマジなのか判断難しい絶妙な文章!!

あえて後者だと仮定してマジレスするならば…
配列を弄るような問題に取り組むよりも前に必要な前提知識を学ぶべき.
その「教材」とやらにそこらへんの話が書かれてないのならば,それは単に「そこは知っていることが前提」っていう扱いなのだろうと想像する.
そのような場合には,より平易な(もっと手前からの話が書いてあるような)別の情報元を探して,必要な事柄を補うのがよろしかろう.

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 文字列を逆順に表示したい

#10

投稿記事 by みけCAT » 1年前

うーる さんが書きました:
1年前
プログラミングではイコールの左側に右側を入れるのですね
C言語では=演算子を用いることで右辺の値を左辺の変数に代入できますが、
一般に「プログラミングではイコールの左側に右側を入れる」とは限りません。
例えば、BASIC言語では=を代入ではなく比較に用いることがあります。
うーる さんが書きました:
1年前
なぜなんの文字列も帰ってこないのか

コード:

    scanf("%d",n);
という行において、本来渡すべきnへのポインタ &n ではなくnの値そのものを渡してしまっているため、
nは未初期化なので読み込んだ値をデタラメな場所に書き込むようscanf関数に指示してしまい、
その結果アクセス違反となり、文字列を出力する前に強制終了してしまうからである、と考えられます。
オフトピック
なぜ文字列の長さをstrlenで求めるのではなく手動で入力させるのか…?
まあ競技プログラミングでも文字列の長さが文字列と別に与えられるタイプの問題はよくあるか…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 文字列を逆順に表示したい

#11

投稿記事 by みけCAT » 1年前

うーる さんが書きました:
1年前

コード:

       moji1[n]=moji2[n]
そもそもここでセミコロンが抜けているため、
提示するコードをC言語としてコンパイルしようとするとコンパイルエラーになるはずです。
何をどうやって実行しているのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: 文字列を逆順に表示したい

#12

投稿記事 by box » 1年前

こんな例はいかが?

コード:

#include <stdio.h>
#include <string.h>

#define LEN (10)

int main(void)
{
    char moji[LEN];
    int i;

    printf("mojiretsu:"), fgets(moji, LEN, stdin);
    for (i = strlen(moji) - 2; i >= 0; i--) {
        putchar(moji[i]);
    }
    putchar('\n');
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 文字列を逆順に表示したい

#13

投稿記事 by usao » 1年前

こんな例はいやだ

コード:

void ReversePrint( const char *Str )
{
	if( *Str == '\0' )return;
	ReversePrint( Str+1 );
	putchar( *Str );
}

int main()
{
	char InputStr[10];
	printf( "input : " );
	scanf( "%s", InputStr );

	ReversePrint( InputStr );
	putchar( '\n' );
	return 0;
}

返信

“C言語何でも質問掲示板” へ戻る