反転させて文字を表示することが出来ません。

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

反転させて文字を表示することが出来ません。

#1

投稿記事 by ヨセフ » 17年前

I like sports.を.strops ekil Iになるようにしたいのですが、出来ませんでした。
メイン関数の中がおかしいようなきがするのですが、どうでしょうか?

#include <stdio.h>

/* length関数の宣言 */
int length(char *str);

int main(void)
{
char str1[100], str2[100];
int i, j = 0, len_num;

printf("文字列を入力してください。");
gets(str1);

len_num = length(str1);
printf("%d",len_num);

printf("文字列 %s を反転させると %s になります。\n", str1, str2);

return 0;
}

/* length関数の定義 */
int length(char *str)
{
int c = 0;

while(*str){
c++;
str++;
}

return c;
}

YuO

Re:反転させて文字を表示することが出来ません。

#2

投稿記事 by YuO » 17年前

反転させるコードがないようですが。

str2には反転させた結果を入れたいのだと思いますが,
結果として,str2は内容が不定な状態のままprintfに渡されています。

ヨセフ

Re:反転させて文字を表示することが出来ません。

#3

投稿記事 by ヨセフ » 17年前

len_num = length(str1);
printf("%d",len_num);
これで反転できるつもりだったのですが・・・。

box

Re:反転させて文字を表示することが出来ません。

#4

投稿記事 by box » 17年前

length関数は、引数として与えた文字列の「長さ」を求めています。
「逆転させた文字列」を求めてはいません。

ところで、今回は、length関数も自作の対象なのですか?
文字列長を求めるには、strlenという標準関数があるのですけれど。

ヨセフ

Re:反転させて文字を表示することが出来ません。

#5

投稿記事 by ヨセフ » 17年前

この問題は、足りないところをたして、結果をだすというものでした。
最初は以下のような感じでした。
 
#include <stdio.h> 

/* length関数の宣言 */ 
int length(char *str); 

int main(void) 
{ 
char str1[100], str2[100]; 
int i, j = 0, len_num; 

printf("文字列を入力してください。"); 

printf("文字列 %s を反転させると %s になります。\n", str1, str2); 

return 0; 
} 

/* length関数の定義 */ 
int length(char *str) 
{ 
return c; 
} 
<//pre> 
実行結果は前に説明した通りです。
反転の方法はfor文が必要ですか?

KEV

Re:反転させて文字を表示することが出来ません。

#6

投稿記事 by KEV » 17年前

for文はきっと使います。多分こんな感じ
for(i = 0; i <  len_num; i++){ /* 処理 */}
あと、実行結果って見せてくれましたっけ?

> int i, j = 0, len_num;
これ、よく見ると i に0が入ってるようで入ってません。
jだけに0を入れたかった って理由があるならこれで正解でしょうけど、
多分違うと思うので。
まあ i と j は多分あとでfor文で使うのだろうから、
そこで初期化するだろうしバグにはならないような気がします。
けど、あまりよくない書き方だとは思います。

穴埋め問題っぽいから、問題作成者が間違ってるのかも。
にしても、main関数内に i と j があるってことは
回答ではmainの中で反転処理させるつもりだったんでしょうか…。
関数作ったほうがスマートなのになぁ。

通りすがり

無題

#7

投稿記事 by 通りすがり » 17年前

コードはきちんとプレタグで囲みましょう。
何故最初だけタグを書いたり一文字違ったりして一度もきちんと書けないのでしょう?
しっかり確認して投稿しましょう。
一回できちんと投稿出来る自信がないならプレビューをしてから投稿しましょう。
それでなくても削除キーを設定しておけば投稿後も修正出来ます。
きちんと誤字やタグミスの無い文章で投稿して下さい。

ヨセフ

Re:無題

#8

投稿記事 by ヨセフ » 17年前

実行する前初期化されていないとにエラーが出ます。
どうすればよいでしょう?

box

Re:無題

#9

投稿記事 by box » 17年前

最新のコードをpre, /preの両タグで挟んで、見せてください。

ヨセフ

Re:無題

#10

投稿記事 by ヨセフ » 17年前

こんな感じになっています。
#include <stdio.h>

/* length関数の宣言 */
int length(char *str);

int main(void)
{
  char str1[100], str2[100];
  int i, j = 0, len_num;
  
  printf("文字列を入力してください。");
  gets(str1);
  
	for(i = 0; i <  len_num; i++){
 hen_num=>i}

  printf("文字列 %s を反転させると %s になります。\n", str1, str2);
  
  return 0;
}

/* length関数の定義 */
int length(char *str)
{
  int c = 0;
  
  while(*str){
    c++;
    str++;
  }
  
  return c;
}

box

Re:無題

#11

投稿記事 by box » 17年前

hen_num=>i}

この行は、何をしたいのでしょうか。

box

Re:無題

#12

投稿記事 by box » 17年前

【例】"abcd"を与えて、逆順の"dcba"を得る

与えた文字列"abcd"の長さは4である。
このとき、str1[/url]の中身は次のとおりである。
str1[0]:'a'
str1[1]:'b'
str1[2]:'c'
str1[3]:'d'
str1[4]:'\0'(文字列終端を表わす)

さて、逆順の文字列を得る、ということは、
str2[0]:'d'
str2[1]:'c'
str2[2]:'b'
str2[3]:'a'
str2[4]:'\0'(きちんと終端させる)
の状態にすることである。

終端の'\0'は最後にセットするとして、さて、str1[/url]の各文字(例:'a')が入っている添字番号と
str2[/url]中の同じ文字('a')が入っている添字番号との間には、どういった関係式が成り立つだろうか。
考えてみよう。

ヨセフ

Re:無題

#13

投稿記事 by ヨセフ » 17年前

forでまわしたものを反転していくという考えでやってみました。

box

Re:無題

#14

投稿記事 by box » 17年前

> forでまわしたものを反転していくという考えでやってみました。

コンパイルできませんよね。

ヨセフ

Re:無題

#15

投稿記事 by ヨセフ » 17年前

str[1]とstr[2]の関係をかかなくてはいけないということですか?
str[1]=aのときはstr[2]に何かがくる、という感じにするということでしょうか?

box

Re:無題

#16

投稿記事 by box » 17年前

元の文字列str1で、'a'は[0]にありますね。
同じ'a'という文字が、逆順文字列str2では[3]にありますね。

このように、同じ'a'という文字が、str1[/url]とstr2[/url]のどこに入っているかには
法則があります。その法則を見つけてください、ということです。
'b'でも'c'でも'd'でも、共通の法則です。

ヨセフ

Re:反転させて文字を表示することが出来ません。

#17

投稿記事 by ヨセフ » 17年前

法則ですかぁ…。
1の箱の一番目にaが入ったら、2の箱の最後にaがくる。
という考え方ですよね?

box

Re:反転させて文字を表示することが出来ません。

#18

投稿記事 by box » 17年前

'a'という文字は、
反転前のstr1[0]と反転後のstr2[3]にあります。

'b'という文字は、
反転前のstr1[1]と反転後のstr2[2]にあります。

'c'という文字は、
反転前のstr1[2]と反転後のstr2[1]にあります。

'd'という文字は、
反転前のstr1[3]と反転後のstr2[0]にあります。

さて、上記のことから、同じ文字を格納しているstr1[/url]の添字番号と
str2[/url]の添字番号との間に、どういう関係があるでしょうか。

BIOS

その仕様のコードです。

#19

投稿記事 by BIOS » 17年前

#include <stdio.h>
#define MAZ 15
#define ZERO 0
static char ap[MAZ]={"I speak English"};
int main(void){
char wk;
int ia,ib;
for(ia=ZERO;ap[ia+1]='\n';ia++) printf("%c",ap[ia]);
printf("\n");
for(ia=ZERO;ib=MAZ-1;ia<ib;ia++,ib--){
wk=ap[ib];
ap[ib]=ap[ia];
ap[ia]=wk;
}
for(ia=ZERO;ap[ia+1]='\n';ia++) printf("%c",ap[ia]);
printf("\n");
return ZERO;
}
以上です。APIの技術情報を交換し合いませんか?もよろしくお願いいたします。

通りすがり

無題

#20

投稿記事 by 通りすがり » 17年前

>BIOSさん

答えのコードを投稿する事はboxさんや他の閲覧者の方々もすぐ出来ますが、それはしないでいるのです。
これではboxさんが今まで答えを提示することなく丁寧に答えに導いていらっしゃった努力が無意味になってしまいます。
場合によっては正解例を示しながら解説するほうがいい場合もあるかと思います。
ただし、今回の場合そのように感じられません。
しかも何故勝手にトピを解決にしてしまっているのでしょう。

ちょっと場の空気を読まない投稿が多すぎるのじゃないでしょうか。
また、コードはタグで囲みましょう。

YuO

Re:その仕様のコードです。

#21

投稿記事 by YuO » 17年前

at 2008-08-07T19:37+09:00
[19944] その仕様のコードです。
BIOS wrote (No. 19820) :
(ざっくり省略)

色々とだめ。
・ZEROなんてマクロあるだけ無駄 (ZEROという単語に数値0以上の意味がないから)
・MAZは定義する必要がない。必要ならstrlenを使う
・一つ目と三つ目のfor文の条件式が明らかに間違っている
・そもそもそれらのfor文を用意する意味がない (%15sとかで十分。本来ならナル文字で終端しておくべき)
・二つ目のfor文は構文が間違っている (;が多すぎる)
API云々の前に,Cの勉強をちゃんとすべきだと思います。

kaiten

Re:無題

#22

投稿記事 by kaiten » 17年前

>BIOSさん

>「マーク」はトピ主が選択する物です(トピ主は最後に「解決!」を選択)
>(つまりトピ主は最初質問か雑談のどちらかを選択する。返信者は選択の必要無し)

利用規約の一文です。言いたいことは通りすがりさんと同じなので言わないでおきますが。
答えを書くにしてもヨセフさんの書き方に合わせた方が親切だと思います。せめてコメント付けるとか。


本題と全く関係ないですけどなんかヒーロー戦機思い出した…やったことないのに……

box

Re:無題

#23

投稿記事 by box » 17年前

コンパイルエラー満載のコードで「解決!」って言われてもね…。

ヨセフ

Re:無題

#24

投稿記事 by ヨセフ » 17年前

すいません。
分けあって投稿が出来ませんでした。
解決はまだしていません。

同じ文字を格納しているstr1[/url]の添字番号と
str2[/url]の添字番号との間にある関係は、
aが最初に出ていて、反転した後は最後に出てるということですか?
ってなると前の考えと同じになってしまいすよね・・・。
逆に動いているって事ですか?

ヨセフ

Re:無題

#25

投稿記事 by ヨセフ » 17年前

文字を回して、回し終えたら、最後の文字から最初の文字までまた回すっていう考えもしてみたのですが?

あっすみません!「分けあって」ではなく、訳あってです。
ちゃんと編集が出来るように努力します。

YuO

Re:無題

#26

投稿記事 by YuO » 17年前

> 同じ文字を格納しているstr1[/url]の添字番号と
> str2[/url]の添字番号との間にある関係は、
> aが最初に出ていて、反転した後は最後に出てるということですか?

それを式で表して,はじめてプログラムが書けます。
まぁ,ポインタ使えば式は不要,という考え方もありますが。


> ってなると前の考えと同じになってしまいすよね・・・。
> 逆に動いているって事ですか?

やり方はひとつではないのですが,私の考えているやり方を。

今回の場合は別の配列へのコピーが入るので,
str1の添字番号からstr2の添字番号を計算で出してしまった方が楽だろう,と思います。

まずは,str1の中身が"abcde"だった場合の,
各文字のstr1における添字番号i1とstr2における添字番号i2を書き出してみてください。
表にすると分かり易くなると思います。
# これは紙と鉛筆で十分できると思います。

次に,各文字について,i1とi2の間にはどういう関係があるのか,数式化して下さい。
最後に,文字列の長さがlenの時に,str1の添字番号nにある文字はstr2の添字番号になるかを数式化して下さい。

あとは,str1の全ての文字について,上記の式を使ってstr2にコピーしていけばできあがりです。

ヨセフ

Re:無題

#27

投稿記事 by ヨセフ » 17年前

返事が遅くなってすみません。最近、パソコンの調子がよくないみたいで…。
今回の反転の方法をなんとなくは理解できたのですが、プログラムとしてかくと、
よくわからなくなってしまいます。

box

Re:無題

#28

投稿記事 by box » 17年前

下表の?部を埋めてみてください。


【"abcd"を"dcba"に反転させる場合】

文字列の長さ=4
反転前:str1
反転後:str2

+--------+-----+-----+-----+-----+-----+
| ------ | 'a' | 'b' | 'c' | 'd' | '\0'|
+--------+-----+-----+-----+-----+-----+
| str1の |  ?  |  ?  |  ?  |  ?  |  ?  |
|添字No. |     |     |     |     |     |
+--------+-----+-----+-----+-----+-----+
| str2の |  ?  |  ?  |  ?  |  ?  |  ?  |
|添字No. |     |     |     |     |     |
+--------+-----+-----+-----+-----+-----+



【"abcde"を"edcba"に反転させる場合】

文字列の長さ=5
反転前:str3
反転後:str4

+--------+-----+-----+-----+-----+-----+-----+
| ------ | 'a' | 'b' | 'c' | 'd' | 'e' | '\0'|
+--------+-----+-----+-----+-----+-----+-----+
| str3の |  ?  |  ?  |  ?  |  ?  |  ?  |  ?  |
|添字No. |     |     |     |     |     |     |
+--------+-----+-----+-----+-----+-----+-----+
| str4の |  ?  |  ?  |  ?  |  ?  |  ?  |  ?  |
|添字No. |     |     |     |     |     |     |
+--------+-----+-----+-----+-----+-----+-----+

ね~す

Re:無題

#29

投稿記事 by ね~す » 17年前

はじめまして。このスレを見ていてちょっとした思い付きがあったのですが、
このようなものはどうでしょうか。

| -4 | -3 | -2 | -1 |  0 | +1 | +2 | +3 | +4 |
|    |    |    |    |    | a  | b  | c  | d  |

ここで配列全体を文字数+1で引くと、

| -4 | -3 | -2 | -1 |  0 | +1 | +2 | +3 | +4 |   
| a  | b  | c  | d  |    |    |    |    |    |  ※ここの計算部分は配列に代入しません

そして、絶対値として計算すると、


| -4 | -3 | -2 | -1 |  0 | +1 | +2 | +3 | +4 |   
|    |    |    |    |    | d  | c  | b  | a  |

このようになる気がします。

Cは超初心者なので、ソースコードは書けませんが、この考え方が使えるのかな?と思います。
覚束ない日本語で申し訳ないです。

管理人

Re:無題

#30

投稿記事 by 管理人 » 17年前

>ね~すさん

それでも出来ますね。
ただ、0番を最初にした方がいいかもしれません。
実際にやってみました。
答えを書いてしまうとよくないので、肝心な要素番号をさす部分だけ省略してあります。
#include <stdio.h>
#include <string.h>
#include <math.h>

int main(){
	int i,len;
	char str[10]="abcd",str2[10];
	len=(int)strlen(str);
	for(i=0;i<len;i++)
		str2=str[上記理論];
	str2='\0';
	printf("%s\n",str2);
	return 0;
}

実行結果

dcba

 
「str[上記理論]」の部分を仰っている理論の通りに番号を示す式を書けばこれでも出来ました。

box

Re:無題

#31

投稿記事 by box » 17年前

ね~すさんの考え方はすばらしいと思います。
ただ、管理人さんも書かれているとおり、
C言語の配列はゼロ始まりですので、
こんな風に考えるのがよいかもしれません。


| -4 | -3 | -2 | -1 |  0 | +1 | +2 | +3 | +4 |
|    |    |    |    | a  | b  | c  | d  |    |


ここで配列全体から「文字数-1」を引く

| -4 | -3 | -2 | -1 |  0 | +1 | +2 | +3 | +4 |
|    | a  | b  | c  | d  |    |    |    |    |


正負を反転させるとできあがり

| -4 | -3 | -2 | -1 |  0 | +1 | +2 | +3 | +4 |
|    |    |    |    | d  | c  | b  | a  |    |

lbfuvab

Re:無題

#32

投稿記事 by lbfuvab » 17年前

文字列strと長さlenを渡すと逆に出力する
void PutStrReverse(char *str,int len);
を定義したとすると、
#include<stdio.h>
#include<string.h>

void PutStrReverse(char *str,int len);

void main(){
    char str[50];
    int len;
    
    puts("文字を入力してください");
    gets(str);
    puts("反転して出力します");
    PutStrReverse(str,strlen(str));
}
となりますよね。

後、PutStrReverseに関するヒントとしては
最初に出力するのはstr[len-1]で
最後に出力するのはstr[0]です。
後は上手くループを使ってやれば良いと思います。

閉鎖

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