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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

779閲覧

for文の動作について。

carnage0216

総合スコア194

C

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/01/31 10:40

編集2021/01/31 13:32
#include <stdio.h> #include <string.h> int main(void){ char str[] = "str == NULL ? \"(NULL)\" : str"; char *p, *q; int ch; p = str; for(;;){ for(q=p; !(*q=='?' || *q==':' || *q==0); q++) ; ch = *q; *q = 0; printf("|%s|\n", p); if(ch==0) break; p = q+1; } }

以上のプログラムについて

char str[] = "str == NULL ? \"(NULL)\" : str"; char *p, *q; int ch; p = str;

までの動作はわかるのですが、残りの部分の動作がいまいちわかりません。
どうか

for(;;){ for(q=p; !(*q=='?' || *q==':' || *q==0); q++) ; ch = *q; *q = 0; printf("|%s|\n", p); if(ch==0) break; p = q+1; } }

自分なりの考え
**多分、for(q=p; !(*q=='?' || q==':' || q==0); q++) ;に関しては、
p(ポインタ)のアドレスをq(ポインタ)に代入(箱に入れて)して、qのアドレスに入った文字列に含まれる?や:や0を探すためにqのアドレスをq++より++していき一致した場合、chに代入して、qに0を代入、これを繰り返しと思うのですが、
文字列[str == NULL]["(NULL)"][str"]はchに入っていると思ったのですが、なぜ printf("|%s|\n", ch);
ではなく、 printf("|%s|\n", p);なのでしょうか?
また if(ch==0) break;よりchに何も入らない(NULL)の後にp = q+1;とありますが、
これは何のための物でしょうか?

の部分の動作を細かく教えて頂けないでしょうか?
kazuma-sさんのような解説が一番わかりやすいです。

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

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

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

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

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

maisumakun

2021/01/31 10:58

逆質問にはなりますが、何を意図して書いたプログラムなのでしょうか?
carnage0216

2021/01/31 11:28

古い本に書いてあったプログラムです。
guest

回答2

0

ベストアンサー

p(ポインタ)のアドレスをq(ポインタ)に代入して、

ポインタ変数 p が保持している str[0] のアドレスをポインタ変数 q に代入して、
p も q も文字列 "str = ... str" を指すようになります。

qのアドレスに入った文字列に含まれる?や:や0を探すために

q の指す文字列 "str = ... str" に含まれる '?' や ':' や '\0' を探すために

qのアドレスをq++より++していき一致した場合

q の持つアドレスを 1つずつ進めて、str[0]、str[1]、str[2]、... を *q で
見ていき、一致する文字を探します。

chに代入して、qに0を代入、

ch に代入するのは q の値ではなく、*q の値です。
それは '?' または ':' または '\0' です。

q に代入はしていません。*q に 0 (すなわち '\0')を代入しています。

文字列[str == NULL]["(NULL)"][str"]はchに入っていると思ったのですが、

文字列の長さは 28です。文字列の終端の '\0' を含めて 29バイトあります。
ch は int で 4バイトです。
ch に文字列を代入することはできません。
ch に代入しているのは *q の値。すなわち '?' または ':' または '\0' です。

また if(ch==0) break;よりchに何も入らない(NULL)の後に

ch==0 の 0 は NULL ではなく、'\0' です。
ch に '?' でも ':' でもなく、'\0' が入っていた場合は、
もう次に探す文字列がないので break; で for(;;) の無限ループから脱出します。

p = q+1;とありますが、これは何のための物でしょうか?

ch が '?' または ';' だった場合、次に探索する文字列をその次に進めるためです。
*q に 0 を代入して文字列を 2つに分割したあとの 2番目の文字列の先頭を
p が指すようにします。

追記
amazon で「苦しんで覚えるC言語」を検索して、「試し読み」で目次を見たら、
pp.252-354 が「第14章 文字列を扱う方法」と「第15章 ポインタ変数」だと分かりました。
説明はとても丁寧で分かりやすく書いてあります。
これを読んで、q と *q の違いが分からないはずがないと思うのですが、
まだ分からないのですね。

書名を教えてもらったので、次の質問には答えます。

q=p; はpの値をqに代入します。そして

!(*q=='?' || *q==':' || *q==0); に進む、
qに入った文字列を一つとして扱うのではなく、文字列の文字一つ一つの文字のアドレスに含まれる?:0を探すために!(*q=='?' || q==':' || q==0);の形にした。
しかし、なぜ
q++ではなく、q++なのでしょうか?
++してアドレスをずらしていきながら?:0をを探すのなら
q++ではないのですか?

まず、「q に入った文字列」ですが、
q はポインタ変数なので、29バイトの文字列は入りません。
q に入るのは、文字列の先頭アドレスです。

p = str; は p = &str[0]; と同じ意味です。
p には、str[0] のアドレスが入っています。
q = p を実行すると、q にも str[0] のアドレスが入ります。
p も q もポインタで、str[0] を指しているのです。
str[0] は文字列の先頭なので、p と q は文字列を指していると言っていいでしょう。

q=='?' ですが、 は間接演算子なので、*q は q の指している変数になります。
q の値は str[0] のアドレスなので、*q は str[0] です。
*q=='?' は str[0]=='?' のことなのです。

q++ で、q が 1増えます。q の値は str[1] のアドレスになりました。
次の *q=='?' は str[1]=='?' のことなのです。

これを繰り返すと、str[12] が '?' なので、そこで forループを抜けます。
q は str[12] を指しています。q には str[12] のアドレスが入っています。

q++ ですが、後置演算子++ のほうが、前置演算子 よりも優先順位が高いので、
(q++) ということになります。
q++ で str[0] のアドレスを持っていた q が str[1] のアドレスを持つようになります。
ただし、後置演算子++ の演算結果は 1増えた q の値ではなく、元の値です。
ということは、 q++ の値は str[0] のアドレスのままです。
前置演算子
により *q++ は str[0] になります。
この str[0] という変数は、値を参照されることもなく、別の値を代入されること
もなく、何の意味もないことになります。

for (i = 0; a[i] != 0; i++) printf("%d\n", a[i]); を
for (i = 0; a[i] != 0; a[i++]) printf("%d\n", a[i]); と書いても同じように
動きますが、だれもそんな風には書きません。

for (q = p; !(*q == '?'); q++) を
for (q = p; !(*q == '?'); *q++) と書いても同じように動きますが、
そう書く意味はありません。

追記2
ポインタを使わずに配列だけで書いてみました。
実行手順も実行結果もポインタを使ったものと同じです。

C

1#include <stdio.h> 2#include <string.h> 3 4int main(void) 5{ 6 char str[] = "str == NULL ? \"(NULL)\" : str"; 7 int i, j; 8 int ch; 9 i = 0; 10 for (;;) { 11 for (j = i; !(str[j]=='?' || str[j]==':' || str[j]==0); j++) ; 12 ch = str[j]; 13 str[j] = 0; 14 printf("|%s|\n", &str[i]); 15 if (ch == 0) break; 16 i = j + 1; 17 } 18}

これなら理解できますか?

p は &str[i]、*p は str[i]、
q は &str[j]、*q は str[j] という関係です。

追記3

しかし、なぜ*q++ではなく、q++なのでしょうか?

++してアドレスをずらしていきながら?:0をを探すのなら*q++ではないのですか?

この質問に対して、i++ と a[i++] の例を出して、a[i++] は無意味であり、
同様に q++ で済むのに、*q++ と書くのは無意味である、
と回答しましたが、理解されなかったようですね。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 int a[4] = { 3, 5, 7, 0 }; 6 char str[4] = "abc"; // char str[5] = { 'a', 'b', 'c', '\0' }; でも同じ 7 8 for (int i = 0; a[i] != 0; i++) printf("%d ", a[i]); 9 putchar('\n'); 10 for (int i = 0; a[i] != 0; a[i++]) printf("%d ", a[i]); 11 putchar('\n'); 12 for (int i = 0; a[i] != 0; &a[i++]) printf("%d ", a[i]); 13 putchar('\n'); 14 15 for (int i = 0; str[i] != 0; i++) printf("%s ", &str[i]); 16 putchar('\n'); 17 for (int i = 0; str[i] != 0; str[i++]) printf("%s ", &str[i]); 18 putchar('\n'); 19 for (int i = 0; str[i] != 0; &str[i++]) printf("%s ", &str[i]); 20 putchar('\n'); 21 22 for (char *p = str; *p != 0; p++) printf("%s ", p); 23 putchar('\n'); 24 for (char *p = str; *p != 0; *p++) printf("%s ", p); 25 putchar('\n'); 26 for (char *p = str; *p != 0; &*p++) printf("%s ", p); 27 putchar('\n'); 28}

i++ や p++ に意味があるのに、それに * や [] や & を付けてもその演算結果を
使わないのであれば無意味です。
わかりませんか?

投稿2021/01/31 13:17

編集2021/02/13 07:57
kazuma-s

総合スコア8224

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

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

carnage0216

2021/01/31 13:25

ありがとうございます。 あの今更ながら、pと*pの違いは何でしょうか? ポインタと、固定されたポインタという区別でしょうか?
kazuma-s

2021/01/31 13:28

入門書の「ポインタ」の章をよく読んでマスターしてください。 そうでないと、いくら回答をもらっても全く理解できないはずです。
carnage0216

2021/01/31 14:25

pは変数の「値」を扱い、*pは変数の値の「アドレス」を表しているのですね。
kazuma-s

2021/01/31 14:54 編集

違います。入門書を読みましたか? 入門書の最初の方に書いてあるので、10分、長くても30分読めば分かります。
carnage0216

2021/02/01 03:33

q=p; はpの値をqに代入します。そして !(*q=='?' || *q==':' || *q==0); に進む、 qに入った文字列を一つとして扱うのではなく、文字列の文字一つ一つの文字のアドレスに含まれる?:0を探すために!(*q=='?' || *q==':' || *q==0);の形にした。 しかし、なぜ*q++ではなく、q++なのでしょうか? ++してアドレスをずらしていきながら?:0をを探すのなら*q++ではないのですか? どうか詳しく教えてください。
carnage0216

2021/02/01 03:40

それともfor文的に*q++ではなく、q++という書き方なのでしょうか?
kazuma-s

2021/02/01 04:04

入門書を読んだのか読んでないのかを答えてください。 読んだ場合は書名を教えてください。 web上のサイトを参照したのなら、URL を教えてください。 それらを読んだけれども分からないのであれば、上の質問にお答えします。
carnage0216

2021/02/01 04:08

すいませんでした。読みながら解読しています。 呼んでいる本は苦しんで覚えるC言語です。
carnage0216

2021/02/01 04:12

252から324まで読みましたが、こんな理解力なので、応用に対抗できず、悩んでいます。
carnage0216

2021/02/01 04:14

出来れば、図などを用いて説明して頂けると大変助かります。
Zuishin

2021/02/01 04:39

https://9cguide.appspot.com/15-05.html これが理解できるとは思えませんが、読んでいるようにも思えません。 読んでいれば「通常変数モード」や「ショートカット」などの謎のワードが飛び出してきたでしょう。
carnage0216

2021/02/01 21:41 編集

ありがとうございます。 凄くわかりやすいです。かずまさんに本を書いて出版してほしいほどです。 あのできればhttps://teratail.com/questions/319574にも答えて頂きたいです。 また、改めて読み直したのですが、ポインタはアドレスを保持し、そのアドレスにポインタの文字列や数値が入るという理解で良いでしょうか?
carnage0216

2021/02/01 21:01 編集

編集します。 p=strより、ポインタpが持つアドレスが指す メモリに文字列が入る。 forのq++により ポインタqが持つアドレスが指すメモリの先頭に入れた文字のアドレスはforにより一つ一つ+され、そのアドレスの対応したメモリを探してメモリに入った文字列の文字を?:0を排除しながら、排除されなかった文字列のポインタのみが p=qによりポインタqに持つアドレスが指すメモリに入った文字列がポインタpが持つアドレスが指すメモリ代入する。 それによりアドレスは上書きされ、ポインタpの持つアドレスの指すメモリに文字列が入り保存される そして、 p=q+1はポインタqが持つアドレスを+1したアドレスをポインタpに入れて、次の文字列がはいるメモリとしてに書いた。 それを繰り返して、保管されたポインタpの持つアドレスに入ったメモリの文字列をprintf("|%s|\n", p);により表示する。同時にch = *q;より、*qはqの値や文字を扱うので、文字がchに代入され、 if(ch==0) break;より0の文字が来たら終了してループを抜ける。 と理解しました。正しいでしょうか?
carnage0216

2021/02/01 22:44

for(q=p; !(*q=='?' || *q==':' || *q==0); q++) ; ch = *q;// q++して、アドレスを++して、そのアドレスの指すメモリにある変数 *qの文字をchに入れる。そして、*q=='?' || *q==':' || *q==0の条件に当てはまるまで、++されていくメモリにある変数 *qの文字をポインタpの先頭のアドレスに代入する。 *q = 0;//変数 *qの中身を0にする。 printf("|%s|\n", p);//pには文字列の先頭のアドレスが入っているのですが、なぜ printf("|%s|\n", *p);ではないのでしょうか?アドレスに入っている「文字列」なのでpではないのでしょうか? デバッグを掛けてみるとprintfの引数は文字列の「アドレス」でなければならないと出ました。 なのでprintf("|%s|\n", p);と書くしかないとわかりましたが、その文字列の数値のコードを文字列にするために%sと書いたという認識でしょうか?これは文字列を表示する場合にprintf("|%s|\n", p);としているのですか?それともprintfはアドレスしか扱えないのでしょうか?(入門書にはそのようなことは書いてなかったのですが。) p = q+1;//文字列を表示した後、p = strより、strに入った文字列をpのアドレスに代入するためにqのアドレスを+した。 そして、if(ch==0) break;よりchに0が来たらループ終了。
kazuma-s

2021/02/02 06:32

> ポインタはアドレスを保持し、そのアドレスにポインタの文字列や数値が入るという理解で良いでしょうか? アドレスはメモリ上の位置を示す値です。値に文字列や数値を入れることはできません。 ポインタ変数がアドレスを保持することによって、そのポインタが指すメモリ領域に 数値や文字列を入れたり、その領域から取り出したりできるのです。 そのメモリ領域に名前を付けたのが変数です。 ポインタ変数は、ある変数のアドレスを持つことによって、変数を指します。 ポインタに間接参照演算子* を適用することで、演算結果は変数になります。 変数だから、その値を取り出すこともできるし、別の値を入れることもできます。 本当は変数の代わりに、オブジェクトや左辺値という規格書の用語を使いたいのですが、 混乱するといけないのでやめておきます。
kazuma-s

2021/02/02 06:36

> p=strより、ポインタpが持つアドレスが指すメモリに文字列が入る。 文字列が入るのではなく、文字列は既にメモリに入っていて、 そのメモリ領域には str という変数名が付いています。 p = str; により、p が その文字列の先頭アドレスを持つようになるだけです。 p は &str[0] であり、*p は str[0] です。
carnage0216

2021/02/02 15:14

編集どうもありがとうございます。 あの良ければ >>printf("|%s|\n", p);//pには文字列の先頭のアドレスが入っているのですが、なぜ printf("|%s|\n", *p);ではないのでしょうか?アドレスに入っている「文字列」なのでpではないのでしょうか? デバッグを掛けてみるとprintfの引数は文字列の「アドレス」でなければならないと出ました。 にもお答えして頂けないでしょうか? またhttps://teratail.com/questions/319574に関して、デバッグしたのですがbuffer3には文字列ではなく、数値が入ります。
kazuma-s

2021/02/02 17:02 編集

「苦しんで覚えるC言語」をもう一度読み直してください。 といっても読まないか、読んでもなかなか理解できないようなので、一応説明します。 char *p; と宣言された p はポインタです。「char へのポインタ」です。 char str[] = "str ==..."; と宣言された str は配列です。「char の配列」です。 配列の要素 str[0] の型は char で、値は 's' です。 配列の要素 str[1] の型は char で、値は 't' です。 p = str; は p = &str[0]; と同じで、p には str[0] のアドレスが入りました。 p は文字列の先頭のアドレスを持っています。 *p は ポインタp が指している str[0] です。 *p も str[0] もその型は char で、値は 's' です。 書式が "%s" のとき、printf は「char へのポインタ」の値、すなわち 文字列の先頭アドレスが来るぞ、と解釈するので、p の値が渡されると、 その文字列全体を表示します。 書式が "%s" なのに、アドレスではなく 's' という値が来ても文字列を表示できません。 *p の値は 's' であり、その値は 0x73 であり、 それをアドレスと解釈してとんでもないところを参照してしまいます。 「苦しんで覚えるC言語」をもう一度読んで理解できました、という声を聞きたいものです。
kazuma-s

2021/02/02 16:41

もう一度確認します。 p と *p の違いを理解していますか?
carnage0216

2021/02/03 03:08

pは文字列の入るアドレスを表し、*pはそのアドレスに入る文字('s' )や数字の文字コード( 0x73 )や10進数などの数字を表しています。 >>書式が "%s" のとき、printf は「char へのポインタ」の値、すなわち 文字列の先頭アドレスが来るぞ、と解釈するので、p の値が渡されると、 その文字列全体を表示します。 printfで書式が"%s" は文字や数字が来ても表示できずないので、アドレスなど渡してあげないとならない、なので(文字や文字列などを保存するメモリの)アドレスを表す(char の)ポインタpを渡す。 書式"%s"はアドレスからの文字列しか表示できないため。pの表すアドレスの指すメモリにある文字列をprintfにより表示される。 合っているでしょうか? また書式"%s"はアドレスからの文字列しか表示できないという仕様なのでしょうか?要は、そのまま文字列の値、例えば 文字's' でその値 0x73が来ても、その文字の値0x73が来ても表示できず、文字's' の入ったアドレスを渡すことで、アドレスから文字の値0x73を渡され、's'が表示できるということでしょうか?
kazuma-s

2021/02/05 22:31

回答の追記2 で配列版のコードを示しました。 「これなら理解できますか?」と質問したのに、それには答えず、 ポインタ版のコードと配列版のコードをごちゃ混ぜにし、 j++ の意味を問う新たな質問をするとは、どういうことですか?
carnage0216

2021/02/13 08:25 編集

ありがとうございます。 あの for (i = 0; a[i] != 0; i++) printf("%d\n", a[i]); を for (i = 0; a[i] != 0; a[i++]) printf("%d\n", a[i]); ではなく、 for (i = 0; &str[i] != 0; i++) printf("%d\n", &str[i]); を for (i = 0; &str[i] != 0; &str[i++]) printf("%d\n", &str[i]);ではないのでしょうか? &が付いていないとポインタとして定義できなかったと思います。 いえ、%dより値を表すため、アドレスではなく、アドレスに入った「数値」を表すためにstr[i]で良いのですね。間違えていました。また p は &str[i]、*p は str[i]、 q は &str[j]、*q は str[j] よりa[i]はポインタの表すアドレスに入っている「数値を表す」とわかりました。 正しいでしょうか? 正しくは for (i = 0; str[i] != 0; i++) printf("%d\n", str[i]); を for (i = 0; str[i] != 0; str[i++]) printf("%d\n", str[i]);でした。 ちなみにこのプログラムはアドレスのメモリに入った「数値」を表すためのプログラムですか?
carnage0216

2021/02/13 07:32

ch = str[j];について、 str[i];と同じアドレスで動くため、 str[j] = 0;と書かないと次のループで str[j] の指定するアドレスの初めからメモリに入る一つ一つの文字(文字列)chに入ってしまい if (ch == 0) break;がうまく作用しないため、 ch = str[j]; str[j] = 0; if (ch == 0) break; が必要とわかりました。
kazuma-s

2021/02/13 08:23

for の中をよく見たら、str[i] != 0 ではなくて、&str[i] != 0 と書いていますね。 str[i] はメモリ上にありますから、そのアドレスは確定しています。 &str[i] は str[i] のアドレスであり、0 (NULL のこと) になることはあり得ません。 for文は無限ループになり、i の値がどんどん大きくなり配列 str の範囲外にアクセスしてしまいます。
kazuma-s

2021/02/13 08:26

& を付けるということは、変数のアドレスを求めるということです。 求めた値を使わないと & をつける意味がありません。 for文の 3番目の式に &str[i++] と書いても無駄です。i++ で十分です。 printf の &str[i] は、その値を printf に渡すということで意味があります。
carnage0216

2021/02/13 08:28

すいません、編集します。 あの for (i = 0; a[i] != 0; i++) printf("%d\n", a[i]); を for (i = 0; a[i] != 0; a[i++]) printf("%d\n", a[i]); ではなく、 for (i = 0; &str[i] != 0; i++) printf("%d\n", &str[i]); を for (i = 0; &str[i] != 0; &str[i++]) printf("%d\n", &str[i]);ではないかと思っていましたが、 &が付いた際はポインタのアドレスを扱う定義だったので。 いえ、%dより値を表すため、アドレスではなく、アドレスに入った「数値」を表すためにstr[i]で良いのですね。間違えていました。また p は &str[i]、*p は str[i]、 q は &str[j]、*q は str[j] よりa[i]はポインタの表すアドレスに入っている「数値を表す」とわかりました。 正しいでしょうか? 正しくは for (i = 0; str[i] != 0; i++) printf("%d\n", str[i]); を for (i = 0; str[i] != 0; str[i++]) printf("%d\n", str[i]);でした。 ちなみにこのプログラムはアドレスのメモリに入った「数値」を表すためのプログラムですか?
carnage0216

2021/02/13 08:30

なるほど、 for (i = 0; str[i] != 0; i++) printf("%d\n", str[i]); を for (i = 0; str[i] != 0; str[i++]) printf("%d\n", str[i]);でした。 は 前もってstr[i]と定義されているため for (i = 0; str[i] != 0; i++) printf("%d\n", str[i]); for (i = 0; str[i] != 0; i++) printf("%d\n", str[i]);としても良いのですね。
carnage0216

2021/02/13 08:31

2021/02/13 17:28と2021/02/13 17:30の解釈が正しいかはいかいいえで答えて頂けるとありがたいです。
kazuma-s

2021/02/13 09:15

見落としていました。printf("%d\n", &str[i]); はダメです。 %d は int の値を数字列に変換するためのもので、ポインタの値(アドレス) には使えません。 printf("%d\n", str[i]); なら、str[i] の型は char ですが、値は int に変換されるので問題ありません。 2021/02/13 17:28 > よりa[i]はポインタの表すアドレスに入っている「数値を表す」とわかりました。 正しいでしょうか? いいえ、正しくありません。 a[i] は配列 a の i番目の要素であり、printf に渡す引数として使うなら、数値になります。 ポインタやアドレスという用語はどこからでてきましたか? あるいは、a[i] が *(a + i) と同じであるという事実をご存知ですか? > ちなみにこのプログラムはアドレスのメモリに入った「数値」を表すためのプログラムですか? 「アドレスのメモリに入った」が意味不明であり、「はい・いいえ」で答えられません。 配列 str の各要素の文字の文字コードの値を 10進数で表示するものです。 2021/02/13 17:30 「前もってstr[i]と定義されているため」が意味不明のため答えられません。 そのあとの 2つの for文が同じもののため、意味不明です。
guest

0

なぜ printf("|%s|\n", ch); ではなく、 printf("|%s|\n", p);なのでしょうか?

文字で無く文字列を表示するためです。
文字列としてまとめて表示せず、1文字ずつ表示する案もあるでしょうか、それを|で囲むようにする処理が面倒になりそうですね。

また if(ch==0) break;よりchに何も入らない(NULL)の後にp = q+1;とありますが、 これは何のための物でしょうか?

今表示した文字列(pからqまで)の続きを処理するためです。

投稿2021/01/31 11:56

otn

総合スコア84421

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問