dポイントプレゼントキャンペーン実施中!

c言語でポインタ変数を用いた配列の反転操作を行いたいのですが、文字列の反転の仕方が分かりません。流れとしては、文字列の長さを調べてから文字列を反転して表示するという感じです。どうか教えてください。また、その他問題点があればご指摘よろしくお願いします。

#include <stdio.h>

int strlength(char *str) { /* 文字列の長さを調べる /*
int length = 0;

while (*str++ != '\0'){
length++;
}
return length;
}

int main(void) { /*配列strSrc[]の文字列を逆にして配列strDst[]に格納する */
char strSrc[] = "reverse this";
char *pC;
char strDst[] = "01234567890123456789";
char *pD;
int length;

printf( "%s\n", strSrc );

/* この部分が分かりません */

printf("%s\n", strDst ) ;

return( 0 );
}

A 回答 (15件中1~10件)

質問者さんの意図を素直に読み取ると、こんなのでもいいかも。



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

int main(void)
{
char s[] = "reverse this", *p, *q, t;

printf("逆転前:%s\n", s);
for (p = s, q = &s[strlen(s)-1]; p < q; p++, q--) {
t = *p, *p = *q, *q = t;
}
printf("逆転後:%s\n", s);
return 0;
}
    • good
    • 0

>流れとしては、文字列の長さを調べてから文字列を反転して表示するという感じです。



>/*配列strSrc[]の文字列を逆にして配列strDst[]に格納する */

 質問者様の「望む結果」は、No.2 さんのような結果の他に、

 "siht esrever23456789" とも考えられます(特にソースから)。

 これを実現するソースを回答します。

( No.2 さんのような結果を望むのであれば、格納後、出力直前に strDst[ iLength + 1 ] = '\0'; )

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

int main( void )
{
 char strSrc[] = "reverse this";
 char strDst[] = "01234567890123456789";
 char *pS = strSrc;
 char *pD = strDst;
 int iLength;

 iLength = strlen( strSrc ) - 1; // - 1 に注意

 printf( "%s\n", strSrc );

 pD += iLength; // 長さ分、後方へ

 while( *pS ){

  *pD = *pS; // 1文字ずつ「格納する」

  pS++; // 後方へ
  pD--; // 前方へ
 }
 printf( "%s\n", strDst );

 return( 0 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
    • good
    • 2

>#12さん


そりゃそうですね。これは一本取られました。:D
    • good
    • 0

>#10, 11


それをやるならいっそ「文字列の最後から先頭に向けて1文字ずつ画面表示」してしまえば入れ替えルーチンすら不要ですが。
    • good
    • 1

>・先頭と最後を入れ替える



言わずもがなですが、ここでいう「最後」とは'\0'のことではないです。
    • good
    • 0

対象配列の


・先頭と最後を入れ替える
・先頭の次と最後の前を入れ替える
・…
を適切に繰り返せば、strDst[]は不要で、十分な領域が必要云々の議論も不要ですね。
    • good
    • 0

受け手になる strDst に十分な領域を確保しなきゃいけないのは #8 の通りで, 正攻法で行くなら malloc で動的に確保するんだけど手を抜くなら (今の場合は)


char strDst[sizeof strSrc];
でも OK.
あと, 本当は「文字列を反転する」という関数を作った方がいいような気がする. インターフェースは string.h の strcpy/strncpy とか (標準にはないけど) strdup に合わせる方向で.
    • good
    • 0

逆順コピーの手順自体は既に書かれています(※)が、元コードはもともとstrSrcがstrDstより長いとエラーになる、という問題を抱えています。


※敢えて言うなら#7の手順はどこかでstrDstの終端を入れる必要がある、というくらい

汎用性を上げるならstrDstは動的に確保する方がいいです。
char *strDst;
strDst = malloc(sizeof(char) * (length + 1));

length + 1で確保するのはlengthに渡る値が終端文字分を含まないためです。
    • good
    • 0

#6さんへ



>2) 文字列の先頭アドレスを ポインタpCに代入
>3) 文字列の末尾アドレスを ポインタpDに代入
>3) ループで末尾側と先頭側を入れ替え

これだと、「配列strSrc[]の文字列自体を逆にする」という仕様になります。しかし、元の質問では「配列strSrc[]の文字列を逆にして配列strDst[]に格納する」という仕様なので、違ったものになってしまいますね。
strSrcの内容を逆にしてからstrDstにコピーするのなら結果は一緒ですが、おそらく出題の意図からは外れてしまうと思います。
なのでここは、下記のような流れになるかと。

2) strSrcの先頭アドレスを ポインタpCに代入
3) strDstの末尾アドレスを ポインタpDに代入
4) 文字列の長さ分、下記を繰り返す
4-1) pC→pDに値を代入
4-2) pCをインクリメント
4-3) pDをデクリメント
    • good
    • 0

考え方は


1) 元の文字列の長さを取得
2) 文字列の先頭アドレスを ポインタpCに代入
3) 文字列の末尾アドレスを ポインタpDに代入
3) ループで末尾側と先頭側を入れ替え
  pCをインクリメント ... 末尾側へ移動
  pDをデクリメント ... 先頭側へ移動
4) pCとpDを比較して交差するかまたは同一ならループ終了
  要素が偶数なら ... 交差
  要素が奇数なら ... 同一
といった具合でしょう

4)の判定ですが
01234567890123456789 この文字列を処理していくと
98765432190876543210 10回目のループで 10文字目の『9』と11文字目『0』の入れ替えをします
これで98765432109876543210が逆順になり完成します
このとき pCとpDは
pC = &strDst[9], pD = &strDst[10] です
ループでpC++ pD-- を実行すると
pC = &strDst[10], pD = &strDst[9] になり交差します

奇数だった場合は pC = &strDst[9], pD = &strDst[9] のように中心の文字を指すときがありますのでこれを終了条件にします

このようにして終了判定をしないと せっかく逆順にした文字列を
もう一度逆順に加工してしまい 結果として逆順の逆順つまり元通りにしてしまうことがあります
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!