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

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

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

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

Q&A

解決済

2回答

1898閲覧

複数のファイル読み込みについて

Gurt

総合スコア14

C

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

0グッド

0クリップ

投稿2020/07/31 01:52

前提・実現したいこと

乱数を格納したdatファイルを読み込みソートするプログラムを実装しようとしています。
また、上記datファイルを中身の総数を変えて複数読み込みたいと考えています。
そこでdatファイルのファイル名を格納したテキストファイルを作り、テキストファイルを読み込みdatファイルのファイル名を配列に格納してから、ループでそれぞれのdatファイルを読み込んでいきたいと考えています。
datファイルは総数が10000~50000の5つを想定しています。
エラー内容としてはセグメンテーションフォルト11となっています。

発生している問題・エラーメッセージ

Segmentation fault: 11

該当のソースコード

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <sys/time.h> 4 5#define N 50000 6#define MAX_DAT_FILE 5 7 8void StraightSelectionSort(int x[], int n){ 9 int k, temp; 10 for(int i = 0; i < n - 1; i++){ 11 k = i; 12 for(int j = i + 1; j < n; j++){ 13 if(x[k] > x[j]){ 14 k = j; 15 } 16 } 17 temp = x[i]; 18 x[i] = x[k]; 19 x[k] = temp; 20 } 21} 22 23void BubbleSort(int x[], int n){ 24 int temp; 25 for(int i = 0; i < n - 1; i++){ 26 for(int j = n - 1; j > i; j--){ 27 if(x[j - 1] > x[j]){ 28 temp = x[j]; 29 x[j] = x[j - 1]; 30 x[j - 1] = temp; 31 } 32 } 33 } 34} 35 36void QuickSort(int x[], int left, int right){ 37 int i, j, pivot, temp; 38 39 i = left; 40 j = right; 41 42 pivot = x[(left + right) / 2]; 43 while (1) { 44 while (x[i] < pivot) 45 i++; 46 while (pivot < x[j]) 47 j--; 48 if (i >= j) 49 break; 50 51 temp = x[i]; 52 x[i] = x[j]; 53 x[j] = temp; 54 i++; 55 j--; 56 } 57 58 if (left < i - 1) 59 QuickSort(x, left, i - 1); 60 if (j + 1 < right) 61 QuickSort(x, j + 1, right); 62} 63 64void ShowData(int sss[], int bs[], int qs[], int n){ 65 unsigned int sec; 66 int nsec; 67 double d_sec; 68 struct timespec start_time, end_time; 69 70 clock_gettime(CLOCK_REALTIME, &start_time); 71 StraightSelectionSort(sss, n); 72 clock_gettime(CLOCK_REALTIME, &end_time); 73 sec = end_time.tv_sec - start_time.tv_sec; 74 nsec = end_time.tv_nsec - start_time.tv_nsec; 75 d_sec = (double)sec + (double)nsec / (1000 * 1000 * 1000); 76 printf("ssSort : %f\n", d_sec); 77 78 clock_gettime(CLOCK_REALTIME, &start_time); 79 BubbleSort(bs, n); 80 clock_gettime(CLOCK_REALTIME, &end_time); 81 sec = end_time.tv_sec - start_time.tv_sec; 82 nsec = end_time.tv_nsec - start_time.tv_nsec; 83 d_sec = (double)sec + (double)nsec / (1000 * 1000 * 1000); 84 printf("bSort : %f\n", d_sec); 85 86 clock_gettime(CLOCK_REALTIME, &start_time); 87 QuickSort(qs, 0, n - 1); 88 clock_gettime(CLOCK_REALTIME, &end_time); 89 sec = end_time.tv_sec - start_time.tv_sec; 90 nsec = end_time.tv_nsec - start_time.tv_nsec; 91 d_sec = (double)sec + (double)nsec / (1000 * 1000 * 1000); 92 printf("qSort : %f\n", d_sec); 93} 94 95int main(){ char dat[MAX_DAT_FILE]; 96 FILE *inputFile, *datFile; 97 98 if((inputFile = fopen("dat.txt", "r")) == NULL) { 99 printf("cannot open\n"); 100 exit(1); 101 } 102 for(int i = 0; i < MAX_DAT_FILE; i++){ 103 int random[N], j = 0; 104 fscanf(inputFile, "%s", &dat[i]); 105 // dat[i]だとエラーが出てしまうので&をつけてみましたが理由はよくわかっていません 106 if((datFile = fopen(&dat[i], "r")) == NULL) { 107 printf("cannot open\n"); 108 exit(1); 109 } 110 while(fscanf(datFile, "%d", &random[j]) != EOF){ 111 j++; 112 } 113 fclose(datFile); 114 115 printf("%s~~~~~~~~~~\n", dat[i]); 116 ShowData(random, random, random, j); 117 } 118 fclose(inputFile); 119 120}

試したこと

ファイル読み込みをテキストファイルからではなくループさせずに個別に読み込んだプログラムは以下の通りです。
下記のプログラムを問題のプログラムにする際に一箇所エラーが出てしまいエラー内容はよくわかりませんでしたがとりあえずエラー文通り直してみました。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <sys/time.h> 4 5#define N 50000 6 7void StraightSelectionSort(int x[], int n){ 8 int k, temp; 9 for(int i = 0; i < n - 1; i++){ 10 k = i; 11 for(int j = i + 1; j < n; j++){ 12 if(x[k] > x[j]){ 13 k = j; 14 } 15 } 16 temp = x[i]; 17 x[i] = x[k]; 18 x[k] = temp; 19 } 20} 21 22void BubbleSort(int x[], int n){ 23 int temp; 24 for(int i = 0; i < n - 1; i++){ 25 for(int j = n - 1; j > i; j--){ 26 if(x[j - 1] > x[j]){ 27 temp = x[j]; 28 x[j] = x[j - 1]; 29 x[j - 1] = temp; 30 } 31 } 32 } 33} 34 35void QuickSort(int x[], int left, int right){ 36 int i, j, pivot, temp; 37 38 i = left; 39 j = right; 40 41 pivot = x[(left + right) / 2]; 42 while (1) { 43 while (x[i] < pivot) 44 i++; 45 while (pivot < x[j]) 46 j--; 47 if (i >= j) 48 break; 49 50 temp = x[i]; 51 x[i] = x[j]; 52 x[j] = temp; 53 i++; 54 j--; 55 } 56 57 if (left < i - 1) 58 QuickSort(x, left, i - 1); 59 if (j + 1 < right) 60 QuickSort(x, j + 1, right); 61} 62 63void ShowData(int sss[], int bs[], int qs[], int n){ 64 unsigned int sec; 65 int nsec; 66 double d_sec; 67 struct timespec start_time, end_time; 68 69 clock_gettime(CLOCK_REALTIME, &start_time); 70 StraightSelectionSort(sss, n); 71 clock_gettime(CLOCK_REALTIME, &end_time); 72 sec = end_time.tv_sec - start_time.tv_sec; 73 nsec = end_time.tv_nsec - start_time.tv_nsec; 74 d_sec = (double)sec + (double)nsec / (1000 * 1000 * 1000); 75 printf("ssSort : %f\n", d_sec); 76 77 clock_gettime(CLOCK_REALTIME, &start_time); 78 BubbleSort(bs, n); 79 clock_gettime(CLOCK_REALTIME, &end_time); 80 sec = end_time.tv_sec - start_time.tv_sec; 81 nsec = end_time.tv_nsec - start_time.tv_nsec; 82 d_sec = (double)sec + (double)nsec / (1000 * 1000 * 1000); 83 printf("bSort : %f\n", d_sec); 84 85 clock_gettime(CLOCK_REALTIME, &start_time); 86 QuickSort(qs, 0, n - 1); 87 clock_gettime(CLOCK_REALTIME, &end_time); 88 sec = end_time.tv_sec - start_time.tv_sec; 89 nsec = end_time.tv_nsec - start_time.tv_nsec; 90 d_sec = (double)sec + (double)nsec / (1000 * 1000 * 1000); 91 printf("qSort : %f\n", d_sec); 92} 93 94int main(){ 95 int random[N], i = 0; 96 FILE *inputFile; 97 98 if((inputFile = fopen("c06-10000.dat", "r")) == NULL) { 99 printf("cannot open\n"); 100 exit(1); 101 } 102 while(fscanf(inputFile, "%d", &random[i]) != EOF){ 103 i++; 104 } 105 fclose(inputFile); 106 107 printf("c06-10000.dat~~~~~~~~~~~~~~~~~~~~~\n"); 108 printf("%d\n", i); 109 ShowData(random, random, random, i); 110 111 i = 0; 112 if((inputFile = fopen("c06-20000.dat", "r")) == NULL) { 113 printf("cannot open\n"); 114 exit(1); 115 } 116 while(fscanf(inputFile, "%d", &random[i]) != EOF){ 117 i++; 118 } 119 fclose(inputFile); 120 121 printf("c06-20000.dat~~~~~~~~~~~~~~~~~~~~~\n"); 122 printf("%d\n", i); 123 ShowData(random, random, random, i); 124 125 i = 0; 126 if((inputFile = fopen("c06-30000.dat", "r")) == NULL) { 127 printf("cannot open\n"); 128 exit(1); 129 } 130 while(fscanf(inputFile, "%d", &random[i]) != EOF){ 131 i++; 132 } 133 fclose(inputFile); 134 135 printf("c06-30000.dat~~~~~~~~~~~~~~~~~~~~~\n"); 136 printf("%d\n", i); 137 ShowData(random, random, random, i); 138 139 i = 0; 140 if((inputFile = fopen("c06-40000.dat", "r")) == NULL) { 141 printf("cannot open\n"); 142 exit(1); 143 } 144 while(fscanf(inputFile, "%d", &random[i]) != EOF){ 145 i++; 146 } 147 fclose(inputFile); 148 149 printf("c06-40000.dat~~~~~~~~~~~~~~~~~~~~~\n"); 150 printf("%d\n", i); 151 ShowData(random, random, random, i); 152 153 i = 0; 154 if((inputFile = fopen("c06-50000.dat", "r")) == NULL) { 155 printf("cannot open\n"); 156 exit(1); 157 } 158 while(fscanf(inputFile, "%d", &random[i]) != EOF){ 159 i++; 160 } 161 fclose(inputFile); 162 163 printf("c06-50000.dat~~~~~~~~~~~~~~~~~~~~~\n"); 164 printf("%d\n", i); 165 ShowData(random, random, random, i); 166 167}

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

Penpen7

2020/07/31 02:11 編集

Segmentation fault: 11は配列外にアクセスするなど、メモリの触っちゃいけないところに触ると発生します。gdbなどのデバッガを使ってどこで落ちたか調べるといいと思います。
guest

回答2

0

今回のプログラムでは、後でデータファイル名を使っていないので、5つのデータファイル名を保持する必要はありません。ひとつだけchar filename[255]みたいなの(長さは適当に)を作って、それに現在読む必要のあるファイル名を順次いれていけばいい。
この場合のfscanfはfscanf(inputFile, "%s", filename);みたいな形になります。

もし、何らかの理由で、後でデータファイル名を利用するのであれば、char filenames[MAX_DATA_FILE][255]などとして複数のデータファイル名を保持する場所を用意し、fscanf(inputFile, "%s", filename[i]);のようにして読み込みます。

投稿2020/07/31 02:39

Daregada

総合スコア11990

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

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

Gurt

2020/07/31 03:02

回答ありがとうございます 今回は後者の方を実装することで問題を解決することができました。 ファイル数に固執するあまり、ファイル名のサイズを定義することを忘れていました。
guest

0

ベストアンサー

fscanf(inputFile, "%s", &dat[i]);

これ、5文字文の dat[] にファイル名を読み込んでいません?
それも、読み込む位置 &dat[i] を変えながら。

ファイルが5個有るのなら、文字列 5個 分の場所を用意しましょう。

投稿2020/07/31 02:14

nob.

総合スコア711

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

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

Gurt

2020/07/31 02:33

ありがとうございます。 datファイルの数ばかり考えていて文字数の存在を忘れていました。 char dat[MAX_DAT_FILE][20]で解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問