![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
構造体のプログラミング...練習です。
#include <stdio.h>
int main ( void )
{
int i;
struct rool{
char name[20];
float height;
char bloodType;
}date[128];
for(i = 0;; i++)
{
printf("%d人目のデータ:", i + 1 );
scanf("%s %f %c",date[i].name[i], &date[i].height, &date[i].bloodType);
if((date[i].name[0] == '0') && (date[i].height == 0) && (date[i].bloodT\
ype == 0))
{
break;
}
}
printf("名前 体重 歳\n");
for(i = 0; (date[i].name[0] == '0') && (date[i].height == 0) && (date[i].bl\
oodType == 0); i++)
{
printf("%s, %10s, %10s\n",date[i].name[i], date[i].height, date[i].bloodTy\
pe);
}
return 0;
}
構造体を使ったプログラミングです。
名前と体重、歳を入力して0 0 0が入力されたら、今まで入力したものを表示する。というものです。
セグメントエラーが出て困っています。
入力をしてエンターキーを押すと、何人目のデータ:何人目のデータ:~と言うふうにでて、セグメントエラーで止まります。
よろしくお願いします。
No.3ベストアンサー
- 回答日時:
scanfは、いろいろと面倒なことの多い関数です。
おそらく
scanf失敗:ファイルポインタはそのまま
→終了チェックにはひっからない
初期化していない構造体の中身は不定で、なにが入っているかわからない。
全部0で初期化されていたとしても、0と'0'とは違う。
→ i++してループ続行
→さっきエラーになったところか読み出し
→ずれていたり、最初から変化してなかったりで正確に読めない
→終了チェックにはひっからない
→ i++してループ続行
....
→ i >= 128 になる
→ 宣言より data[128]以上は保証されない
→セグメントエラー
という流れだと思われます。
・fgets等で1行読み込む→sscanfや別の方法で解析する
・scanfのエラーチェックと、エラーの際の復帰処理をきちんと行う
といった対策が必要です。
あと気付いたことは
> 名前と体重、歳を入力
とあるのに、構造体のメンバは
> float height;
> char bloodType;
と、身長と血液型を連想させるものになっている。
文法的にはあっているけど、作法としては問題。
また、歳を扱うのなら、charの範囲(普通は-128~127)を越えることはほぼ無いけれど、intを使うのが自然。
> scanf("%s %f %c",date[i].name[i], &date[i].height, &date[i].bloodType);
%sと%fの間に「全角スペース」が入っていますが、これは、ここへの打ち込み間違いでしょうか?
もし、プログラムをコピペしたものだとしたら、入力時には、名前と体重との間に「全角スペース」が無いとこのscanfは成功しません。
名前を読み込んだところで、読み込みポインタは体重の前で止ってしまい、次回のscanfはそこからに
→名前は空文字列、体重の前に「全角スペース」がないのでエラー、読み込みポインタは体重の前
→名前は空文字列、体重の前に「全角スペース」がないのでエラー、読み込みポインタは体重の前
....
と無限ループになります。
また、%cは文字を読み込むものです。
歳に25を入れたとして、%cで読み込まれるのは '2' だけであって、 通常は '2' != 2 です。
'5'はバッファにそのまま残り、次の入力はここからになります。
整数を読み込むなら 変換文字は d です。
> if((date[i].name[0] == '0')
これだと、 0taro氏も条件に合致します。
> (date[i].bloodType == 0))
現在のままだと、 歳に0を入れた場合は、 bloodType = '0' であって 0ではありません。
> printf("%s, %10s, %10s\n",date[i].name[i], date[i].height, date[i].bloodType)
2番目は %sに対して height、つまりfloatを指定しています。
floatをムリヤリchar *だと思いこんで、まったく意味のないアドレスから文字列として出力しようとします。
3番目は %sに対して bloodType、つまりcharを指定しています。
charをムリヤリchar *だと思いこんで、まったく意味のないアドレスから文字列として出力しようとします。
charは1文字を表現できる数値であって、文字列ではありません。
No.4
- 回答日時:
エラーになるのは
scanf("%s %f %c",date[i].name[i], &date[i].height, &date[i].bloodType);
の引数date[i].name[i]が
date[i].name または &date[i].name[0]
になっていないからです。
あとの変なところは他の回答者の指摘どうりです。
No.2
- 回答日時:
>scanf("%s %f %c",date[i].name[i],
i は「何人目のデータか」を表わす変数ですよね。
name[i] の i は、どういう意味ですか?
>for(i = 0; (date[i].name[0] == '0') && (date[i].height == 0) && (date[i].bl\
oodType == 0); i++)
入力がうまくいったとしても、これだと何も出力しないのではありませんか?
for文の継続条件を見直す必要があると思います。
No.1
- 回答日時:
データを手入力するときにscanf()をループで複数回呼ぶとうまくいかないようですね。
fgets()で1行ごと入力してからsscanf()を使うのがいいと思います。
(それと、載せられたプログラムは表示部のforループの継続条件の論理が逆ですよ。)
簡略化したサンプルプログラムを作ってみました。
これは整数を1行に1個ずつ入力して配列に格納し、0が入力されたら入力を終わって、
配列の中身を表示する、というものです。参考にしてください。
#define LINE_SIZE 1024
#include <stdio.h>
int main(void)
{
char line[LINE_SIZE + 1];
int numbers[256];
int count;
int i;
count = 0;
for (;;) {
int r;
int n;
if (fgets(line, LINE_SIZE, stdin) == NULL) {
break;
}
line[LINE_SIZE] = '\0';
r = sscanf(line, "%d", &n);
if (r != 1) {
break;
}
if (n == 0) {
break;
}
numbers[count] = n;
count++;
}
for (i=0; i<count; i++) {
printf("%d: %d\n", i, numbers[i]);
}
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- JavaScript gasについて 1 2022/05/31 21:51
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- PHP プログラムコードを入力する場合改行してもいいですか? 2 2022/10/02 16:05
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- PHP 共通の処理をまとめる方法がわからないのでアドバイスお願いします。 1 2022/12/19 20:20
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バッチファイルで以下のような...
-
逆コンパイルと逆アセンブルの...
-
C言語って古いですか?
-
Windows Formアプリからコンソ...
-
私は
-
Notepad++の関数リスト表示の変...
-
パイソン。If elseの挙動につい...
-
ホワイトハッカーを目指そうか...
-
大量のデータを読み込んで表示...
-
これて逆じゃないですか?
-
C言語について。
-
コンソールアプリを作成するの...
-
0 == False はいいけど
-
プログラム言語について c言語...
-
【C言語】全角文字の配列を、全...
-
C言語初心者 ポインタについて...
-
あんまり考えたくないけど
-
CPUが16bitでも32bitOSでコンパ...
-
VisualStudio2022でC言語プログ...
-
C言語初心者 構造体 課題について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
postgresのカレンダーについて
-
PHP+MySQLで月ごとの数量を表...
-
【PL/SQL】DATE型の時刻の表示...
-
配列の重複を削除後、削除分の...
-
掲載日と更新日の管理の仕方
-
MySQLのUPDATE文でサブクエリ
-
続・指定した時間にPHPプログラ...
-
DB登録に関する日付の認識
-
EXCELマクロのSQL文での引用符...
-
日替わりメッセージを表示させ...
-
PHPでMySQL内のデータの合計値...
-
構造体のプログラミング......
-
JavaScriptの条件文の応用
-
JOINを使った文で、date > now();
-
preg_replace, ereg_replace
-
UNIXの時間はどう変更すれ...
-
MySQL + PHP 同じテーブル内で...
-
複数のカテゴリを選択した上でL...
-
Strict Standards: date() ...
-
質問:年月日の表示方法について
おすすめ情報