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

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

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

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

Q&A

解決済

3回答

1870閲覧

ポインタを使って文字列を逆順に表示させたいです。

sawayakaunagi

総合スコア17

C

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

0グッド

0クリップ

投稿2021/11/14 00:26

ポインタを使ってキーボード入力した文字列を逆順に表示させたいのですが、うまくいきません。参考書を読んだり、試行錯誤したのですがわからずじまいでした。
きっと無茶苦茶なコードだと思うのですが、どこをどう直せばいか教えていただけると嬉しいです。

c

1コード 2#include <stdio.h> 3 4int str_length(const char *s) 5{ 6 int len = 0; 7 while(*s++) 8 len++; 9 return len; 10} 11int main(void) 12{ 13 printf("文字列を入力してください:"); 14 char t[100]; 15 char str[100]; 16 char *p1 = t; 17 char *p2; 18 scanf("%c",t); 19 int i; 20 21 p1 = &t[0]; 22 p2 = &str[0]; 23 24 int str_length = k; 25 for(i=0;i<k;i++){ 26 *(p2+k-i) = *(p1+i); 27 } 28 29 *(p2+k) = '\0'; 30 31 printf("str2の文字列は %s です.¥n", str); 32}

実行結果

c

1コード 2ensyuu5a.c: In function ‘main’: 3ensyuu5a.c:23:22: error: ‘k’ undeclared (first use in this function) 4 23 | int str_length = k; 5 | ^ 6ensyuu5a.c:23:22: note: each undeclared identifier is reported only once for each function it appears in

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

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

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

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

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

guest

回答3

0

間違っているのは次のところです。

diff

1-コード 2+//コード 3 4- scanf("%c",t); 5+ scanf("%s",t); 6 7- int str_length = k; 8+ int k = str_length(t); 9 10- *(p2+k-i) = *(p1+i); 11+ *(p2+k-i-1) = *(p1+i); 12 13- printf("str2の文字列は %s です.\n", str); 14+ printf("str の文字列は %s です.\n", str);

しかし、*(p1+i) という書き方は p1[i] と同じで、
i を添字とする配列のアクセスと変わりません。
ポインタを使ったプログラムというのは、ポインタを動かして配列の要素を
参照するプログラムを要求されているのだと思います。

例えば、次のようなものです。

C

1#include <stdio.h> 2 3int str_length(const char *s) 4{ 5 const char *p = s; 6 while (*p) p++; 7 return p - s; 8} 9 10int main(void) 11{ 12 char t[100]; 13 char str[100]; 14 printf("文字列を入力してください:"); 15 scanf("%s", t); 16 char *p1 = t + str_length(t); 17 char *p2 = str; 18 while (p1 > t) *p2++ = *--p1; 19 *p2 = '\0'; 20 printf("str の文字列は %s です.\n", str); 21}

投稿2021/11/14 01:12

編集2021/11/14 01:18
kazuma-s

総合スコア8224

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

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

0

C

1#include <stdio.h> 2 3int str_length(const char *s) { 4 int len = 0; 5 while(*s++) 6 len++; 7 return len; 8} 9 10int main(void) { 11 char t[100]; 12 char str[100]; 13 14 printf("文字列を入力してください:"); 15 scanf("%s",t); // %c -> %s 16 17 int k = str_length(t); // k = tの長さ 18 for ( int i = 0; i < k; i++ ) { 19 *(str+i) = *(t+k-i-1); 20 } 21 *(str+k) = '\0'; 22 23 printf("str2の文字列は %s です.\n", str); 24}

投稿2021/11/14 00:41

編集2021/11/14 01:34
episteme

総合スコア16614

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

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

0

ベストアンサー

まず、エラーメッセージを読んで対応しましょう。文法エラーが出ているならそれはプログラムの要件を満たしていない、「プログラム未満の何か」でしかないということですから、まずプログラムとして成立させましょう。

int str_length = k;
これは、str_lengthという変数を宣言し、初期値として(この時点で)変数kが持っている値を与えるという指示です。しかし、変数kというのはプログラムにそれまで登場していませんから、なんじゃそりゃ初めて見たぞそんなの知らない、ということでエラーになっています。

基本的な文法は教科書等を確認してください。ポインタ以前(別に前とか後ろがあるわけじゃないですけれど)がわからないで新しい話に手を出したら混乱が増すばかりかと思います。

関数の呼び出しは
関数名( 引数リスト )
です。
関数で得た値を変数に代入したいのなら代入の演算子=を使って
変数 = 関数名(引数リスト)
で「右辺の値を左辺に」代入してください。

さて。別に悪いことではないのですがstr_length()だけを関数に切り出したのはどういう理由でしょう。なんだか唐突な印象があります。
関数に切り出すのなら、例えば、「入力した文字列を逆順に表示させたい」というお題に則ってやることを考えて

  • リスト入力を保存する変数を用意

  • 入力を得る関数呼び出し

  • 反転した結果を保存する変数を用意

  • 反転する関数呼び出し

  • 反転した結果を表示する関数呼び出し

という作業をすればよさそうで、いきなり「文字数を数える関数が要るなぁ」とは考えないのではないでしょうか。(こういうのを考えて、できれば紙に書き出してからプログラムコードを打ち始める、というのは結構大事なことだと思います)

そうすると、

C

1int main(void){ 2 //入力する 3 char in[100]; 4 scanf("%99s",in); 5 6 //反転する 7 char rev[100]; 8 reverse(in,rev); 9 10 //表示する 11 printf("%s\n",rev); 12 13 return 0; 14}

ここまではポインタもへったくれもないですから、reverse関数にポインタ操作を盛り込んで

C

1void reverse( char* in, char* out){ 2 int len=str_length(in); 3 in+=len-1; //ポインタが入力の一番最後の文字を指すようにする 4 for(int i=0;i<len;i++){ 5 *out++=in--; 6 } 7 *out='\0'; 8}

とでもすればそれっぽい、という話になるでしょう。

もっとも、お題が何の制限もなく「ポインタを使ってキーボード入力した文字列を逆順に表示」だけなら、途中他の文字列を介する必要もなく

C

1int main(void){ 2 char in[100]; 3 scanf("%99s",in); 4 int len=str_length(in); 5 char* t=in+len; 6 while(t!=in){ 7 putchar(*--t);//printf("%c", *--t);でも同じ結果 8 } 9 return 0; 10}

あたりで十分じゃないでしょうか? いろいろ使って複雑にするのならそれなりの理由が必要と思います。

付け加えると、これも間違いではないのですが、変数の宣言と使う場所が微妙に離れているのも「なんだかいきあたりばったり/あちこちから集めた情報の切り貼りで作ってるなぁ」という印象を醸し出しているような気がします。

余談。
できるだけ「いろいろ使わない」とこんなのもできるげど...ポインタも使ってないや。

C

1int main(void){ 2 char c=getchar(); 3 // cへの値取り込みはscanf("%c",&c);を使ってもよい 4 if(c!='\n'){ 5 main(); 6 putchar(c); 7 } 8 return 0; 9}

投稿2021/11/14 04:11

編集2021/11/14 05:20
thkana

総合スコア7639

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

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

sawayakaunagi

2021/11/15 05:55

void reverse( char* in, char* out){ int len=str_length(in); in+=len-1; //ポインタが入力の一番最後の文字を指すようにする for(int i=0;i<len;i++){ *out++=in--; } この2行目のstr_length(in);の(in)はどのような役割をしているのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問