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

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

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

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

Q&A

解決済

3回答

422閲覧

scanfを同じchar配列に2度用いたときの動作について

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2020/08/05 14:57

背景

scanfを使っていて、その動作に疑問を持ったので質問させていただきました。


コード

#include <stdio.h> int main(void){ char test[100]; scanf("%s",test); printf("%s",&test); scanf("%s",test); printf("%s",&test); }

疑問に思ったこと

最初のscanfで、testabcdefghiという文字列を入力した後に、
次のscanftestzzzzzという文字列を入力すると、最後のprintfにおいて・・・


1:zzzzzと表示される。

2:zzzzzfghiと表示される。


この1と2どちらが得られるのだろうと思い、実験したところ、

zzzzz

という文字列を得ました。

ということはこの結果から、

scanfは代入する配列を初期化してから代入する関数であり、

最初のscanfで入力された文字列は次のscanfで上書きされるのではなく、

次のscanfで一度配列がすべて初期されてから次の入力が代入されている。

という動作なのだろうと思ったのですが、この認識で間違いはないでしょうか?

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

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

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

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

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

guest

回答3

0

見た目はそう見えます。

が、scanf("%s",test); で渡されているのは文字列領域(test)の先頭位置だけあり、scanfはその大きさを知りません。
だから「一旦配列をすべて初期化」しようがないのです("すべて"がどれだけかわからないのですから)。

scanfは、入力文字を格納したあとその末尾に'\0'を書くことで文字列を終端しています。

投稿2020/08/05 15:10

episteme

総合スコア16612

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

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

yumetodo

2020/08/05 15:20

「scanfはその大きさを知りません。」というのは重要な指摘ですね。これがscanfを安全に使うことを難しくする要因の一つでもあります。
退会済みユーザー

退会済みユーザー

2020/08/05 15:35

ご回答ありがとうございます。scanfでバッファオーバーランが起こる要因の一つというわけですね。 理解できました。
guest

0

間違っています。

文字列の最後にNULという制御文字が追加されて保存されます。
出力時にはNULの直前までが出力されます。

メモリーの中は、
'z' 'z' 'z' 'z' 'z' NUL 'g' 'h' 'i 'となっています。

投稿2020/08/05 15:05

otn

総合スコア85901

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

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

0

ベストアンサー

いいえ、scanfによる文字列の書き込みは自動でNULL文字終端されます。つまりzzzzz\0ghiという状態になっていますが、そもそもの文字列の定義がNULL文字終端するバイト列、でしたからzzzzzと出力されるわけです。

投稿2020/08/05 15:03

yumetodo

総合スコア5852

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

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

退会済みユーザー

退会済みユーザー

2020/08/05 15:34

ご回答ありがとうございます。理解できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問