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

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

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

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

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

4回答

3910閲覧

C言語の3次元配列(文字列)

s_clalis

総合スコア17

C

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

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2018/05/29 09:52

編集2018/05/31 00:15

前提・実現したいこと

 ファイルから1行ずつデータをchar型配列に読み込み、int型に変換してから配列の平均を除去・正規化し内積を計算して相関係数を算出するプログラムを作る。
勉強のためにポインタと動的確保を使ってみることとする。

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

 4つのファイル別のデータを各配列に入れて利用したいのですが、想定したとおりに構造ができず困っています。(data_raw[]に各4ファイルの階層がありその中のdata_raw[][]に数値が一行づつ入っている構造)
今のところファイルの先頭の行が全てのdata_raw[]に入ってしまいます。これをdata_raw[][]に入れたいです。

 他の方法を選ぶべきでしたらご教授いただけると幸いです。

該当のソースコード

C

1#include "targetver.h" 2 3#define _CRT_SECURE_NO_WARNINGS 4#define F_C 4 //file_count 5#define D_S 85 //data_size 6 7#include <math.h> 8#include <stdio.h> 9#include <stdlib.h> 10#include <tchar.h> 11 12 13double in_pro(double v1[], double v2[], int size); 14 15int main(void) 16{ 17 FILE *fp; 18 int n = 0; 19 int sum[F_C], data[F_C][D_S]; 20 char *filename[F_C] = { "rdata1.txt", "rdata2.txt", "rdata3.txt", "rdata4.txt" }; 21 char ***data_raw; 22 double u1[] = { 1, 0, 0 }; 23 double u2[] = { 0, sqrt(3) / 2, 0.5 }; 24 double u3[] = { 0, 0.5, -sqrt(3) / 2 }; 25 double xn[] = { 2, -1, 1 }; 26 double a[3]; 27 double x[6]; 28 double g[3]; 29 30 data_raw = (char ***)malloc(sizeof(char **) * F_C); 31 for (size_t i = 0; i < F_C; i++) 32 { 33 data_raw[i] = (char **)malloc(sizeof(char *) * D_S); 34 for (size_t j = 0; j < D_S; j++) 35 { 36 data_raw[i][j] = (char *)malloc(sizeof(char) * 0x10); 37 } 38 } 39 40 for (size_t i = 0; i < F_C; i++) 41 { 42 if ((fp = fopen(filename[i], "r")) == NULL) 43 { 44 fprintf(stderr, "Failed to opening %s.\n", filename[i]); 45 exit(EXIT_FAILURE); 46 } 47 48 while (fgets(data_raw[i][n], 0x10, fp) != NULL) 49 { 50 n++; 51 //puts(data_raw[i][n]); 52 } 53 n = 0; 54 } 55 56 for (size_t i = 0; i < F_C; i++) 57 { 58 for (size_t j = 0; j < D_S; j++) 59 { 60 data[i][j] = atoi(data_raw[i][j]); 61 sum[i] += data[i][j]; 62 } 63 sum[i] /= D_S; 64 printf("%d\n", sum[i]); 65 } 66 67 68 printf("***\tH30\tDSP1-3\t23\t***\n\n"); 69 70 printf("u1:[%f, %f, %f]\n", u1[0], u1[1], u1[2]); 71 printf("u2:[%f, %f, %f]\n", u2[0], u2[1], u2[2]); 72 printf("u3:[%f, %f, %f]\n \n", u3[0], u3[1], u3[2]); 73 74 x[0] = in_pro(u1, u1, 3); 75 x[1] = in_pro(u1, u2, 3); 76 x[2] = in_pro(u1, u3, 3); 77 x[3] = in_pro(u2, u2, 3); 78 x[4] = in_pro(u2, u3, 3); 79 x[5] = in_pro(u3, u3, 3); 80 81 printf("u1 * u1 : %f\n", x[0]); 82 printf("u1 * u2 : %f\n", x[1]); 83 printf("u1 * u3 : %f\n", x[2]); 84 printf("u2 * u2 : %f\n", x[3]); 85 printf("u2 * u3 : %f\n", x[4]); 86 printf("u3 * u3 : %f\n \n", x[5]); 87 88 a[0] = in_pro(xn, u1, 3); 89 a[1] = in_pro(xn, u2, 3); 90 a[2] = in_pro(xn, u3, 3); 91 92 printf("a1[%f], a2[%f], a3[%f]\n \n", a[0], a[1], a[2]); 93 94 for (size_t i = 0; i < 3; i++) g[i] = a[0] * u1[i] + a[1] * u2[i] + a[2] * u3[i]; 95 96 printf("g[%f, %f, %f]\n", g[0], g[1], g[2]); 97 98 99 fclose(fp); 100 return 0; 101} 102 103double in_pro(double v1[], double v2[], int size) 104{ 105 int i; 106 double x = 0; 107 for (i = 0; i < size; i++) x += v1[i] * v2[i]; 108 109 return x; 110}

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

VisualStudio2015
VCコンパイラ

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

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

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

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

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

s_clalis

2018/05/30 11:42

分かりました。直ちに修正します。
guest

回答4

0

これ動的メモリ使う必要ありますか?
data_rawはファイルの中身を格納するのみで、結局そのあとdataに数値変換して入れ替えてますよね。
しかもそのdataは静的メモリ。
だったら最初から、1行読み込み→数値変換→dataに格納で良いのではないでしょうか。
無理に動的メモリを使う必要はなさそうですが。
仮に一旦data_rawに入れておきたいというのであれば、ファイル数・行数・1行あたりの文字数の上限が決まっているのだから、char data_raw[F_C][D_S][0x10]でいいような気もします。

投稿2018/05/30 00:20

ttyp03

総合スコア16996

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

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

s_clalis

2018/05/30 08:00

動的確保の練習と利用の練習に書いています。  atoiして静的なdataに渡しているのは処理部の再利用のためです。もちろん大きさが決まっているので仰る通りの型の方がいいと思いました。
guest

0

ベストアンサー

C

1 while (fgets(data_raw[i][n], 0x10, fp) != NULL) 2 { 3 n++; 4 //puts(data_raw[i][n]); 5 }

ここのn++後、D_Sと値チェックをしてwhile文を抜けないと、ファイル内容次第ではバッファオーバーのエラーが出るかな。
あとファイルは新しく開ける前に閉じましょう。ファイルポインタを使いまわしている。

ぱっと見ですが、そこらへんが気になりました。

投稿2018/05/29 10:43

ardin

総合スコア544

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

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

s_clalis

2018/05/30 08:24

以下のように変更してみました。しかし、ファイル先頭のデータしか読めません。質問のの愛用を更新しました。 while (fgets(data_raw[i][n], 0x10, fp) != NULL) { if (n > D_S - 1) break; n++; puts(data_raw[i][n]); } n = 0; fclose(fp);
guest

0

ありがとうございます。
残念ながら諦めました。

投稿2018/05/30 09:09

編集2018/05/30 09:21
s_clalis

総合スコア17

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

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

0

ぱっと見、問題なさそうですが、、、
ちょっと気になったのが、

while (fgets(data_raw[i][n], 0x10, fp) != NULL)

nが D_S 以上になる事は無いでしょうか?
ファイルの最後に余分な改行があるとか。
--> 余分な改行があると、ここで実行時エラーとなります。

とりあえず、気づいた事として。

投稿2018/05/29 10:41

編集2018/05/29 13:27
pepperleaf

総合スコア6383

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

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

s_clalis

2018/05/30 08:20

D_S以上になることはありません。  ファイルの余分な改行とはどのことをいうのでしょうか。データは以下のようになっています。("[EOF]"は文字列ではありません) ``` 573 577 595 ・ ・ ・ 132 [EOF] ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問