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

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

詳細はこちら
C

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

Q&A

解決済

3回答

12148閲覧

zsh: segmentation fault が出たのですが原因がわかりません

wwwwwa.k.awww

総合スコア4

C

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

0グッド

0クリップ

投稿2021/01/16 08:12

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct ufo {
char time[50];
char city[50];
char shape[50];
double lat;
double lon;
}UFO;

void printUfo(UFO ufo) {
printf("%s,%s,%s,%lf,%lf\n", ufo.time, ufo.city, ufo.shape, ufo.lat, ufo.lon);
}

int main() {
FILE *fp;
char line[256];
UFO ufo, list[80333];
int num=0;

if ((fp = fopen("ufo_sighting_data.csv", "r")) == NULL) { printf("file open error!\n"); exit(EXIT_FAILURE); } while (fgets(line, 256, fp) != NULL) { strcpy(ufo.time, strtok(line, ",\n")); strcpy(ufo.city, strtok(NULL, ",\n")); strcpy(ufo.shape, strtok(NULL, ",\n")); ufo.lat = atof(strtok(NULL, ",\n")); ufo.lon = atof(strtok(NULL, ",\n")); list[num] = ufo; num++; } fclose(fp); for (int i=0; i<num; i++) { printUfo(list[i]); } return 0;

}

コード

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

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

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

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

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

tatsu99

2021/01/16 08:30

インデントがずれてますね。 ```ここに言語を入力 コード ``` が表示されていれば ```① ② ``` ①の個所にCと入力し ②の個所にあなたのソースを貼り付けます。 つまり、以下のようにします。 ```C あなたのソースをはりつけたもの ``` そうすると、きれいに、インデントがそろいます。 もし、 ```ここに言語を入力 コード ``` がなければ <code>をクリックしてください。 ```ここに言語を入力 コード ``` が表示されます。
tatsu99

2021/01/16 08:33

ufo_sighting_data.csvの内容を提示してください。(行数が多いなら、10程度でも構いません) 又、それは、およそ何行ありますか。
wwwwwa.k.awww

2021/01/16 08:41

9/9/1995 22:50,silverdale,,47.6447222,-122.6936111 9/9/1996 05:30,savannah,disk,32.0833333,-81.1 9/9/1996 08:30,san francisco,oval,37.775,-122.4183333 9/9/1997 16:00,las vegas,formation,36.175,-115.1363889 9/9/1997 21:30,roseburg,light,43.2166667,-123.3405556 9/9/1998 01:25,tomah,cylinder,43.9786111,-90.5038889 9/9/1999 00:40,renton,light,47.4830556,-122.2158333 9/9/1999 05:00,los altos,circle,37.3852778,-122.1130556 9/9/1999 12:35,shasta/sand flat,fireball,40.650984,-122.363897 9/9/1999 19:00,marathon,disk,24.7133333,-81.0905556 9/9/1999 20:45,charlottetown (canada),disk,46.233333,-63.133333 9/9/1999 22:00,bothell,other,47.7625,-122.2041667 9/9/1999 22:00,mount shasta,,41.31,-122.3094444 9/9/1999 22:00,santa cruz,other,36.9741667,-122.0297222 9/9/1999 22:00,shasta/sand flat,disk,40.650984,-122.363897 80332行あります。
guest

回答3

0

ベストアンサー

原因は2つあります。
1つ目は、list[80333]が大きすぎるためです。これの解決方法は、kazuma-sさんが提示しています。
もう1つは、データの1行目のように
9/9/1995 22:50,silverdale,,47.6447222,-122.6936111
のような,,のデータがあることが原因です。
,,の中にはデータがないので、strtokはNULLを返します。
従って、strcpy又はatofでセグメンテーションフォールトになります。
対策としては
1案:,,のデータを修正する。(必ずデータを埋める。)
2案:,,があることを前提にソースを修正する。

とりあえず、2案を採用するとして、
,,のデータの場合、文字列なら"",数値なら0.0をセットするようにしました。
確認は、提示されたデータで行いました。80333行のデータでは行っていません。

下記が修正後のソースです。

C

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4typedef struct ufo { 5 char time[50]; 6 char city[50]; 7 char shape[50]; 8 double lat; 9 double lon; 10} UFO; 11UFO list[80333]; 12void printUfo(UFO ufo) 13{ 14 printf("%s,%s,%s,%lf,%lf\n", ufo.time, ufo.city, ufo.shape, ufo.lat, 15 ufo.lon); 16} 17 18int main() 19{ 20 FILE *fp; 21 char line[256]; 22 UFO ufo; 23 int num = 0; 24 char *p; 25 if ((fp = fopen("ufo_sighting_data.csv", "r")) == NULL) { 26 printf("file open error!\n"); 27 exit(EXIT_FAILURE); 28 } 29 30 while (fgets(line, 256, fp) != NULL) { 31 p = strtok(line, ",\n"); 32 if (p==NULL){ 33 strcpy(ufo.time, ""); 34 }else{ 35 strcpy(ufo.time, p); 36 } 37 p = strtok(NULL, ",\n"); 38 if (p==NULL){ 39 strcpy(ufo.city, ""); 40 }else{ 41 strcpy(ufo.city, p); 42 } 43 p = strtok(NULL, ",\n"); 44 if (p==NULL){ 45 strcpy(ufo.shape,""); 46 }else{ 47 strcpy(ufo.shape, p); 48 } 49 p = strtok(NULL, ",\n"); 50 if (p==NULL){ 51 ufo.lat = 0.0; 52 }else{ 53 ufo.lat = atof(p); 54 } 55 p = strtok(NULL, ",\n"); 56 if (p==NULL){ 57 ufo.lon = 0.0; 58 }else{ 59 ufo.lon = atof(p); 60 } 61 list[num] = ufo; 62 63 num++; 64 } 65 fclose(fp); 66 67 for (int i = 0; i < num; i++) { 68 printUfo(list[i]); 69 } 70 71 return 0; 72} 73

投稿2021/01/16 09:53

編集2021/01/16 09:55
tatsu99

総合スコア5493

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

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

wwwwwa.k.awww

2021/01/16 11:13

ありがとうございます。解決しました!
guest

0

sizeof(UFO) は 168 なので、sizeof(list) は 13495933 です。
12メガバイト以上になります。
Linux を使っているのなら、ulimit -a または ulimit -s でスタックサイズを
調べてみてください。8192kbytes になっていませんか?

static UFO list[80333]; のように静的にメモリを確保してみてください。

投稿2021/01/16 09:08

kazuma-s

総合スコア8224

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

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

wwwwwa.k.awww

2021/01/16 11:15

ありがとうございます。参考になりました。
guest

0

UFO ufo, list[80333];

ローカル変数は一般的にスタックに取られますんで、あんまし大きいサイズの変数を定義するとスタックを食いつぶしてエラーとなります。
グローバル変数にしてみては。

投稿2021/01/16 08:19

y_waiwai

総合スコア88038

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

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

wwwwwa.k.awww

2021/01/16 08:30

試してみましたが、同じエラーが出ました。
y_waiwai

2021/01/16 08:34

ならあとは、strtokのところでNULLが帰ってませんか。 C言語のコードを書くなら、デバッグできる環境を整えましょう。 Eclipseや、WindowsならVisualStudioなど。 コードの任意の場所で実行を止め、変数のナカミを見ることができます。そこから1行づつ実行して、コードの流れを見れるようになります そうすれば、アテズッポでコードを書かなくて済むようになります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問