🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

C++

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

Q&A

3回答

690閲覧

putsと文字列に関して。

carnage0216

総合スコア194

C

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

C++

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

0グッド

0クリップ

投稿2021/01/28 11:58

#pragma warning(disable: 4996) #include <stdio.h> // puts, printf #include <string.h> // strcpy, strtok int main() { const char* str = "abc:123\n,tdef:45,ghi:678."; char buf[1024], * p; strcpy(buf, str); puts("-- \"\n\" --"); p = strtok(buf, "\n"); while (p) { printf("[%s]\n", p); p = strtok(NULL, "\n"); } strcpy(buf, str); puts("-- \"\t\" --"); p = strtok(buf, "\t"); while (p) { printf("[%s]\n", p); p = strtok(NULL, "\t"); } strcpy(buf, str); puts("-- \",\" --"); p = strtok(buf, ","); while (p) { printf("[%s]\n", p); p = strtok(NULL, ","); } strcpy(buf, str); puts("-- \",\t\n\" --"); p = strtok(buf, ",\t\n"); while (p) { printf("[%s]\n", p); p = strtok(NULL, ",."); } }

質問
const char* str = "abc:123\n,tdef:45,ghi:678.";とした場合、
\tは文字列にないのに結果が
[abc:123
,tdef:45,ghi:678.]
と改行された形になる理由がわかりません。
文字列に\tがあった場合に改行されるのではないですか?

また三つ目に関しても
[abc:123]
[tdef:45]
[ghi:678]
ではなく、
[abc:123
]
[tdef:45]
[ghi:678.]
と]が改行されている意味が分かりません。バグなどでしょうか?

質問2
もう一つ、同じような問題で理解が出来ないのですが
以下のプログラム
プログラム
の135行目から150行の
以下の部分について
文字列が
「今日は
晴れた 日です。」
と入力した場合、どのような文字列で出力されるのでしょうか?
またなぜwhile (n < 100 && words[n])のように書けるのでしょうか?

words[n] = strtok(buf, "\t\n"); while (n < 100 && words[n]) {//★★ここでもnが0から始まるのが、上での「タバコ」に続く品詞や改行が strtok(NULL, "\t\n"); //によりNULLになる。しかし、nが0の時の「タバコ」はwhileに入る前のwords[n] = strtok(buf, "\t\n");で //既にwords[n]に入っているため必要ない、なのでstrtok(NULL, "\t\n");のみしか書いていない。かつ、何周しても // 正しく単語がwords[++n]に入るように strtok(NULL, "\t\n");と // words[++n] = strtok(NULL, "\t\n");は同じ条件としている。 //二行目の「を」やその後に続く単語には品詞や改行が続くので、その部分をNULLにして words[++n] に単語を入れるために //words[++n] = strtok(NULL, "\t\n");は書いてある。 // strtok(NULL, "\t\n");//★一週目のwords[n] = strtok(buf, "\t\n")のためにこいつがあり、その後の二周目以降のwords[++n] = strtok(NULL, "\n"); }

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

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

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

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

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

episteme

2021/01/28 12:34

質問2: > どのような文字列で出力されるのでしょうか? やってみればわかる。
episteme

2021/01/28 22:54

この件、puts は何の関係もない。
guest

回答3

0

C

1 printf("[%s]\n", "abc\ndef"); 2 printf("[%s]\n", "abc\tdef");

これがどう表示されるか試してみてください。

追記
(1)
"abc:123\n,tdef:45,ghi:678." を "\n" で分割すると、
"abc:123" と ",tdef:45,ghi:678." の 2つに分割される。
この 2つを printf("[%s]\n", で表示すると、
[abc:123]
[,tdef:45,ghi:678.]

(2)
"abc:123\n,tdef:45,ghi:678." を "\t" で分割すると、
"\t" がないので、
"abc:123\n,tdef:45,ghi:678." 全体 1つだけが得られる。
これを printf("[%s]\n", で表示すると、
[abc:123
tdef:45,ghi:678.]
1つなのに 2行表示されるのは、"\n" が改行だから。

(3)
"abc:123\n,tdef:45,ghi:678." を "," で分割すると、
"abc:123\n" と "tdef:45" と "ghi:678." の 3つに分割される。
この 3つを printf("[%s]\n", で表示すると、
[abc:123
]
[tdef:45]
[ghi:678.]
3つなのに 4行表示されるのは "\n" が改行だから。

以上の説明のどこが分かりませんか?

投稿2021/01/28 14:39

編集2021/01/30 02:38
kazuma-s

総合スコア8224

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

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

carnage0216

2021/01/28 16:57

どうなるのでしょうか? すいません。
carnage0216

2021/01/28 18:54

結果は [abc def] [abc def] なりました。 ってことは const char* str = "abc:123\n,tdef:45,ghi:678.";とした場合、printf("[%s]\n",の \nにより改行されるが、 \tは文字列にないのに結果が [abc:123 ,tdef:45,ghi:678.] なのは文字列に\tがないは、printf("[%s]\n",の \nにより改行されるために\nの部分で改行され、 [abc:123 ,tdef:45,ghi:678.] となったのですね! ですが、 strcpy(buf, str); puts("-- \"\n\" --"); p = strtok(buf, "\n"); while (p) { printf("[%s]\n", p); p = strtok(NULL, "\n"); } strcpy(buf, str); puts("-- \"\t\" --"); p = strtok(buf, "\t"); while (p) { printf("[%s]\n", p); p = strtok(NULL, "\t"); } strcpy(buf, str); puts("-- \",\" --"); p = strtok(buf, ","); while (p) { printf("[%s]\n", p); p = strtok(NULL, ","); } strcpy(buf, str); puts("-- \",\t\n\" --"); p = strtok(buf, ",\t\n"); while (p) { printf("[%s]\n", p); p = strtok(NULL, ",."); } が -- "\n" -- [abc:123] [,tdef:45,ghi:678.] -- " " -- [abc:123 ,tdef:45,ghi:678.] -- "," -- [abc:123 ] [tdef:45] [ghi:678.] -- ",\t\n" -- [abc:123] [tdef:45] [ghi:678] となる過程の処理と理由がさっぱりわかりません。 どうかわかりやすく教えて頂けないでしょうか。
carnage0216

2021/01/28 18:56

どの変数に何が代入され、どのように値が移動するかを詳しく知りたいです。
kazuma-s

2021/01/29 05:42 編集

Visual Studio を使っていますよね。 見たい変数が変化する行にブレークポイントを置いて、デバッグ実行を開始し、 そこで値を見てください。ステップ実行で、値の変化を見ることもできます。
carnage0216

2021/01/29 19:31

二つ目の出力について、なぜ [abc:123] ,tdef:45,ghi:678.] ではなく -- " " -- [abc:123 ,tdef:45,ghi:678.] となるのか。 また 3ッつ目の出力が [abc:123 ] [tdef:45] [ghi:678.] と [abc:123 ] の形になるのかさっぱりわかりません。 どうか教えてください。
carnage0216

2021/01/29 19:54

二つ目に関しては\t により]が消えて [abc:123 ,tdef:45,ghi:678.] となるためでしょうか?
episteme

2021/01/30 05:01

↑ ちがいます printf("[%s]\n], p); に対し p = "abc:123\n,tdef:45,ghi:678." だから [abc:123 ,tdef:45,ghi:678.] と出力されています。 '\n' は改行なんだから。
kazuma-s

2021/01/31 16:21

回答の「以上の説明のどこが分かりませんか?」に答えてください。
guest

0

\n という文字は改行を表します
\t は、タブです


文字列に\tがあった場合に改行されるのではないですか?

これが間違っています。
\t では改行しません

投稿2021/01/28 12:01

編集2021/01/28 14:44
y_waiwai

総合スコア88038

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

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

carnage0216

2021/01/28 14:25

ありがとうございます。 タブとはなんですか?
y_waiwai

2021/01/28 14:29

キーボードの左側にTABってキーはありませんか
guest

0

なぜwhile (n < 100 && words[n])のように書けるのでしょうか?

"n が 100 より小さい" かつ "words[n] が 0(NULL)でない" 間繰り返す
ですが、どこが「なぜ」なのでしょうか。

投稿2021/01/28 12:36

episteme

総合スコア16612

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

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

carnage0216

2021/01/28 14:25

ありがとうございます。 あの質問1についても回答して頂けないでしょうか?
episteme

2021/01/28 15:59 編集

> ありがとうございます。 "どこが「なぜ」なのでしょうか" に答えてもらえますか? while (n < 100 && words[n] != NULL) なら、その「なぜ」は解消しますか? # 質問1はすでに回答ついてます。
carnage0216

2021/01/28 16:55

while (n < 100 && words[n] != NULL)の解読ができたため開場しました。 すいません、質問1の回答はどこに書いてあるのでしょうか?
episteme

2021/01/28 21:40

> 質問1の回答はどこに書いてあるのでしょうか? 他の2つの回答と同じです。
episteme

2021/01/28 23:00

> while (n < 100 && words[n] != NULL)の解読ができたため開場しました。 これ↑なら理解できるって? > while (p) { printf("[%s]\n", p); p = strtok(NULL, ",."); } こんな↑コード書いてるやん。なら理解"できていた"はず。 わけがわからん...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問