fork download
  1. //#include "stdafx.h"
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #include<math.h>
  6.  
  7. #define FILE_SAMPLE "sample.txt" // データファイル
  8. #define FILE_TEST "test.txt" // データファイル
  9. #define DAT_N (500) // 1行のデータ個数
  10.  
  11. // データ
  12. typedef struct
  13. {
  14. double a_data[DAT_N]; // a[]
  15. char a_fname[_MAX_PATH];
  16. int b_lines;
  17. char ** b_fname;
  18. double ** b_data; // b[][]
  19. double c_data[DAT_N]; // c[]
  20. } ALL_DATA;
  21.  
  22. // Error コード
  23. enum ERR_CODE
  24. {
  25. EDR_Normal = 0 , // 正常終了
  26. EDR_FileOpen , // ファイルが開けない
  27. EDR_NotEnoughData , // データが足りない
  28. EDR_MemAlloc , // メモリ確保失敗
  29. EDR_Zero , // 要素が全てゼロ
  30. };
  31. char *getStrERR_CODE(int code)
  32. {
  33. switch(code)
  34. {
  35. case EDR_Normal :return "正常終了";
  36. case EDR_FileOpen :return "ファイルが開けない";
  37. case EDR_NotEnoughData :return "データが足りない";
  38. case EDR_MemAlloc :return "メモリ確保失敗";
  39. case EDR_Zero :return "要素が全てゼロ";
  40. }
  41. return "";
  42. }
  43.  
  44. void aldat_init(ALL_DATA *d); // ALL_DATA初期化
  45. ERR_CODE aldat_alloc(ALL_DATA *d, int lines); // ALL_DATA確保
  46. void aldat_free(ALL_DATA *d); // ALL_DATA解放
  47. ERR_CODE data_read(char *file1, char *file2, ALL_DATA *d); // データ読み込み
  48. char * f2s_n(double d, int n); // 有効数字n桁小数文字列生成
  49.  
  50. #ifdef _DEBUG
  51. #define debug_out(x) debug_file_out(x)
  52. void debug_file_out(ALL_DATA *d);
  53. #else
  54. #define debug_out(x)
  55. #endif
  56.  
  57. //---------------------------------------------------------------------------
  58. // ALL_DATA初期化
  59. //---------------------------------------------------------------------------
  60. void aldat_init(ALL_DATA *d)
  61. {
  62. if(NULL == d)
  63. {
  64. return;
  65. }
  66. memset(d, 0x00, sizeof(ALL_DATA));
  67. }
  68.  
  69. //---------------------------------------------------------------------------
  70. // ALL_DATA確保
  71. // 戻り値が EDR_Normal 以外の時は、当関数でfreeしているので呼び元でfreeしなくて良い
  72. //---------------------------------------------------------------------------
  73. ERR_CODE aldat_alloc(ALL_DATA *d, int lines)
  74. {
  75. ERR_CODE r = EDR_Normal;
  76. int i;
  77.  
  78. // b の行数
  79. d->b_lines = lines;
  80. // b
  81. if(NULL == (d->b_data = (double **)malloc(sizeof(double *) * lines)))
  82. {
  83. r = EDR_MemAlloc;
  84. goto END_aldat_alloc;
  85. }
  86. memset(d->b_data, 0x00, sizeof(double *) * lines);
  87. // b[]のfilename
  88. if(NULL == (d->b_fname = (char **)malloc(sizeof(char *) * lines)))
  89. {
  90. r = EDR_MemAlloc;
  91. goto END_aldat_alloc;
  92. }
  93. memset(d->b_fname, 0x00, sizeof(char *) * lines);
  94. // b[][] と b[]のfilename
  95. for(i=0; i<lines; i++)
  96. {
  97. if(NULL == (d->b_data[i] = (double *)malloc(sizeof(double) * DAT_N)))
  98. {
  99. r = EDR_MemAlloc;
  100. goto END_aldat_alloc;
  101. }
  102. if(NULL == (d->b_fname[i] = (char *)malloc(sizeof(char) * _MAX_PATH)))
  103. {
  104. r = EDR_MemAlloc;
  105. goto END_aldat_alloc;
  106. }
  107. }
  108.  
  109. r = EDR_Normal;
  110. END_aldat_alloc:;
  111. if(EDR_Normal != r)
  112. {
  113. aldat_free(d);
  114. }
  115. return r;
  116. }
  117.  
  118. //---------------------------------------------------------------------------
  119. // ALL_DATA解放
  120. //---------------------------------------------------------------------------
  121. void aldat_free(ALL_DATA *d)
  122. {
  123. int i;
  124.  
  125. if(NULL == d)
  126. {
  127. return;
  128. }
  129. for(i=0; i < d->b_lines; i++)
  130. {
  131. if(NULL == d->b_data[i] && NULL == d->b_fname[i])
  132. {
  133. break;
  134. }
  135. if(d->b_data[i])
  136. {
  137. free(d->b_data[i]);
  138. }
  139. if(d->b_fname[i])
  140. {
  141. free(d->b_fname[i]);
  142. }
  143. }
  144. free(d->b_data);
  145. free(d->b_fname);
  146. aldat_init(d);
  147. }
  148.  
  149. //---------------------------------------------------------------------------
  150. // 関数 = データ読み込み
  151. // 引数 = file1 : データファイル名 (sample.txt)
  152. // file2 : データファイル名 (test.txt)
  153. // d : データ
  154. // 戻り値 = enum ERR_CODE;
  155. // 注意 = ・dは呼び元で用意すること
  156. // ・メモリ初期化/確保とエラー時の解放はは当関数でするが、
  157. // 使用後の解放は呼び元ですること
  158. //---------------------------------------------------------------------------
  159. ERR_CODE data_read(char *file1, char *file2, ALL_DATA *d)
  160. {
  161. ERR_CODE res = EDR_Normal; // 戻り値
  162. FILE *fp = NULL; // ファイル
  163. char *buf = NULL; // 1行読み込みバッファ
  164. int buf_size; // 〃 サイズ
  165. int i, j, line; // 汎用
  166. char *token; // 汎用
  167.  
  168. // 初期化
  169. aldat_init(d);
  170.  
  171. // buf のサイズ (大きい方のファイルのサイズ)
  172. if (NULL == (fp = fopen(file1, "rb")))
  173. {
  174. res = EDR_FileOpen;
  175. goto END_DATAREAD;
  176. }
  177. fseek(fp, 0, SEEK_END);
  178. i = (int)ftell(fp) + 1;
  179. fclose(fp);
  180. if (NULL == (fp = fopen(file2, "rb")))
  181. {
  182. res = EDR_FileOpen;
  183. goto END_DATAREAD;
  184. }
  185. fseek(fp, 0, SEEK_END);
  186. j = (int)ftell(fp) + 1;
  187. fclose(fp);
  188. fp = NULL;
  189. buf_size = (j > i) ? j : i;
  190. // buff 確保
  191. if(NULL == (buf = (char*)malloc(buf_size)))
  192. {
  193. res = EDR_MemAlloc;
  194. goto END_DATAREAD;
  195. }
  196.  
  197. // test.txt を空読みしてデータ数(行数)を数える
  198. fp = fopen(file2, "r");
  199. for(line = 0; NULL != fgets(buf, buf_size, fp); line++);
  200. if(line < 1)
  201. {
  202. res = EDR_NotEnoughData;
  203. goto END_DATAREAD;
  204. }
  205. fclose(fp);
  206. fp = NULL;
  207. // データ領域確保
  208. if(EDR_Normal != (res = aldat_alloc(d, line)))
  209. {
  210. goto END_DATAREAD;
  211. }
  212.  
  213. // sample.txt
  214. fp = fopen(file1, "r");
  215. fgets(buf, buf_size, fp);
  216. // filename
  217. if(NULL == (token = strtok(buf, "\t")))
  218. {
  219. res = EDR_NotEnoughData;
  220. goto END_DATAREAD;
  221. }
  222. strncpy(d->a_fname, token, _MAX_PATH);
  223. // data
  224. for (j = 0; j < DAT_N; j++) {
  225. token = strtok(NULL, "\t");
  226. if (NULL == token) {
  227. res = EDR_NotEnoughData;
  228. goto END_DATAREAD;
  229. }
  230. d->a_data[j] = atof(token);
  231. }
  232. fclose(fp);
  233. fp = NULL;
  234.  
  235. // test.txt
  236. fp = fopen(file2, "r");
  237. for(i = 0; i < d->b_lines; i++)
  238. {
  239. fgets(buf, buf_size, fp);
  240. // filename
  241. if(NULL == (token = strtok(buf, "\t")))
  242. {
  243. res = EDR_NotEnoughData;
  244. goto END_DATAREAD;
  245. }
  246. strncpy(d->b_fname[i], token, _MAX_PATH);
  247. // data
  248. for (j = 0; j < DAT_N; j++) {
  249. token = strtok(NULL, "\t");
  250. if (NULL == token) {
  251. res = EDR_NotEnoughData;
  252. goto END_DATAREAD;
  253. }
  254. d->b_data[i][j] = atof(token);
  255. }
  256. }
  257. fclose(fp);
  258. fp = NULL;
  259.  
  260. res = EDR_Normal;
  261. END_DATAREAD:;
  262. if(res != EDR_Normal)
  263. {
  264. aldat_free(d);
  265. }
  266. if(buf)
  267. {
  268. free(buf);
  269. buf = NULL;
  270. }
  271. buf_size = 0;
  272. if(fp)
  273. {
  274. fclose(fp);
  275. fp = NULL;
  276. }
  277. return res;
  278. }
  279.  
  280. //---------------------------------------------------------------------------
  281. // 関数 = 有効数字n桁小数文字列生成
  282. // 動作 = 例えば n == 6 のとき、
  283. // 0.0 → "0"
  284. // 0.123456789 → "0.123457"
  285. // 0.000123456789 → "0.000123457"
  286. // 0.0120000 → "0.012"
  287. // を返す
  288. // メモ = ・n < 16
  289. // ・未完成
  290. //---------------------------------------------------------------------------
  291. char *f2s_n(double d, int n)
  292. {
  293. static char b[32];
  294.  
  295. if(d == 0.0)
  296. {
  297. return "0";
  298. }
  299. sprintf(b, "%.*f", n, d);
  300.  
  301. return &b[0];
  302. }
  303.  
  304. //---------------------------------------------------------------------------
  305. // データ出力 (debug)
  306. //---------------------------------------------------------------------------
  307. #ifdef _DEBUG
  308. void debug_file_out(ALL_DATA *d)
  309. {
  310. int i, j;
  311. FILE *fp;
  312.  
  313. fp = fopen("dbg_s.txt", "w");
  314. fprintf(fp, "%s\t", d->a_fname);
  315. for(j = 0; j < DAT_N; j++)
  316. {
  317. fprintf(fp, "%s\t", f2s_n(d->a_data[j], 6));
  318. }
  319. fprintf(fp, "\n");
  320. fclose(fp);
  321. fp = fopen("dbg_t.txt", "w");
  322. for(i = 0; i < d->b_lines; i++)
  323. {
  324. fprintf(fp, "%s\t", d->b_fname[i]);
  325. for(j = 0; j < DAT_N; j++)
  326. {
  327. fprintf(fp, "%s\t", f2s_n(d->b_data[i][j], 6));
  328. }
  329. fprintf(fp, "\n");
  330. }
  331. fclose(fp);
  332. }
  333. #endif
  334.  
  335. //---------------------------------------------------------------------------
  336. // main
  337. //---------------------------------------------------------------------------
  338. int main()
  339. {
  340. int result = 0;
  341. ALL_DATA data;
  342. ERR_CODE res;
  343. int i, j;
  344. double v1,v2,v3;
  345.  
  346. // 初期化
  347. aldat_init(&data);
  348.  
  349. // read
  350. if(EDR_Normal != (res = data_read(FILE_SAMPLE, FILE_TEST, &data)))
  351. {
  352. result = (int)res;
  353. goto END_MAIN;
  354. }
  355.  
  356. // (debugモード時) 読んだデータを確認のためファイル dbg_s.txt, dbg_t.txt に書き出す
  357. debug_out(&data);
  358.  
  359. // 計算
  360. for(i=0; i < data.b_lines; i++)
  361. {
  362. v1 = v2 = v3 = 0.0;
  363. for(j=0; j< DAT_N; j++)
  364. {
  365. v1 += data.a_data[j] * data.b_data[i][j];
  366. v2 += data.a_data[j] * data.a_data[j];
  367. v3 += data.b_data[i][j] * data.b_data[i][j];
  368. }
  369. if(v2 == 0.0 || v3 == 0.0)
  370. {
  371. fprintf(stderr, "%d行目、", i + 1);
  372. result = EDR_Zero;
  373. goto END_MAIN;
  374. }
  375. data.c_data[i] = v1 / (sqrt(v2) * sqrt(v3));
  376. }
  377.  
  378. // 結果
  379. for(i=0; i < data.b_lines; i++)
  380. {
  381. printf("%s\t%s\n", data.b_fname[i], f2s_n(data.c_data[i], 15));
  382. }
  383.  
  384. // end
  385. result = (int)EDR_Normal;
  386. END_MAIN:;
  387. aldat_free(&data);
  388. if(EDR_Normal != result)
  389. {
  390. fprintf(stderr, "%s\n", getStrERR_CODE(result));
  391. }
  392. return result;
  393. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:15: error: ‘_MAX_PATH’ undeclared here (not in a function)
prog.c:45: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘aldat_alloc’
prog.c:47: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘data_read’
prog.c:73: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘aldat_alloc’
prog.c:159: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘data_read’
prog.c: In function ‘main’:
prog.c:342: error: ‘ERR_CODE’ undeclared (first use in this function)
prog.c:342: error: (Each undeclared identifier is reported only once
prog.c:342: error: for each function it appears in.)
prog.c:342: error: expected ‘;’ before ‘res’
prog.c:350: error: ‘res’ undeclared (first use in this function)
prog.c:350: warning: implicit declaration of function ‘data_read’
stdout
Standard output is empty