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

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

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

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

Q&A

解決済

2回答

8894閲覧

C言語のscanf()でヌルが補完されないのですが

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2014/12/01 05:56

linux mint 16でC言語のプログラミングをしたいのですが、

lang

1#include <stdio.h> 2 3int main(){ 4 char name[10]; 5 printf("tell me your name.\n"); 6 scanf("%s\n", name); 7 printf("your name is %s\n", name); 8}

というプログラムを作り自分の名前を入力するのですが、自分の名前を入力した後にreturnを押してもプログラムが次に進まずに\0を自分で入力する必要があるみたいです。

scanf()は自動で\0を補完してくれると思うのですが、なぜこのプログラムはそうならないのでしょうか?

ちなみにsudo apt-get install libc6-devで環境を整えました。

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

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

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

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

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

guest

回答2

0

\0を自分で入力する必要があるみたいです。

まずこれは勘違いです。文字列末尾の\0は自動的に入ります。

scanf("%s\n",name); に対しては、「空白でない文字が1文字以上」「空白文字(空白タブ改行など)が1文字以上」「空白でない文字」が入力されたときにリターンしてきます。
例えば、

lang

1taro 2jiro

とか

lang

1taro jiro

とか入力すると、name に taro が入ります。

man scanf を見るとわかりますが、これはフォーマット文字列の"\n"が「空白文字(空白タブ改行など)が1文字以上」にマッチするためです。空白文字列の終わりを知るために、非空白文字が入力される必要があるようです。
で、その非空白文字は今回のscanfでは取り込まれないので、次のscanfで取り込まれる対象になります。
上記で言うと、次にscanf("%s", name);すると入力待ちにならずにnameに jiro がはいります。

このようにscanfは使いこなすのが非常に難しいので、初心者は使わない方が良いです。そういう説明がなくてscanfが出てくる入門書も捨てた方が良いです。

単に文字列を入力するには、fgetsを使います。また、数値などをフォーマット文字列を使って解釈して入力したい場合は、fgetsしてその文字列に対してsscanfを使います。fgetsだとEnterを押すことと関数の実行が一致するのでわかりやすいです。

投稿2014/12/02 06:24

otn

総合スコア84505

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

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

退会済みユーザー

退会済みユーザー

2014/12/03 07:53

詳しい説明ありがとうございます fgetsも試してみようと思います
guest

0

ベストアンサー

再現検証のもと、回答を修正します。
手元の環境(Centos6.5 gcc4.4.7 )にてreturnを入力してもscanfが終了しない事象を再現できました。
そして引数フォーマットの\nを消したところ、returnで終了する動作となることを確認しました。

lang

1scanf("%s", name);

フォーマットに\nを含めた際の振る舞いについては、マニュアルを見ましたが確認できませんでした。

<修正前>

nullは補完されていて、意図通りに表示されない状況かも知れません。手元に環境が無いのですが、改行コード(\n)を入れてみたらどうでしょうか。

lang

1  printf("tell me your name.\n"); 2 scanf("%s\n", name); 3 printf("your name is %s\n", name);

scanfには不要かも知れません。(参考サイト
あと、nameの配列サイズが気になります。全角の場合はSJISで1文字2バイト、UTFなら3バイトになるケースも有ります。

投稿2014/12/01 06:53

BlueMoon

総合スコア1339

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

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

退会済みユーザー

退会済みユーザー

2014/12/01 08:45

改行コード忘れはミスでした。すいません nameは半角英数で六文字で試しましたが、ヌル文字が補完されませんでした
BlueMoon

2014/12/01 08:55

ではscanfの\nを取ってみてはどうでしょうか。
BlueMoon

2014/12/01 09:09

仮想環境で再現してみました。scanfに\nを入れるとご質問の事象が再現しました。 外すことで意図の動作となりました。
退会済みユーザー

退会済みユーザー

2014/12/01 11:37

教えていただいた通りにやったら無事に動きました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問