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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

9998閲覧

C言語 文字入力ができません

programming

総合スコア476

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2016/08/19 07:01

編集2016/08/20 01:47

C言語の初心者です。
Visual Studio 2015 Community を使って学習しています。
C言語の入門書を用いてサンプルプログラムを実行しています。
文字入力のサンプルプログラムを実行すると以下のようにエラーが出ます。
インターネットによると、「意図しないメモリ領域に書き込んだのだろう」ということがありましたが、見直してもよくわかりませんでした。

また、"paiza.io" にて scanf_sscanf にすると問題なく実行できます。

何が起きておりどのように対策をすればよいかを教えてください。

本のサンプルプログラムなので投稿してよいのか迷いましたが、
短いですし、基礎的なことだと思うので投稿しました。

0x0F30D0F1 (ucrtbased.dll) で例外がスローされました (C言語の学習用.exe 内): 0xC0000005: 場所 0x00121041 への書き込み中にアクセス違反が発生しました ハンドルされない例外が 0x0F30D0F1 (ucrtbased.dll) で発生しました(C言語の学習用.exe 内): 0xC0000005: 場所 0x00121041 への書き込み中にアクセス違反が発生しました。

以下がプログラムリストです。

C

1#include "stdafx.h" 2int main() 3{ 4 int num; 5 double dnum; 6 char ch0, ch1, ch2; 7 char str[81]; 8 9 printf("整数を入力:"); scanf_s("%d", &num); 10 printf("実数を入力:"); scanf_s("%lf", &dnum); 11 printf("英字1文字と改行入力:"); scanf_s("%c%c%c", &ch0, &ch1, &ch2); 12 printf("英文字列と改行入力:"); scanf_s("%s", str); 13 14 printf("[%d]です\n", num); 15 printf("[%f]です\n", dnum); 16 printf("[%c][%c][%c]\n", ch0, ch1, ch2); 17 printf("[%s]\n", str); 18 19 printf("プログラムを終了するには何かキーを押してください...\n"); 20 char x; 21 scanf_s("%c", &x); 22 return 0; 23}

追記

遅くなりましたが、この本の意図していることを正確にするため、本にある実行結果と説明を簡単に書きます。

整数を入力:100 実数を入力:3.14159 英字1文字と改行入力:A 英文字列と改行入力:XYZ [100]です [3.14159]です [ ][A][ ] [XYZ]

本では、説明として

1 0 0 改行 3 . 1 4 1 5 9 改行 A 改行 X Y Z 改行
↑P1______ ↑P2_________ ↑P3 ※(追記)矢印がずれていたので直しました。
となるから状態によっては前の scanf で読み取った改行が次に読み込まれてしまう

といった内容です。

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

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

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

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

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

guest

回答2

0

ベストアンサー

scanf_sの落とし穴

一度 str への入力でバッファサイズをつけて試してみてください。
###追記
とりあえずこれで動きました。

C

1#include <stdio.h> 2int main() 3{ 4 int num; 5 double dnum; 6 char ch0, ch1; 7 char str[81]; 8 9 printf("整数を入力:"); scanf_s("%d", &num); 10 printf("実数を入力:"); scanf_s("%lf", &dnum); 11 printf("英字1文字と改行入力:"); scanf_s("%*c%c%c", &ch0, 1, &ch1, 1); 12 printf("英文字列と改行入力:"); scanf_s("%s", str, sizeof(str)); 13 14 printf("[%d]です\n", num); 15 printf("[%f]です\n", dnum); 16 printf("[%c][%c]\n", ch0, ch1); 17 printf("[%s]\n", str); 18 19 printf("プログラムを終了するには何かキーを押してください...\n"); 20 char x; 21 scanf_s("%*c%c", &x); 22 return 0; 23}

投稿2016/08/19 07:11

編集2016/08/19 09:03
Zuishin

総合スコア28660

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

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

programming

2016/08/19 07:19

すみません... "バッファサイズをつけて" とは、どのようにするのでしょうか。 本当にすみません
Zuishin

2016/08/19 07:25

リンク先をご覧になりましたか?
programming

2016/08/19 07:33

すみません、見逃していました... printf("英文字列と改行入力:"); scanf_s("%s", str);    を、 printf("英文字列と改行入力:"); scanf_s("%s", str,81);   のように変えました。 結果はエラーが返ってきて、以下のようになりました。 0x0FD6D0F1 (ucrtbased.dll) で例外がスローされました (C言語の学習用.exe 内): 0xC0000005: 場所 0x00291041 への書き込み中にアクセス違反が発生しました ハンドルされない例外が 0x0FD6D0F1 (ucrtbased.dll) で発生しました(C言語の学習用.exe 内): 0xC0000005: 場所 0x00291041 への書き込み中にアクセス違反が発生しました。
Zuishin

2016/08/19 08:31

追記しました。%*C は入力バッファに溜まった改行コードを読み飛ばしています。
Zuishin

2016/08/19 09:02

すみません。たまたまだったようです。修正しました。 改行コードは 13 と 10 の二つを想定しているようですが、それではうまくいかないので一つ減らしました。
Zuishin

2016/08/19 09:08

scanf_s は文字列の際もそうですが、単一文字の場合にもサイズが必要だそうです。ですので、引数で渡された &ch1 がバッファサイズとみなされ、その値によっては大きなバッファが与えられたと見て、&ch0 の位置に改行なども格納しようとしていたようです。
programming

2016/08/19 09:42

遅くなり申し訳ありませんでした。 ありがとうございます。無事に実行できました。 改行コードを一つ減らしたというのは "printf("英字1文字と改行入力:"); scanf_s("%*c%c%c", &ch0, 1, &ch1, 1);" の "&ch0","&ch1" のそれぞれの後にある "1" で数を限定したということでよろしいのでしょうか。 また、今更とても申し訳ないのですが、本にある実行結果を載せます。 できれば ch は3個使って改行も表したいと思っています。 と思いまして、示してくださったソースコードを ch を3個使って書き換えてみましたところ、思ったように動きました。 #include "stdafx.h" #include <stdio.h> int main() { int num; double dnum; char ch0, ch1, ch2; char str[81]; printf("整数を入力:"); scanf_s("%d", &num); printf("実数を入力:"); scanf_s("%lf", &dnum); printf("英字1文字と改行入力:"); scanf_s("%c%c%c", &ch0, 1, &ch1, 1, &ch2, 1); printf("英文字列と改行入力:"); scanf_s("%s", str, sizeof(str)); printf("[%d]です\n", num); printf("[%f]です\n", dnum); printf("[%c][%c][%c]\n", ch0, ch1, ch2); printf("[%s]\n", str); printf("プログラムを終了するには何かキーを押してください...\n"); char x; scanf_s("%*c%c", &x); return 0; } 多くのご教示ありがとうございました。
programming

2016/08/19 09:47

できれば、どなたかお答えしていただけるとありがたいのですが、 結局これは何が原因だったのでしょうか。 (私の中では scanf と scanf_s の違いが原因であったと思うのですが、詳しいことはわかりません。) 今後の参考にしたいです。 よろしくお願いします。
Zuishin

2016/08/19 09:48

C 言語は 20 年くらい前はよく使っていましたが、最近はほとんど使わないので、scanf_s などの新しい関数や文法にうとくなっています。こちらこそ勉強させていただきました。
Zuishin

2016/08/19 09:50

先ほども書きましたが、やはりバッファサイズを指定しなかったために、&ch1 がバッファサイズと誤認されていたのが原因と思います。
programming

2016/08/19 09:58

ありがとうございます。 よくわかりました。 エラーを起こしたら、リファレンスもきちんと読むことが大切なのですね。
otn

2016/08/19 14:07

> エラーを起こしたら、リファレンスもきちんと読むことが大切なのですね。 「初めて使う関数は、リファレンスをきちんと読む」 にしましょう。 泥縄方式だと、エラーが出ずに処理結果が不正というのを防げません。
programming

2016/08/20 01:41

そうですね... MSDNのリファレンスは難しいですが、読解できるよう努めます。 他にもC言語はいろいろと情報が多いので助かります。 アドバイスありがとうございます。
guest

0

C

1scanf_s(%s,str,81);

というように文字列サイズを指定してやると、終端文字が自動付加されると思います。
もとのエラーは終端文字が無くて発生したのではないかと推察されます。

----- 追記 ---------
C関数リファレンス
はどうでしょう?

----- 追記 ---------

C

1scanf_s(%80s,str,81);

とやればいいように思われます。(上記リンク)

投稿2016/08/19 07:30

編集2016/08/19 08:22
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

programming

2016/08/19 07:38

試したみましたが、やはりエラーが返ってきました。 Zuishinさんへのコメントの通りです。
退会済みユーザー

退会済みユーザー

2016/08/19 07:57

そういえばscanfでも自動的に終端は入れるようになってるんでした。失礼しました。
programming

2016/08/19 08:15

>C関数リファレンス はどうでしょう? 初心者ですみません... 何度か見ているのですが、MSDNの関数リファレンスは難しすぎます。 そもそも構文が読み取れません... ただ、とても参考になるのでご紹介ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問