fork(2) download
  1. // C言語/基本/CSVファイル読込sort出力
  2. // CSVファイルを読み込んで、構造体に設定しソートしてから再度CSVファイルに出力するサンプルです。
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. // Record構造体
  8. struct Record {
  9. // インデックス
  10. int idx;
  11. // タイトル
  12. char title[100];
  13. // 日付
  14. char date[11];
  15. };
  16.  
  17. // CSVファイルから読み込んだ文字列をRecord構造体に設定します
  18. void setRecord(struct Record* pR, const char* str) {
  19. int i = 0, start = 1, size;
  20. char* pStr;
  21. char buff[100];
  22. for (i = 0; i < 3; i++) {
  23. // ","を探す
  24. pStr = strstr(&str[start], "\",\"");
  25. if (pStr == NULL ) {
  26. // ","がない場合、最後の"を探す
  27. pStr = strstr(&str[start], "\"\n");
  28. }
  29. size = pStr - &str[start];
  30. switch (i) {
  31. case 0:
  32. // インデックス
  33. strncpy(buff, &str[start], size);
  34. pR->idx = atoi(buff);
  35. break;
  36. case 1:
  37. // タイトル
  38. strncpy(pR->title, &str[start], size);
  39. break;
  40. case 2:
  41. // 日付
  42. strncpy(pR->date, &str[start], size);
  43. break;
  44. default:
  45. break;
  46. }
  47. start = start + size + 3;
  48. }
  49. }
  50.  
  51. // Recordのソートを行います
  52. // 今回は3番目の項目と1番目の項目の昇順にしました。
  53. struct Record** sort(struct Record* pRecord, struct Record** out, int size) {
  54. int i, j;
  55. struct Record* ptmp;
  56. int cmp;
  57.  
  58. // 出力用ポインタ配列にRecordのポインタをすべて設定する
  59. for (i = 0; i < size; i++) {
  60. out[i] = &pRecord[i];
  61. }
  62.  
  63. for (i = 0; i < size - 1; i++) {
  64.  
  65. for (j = i + 1; j < size; j++) {
  66. // 文字列比較
  67. // ポイント2.2 構造体に入れたので好きな項目でソートできます
  68. cmp = strcmp(out[i]->date, out[j]->date);
  69. if (cmp > 0 || (cmp == 0 && out[i]->idx > out[j]->idx)) {
  70. // 日付が、out[i] > out[j]の場合、もしくは
  71. // 日付が同じで、インデックスがout[i] > out[j]の場合ポインタ入れ替え
  72. ptmp = out[i];
  73. out[i] = out[j];
  74. out[j] = ptmp;
  75. }
  76. }
  77. }
  78. return out;
  79. }
  80.  
  81. // CSVファイル出力
  82. void output(FILE* fp, struct Record** out, int size) {
  83. int i;
  84.  
  85. printf("sort後\n");
  86. for (i = 0; i < size; i++) {
  87. // ポイント3 カンマ区切りの文字列を作成して出力します
  88. fprintf(fp, "\"%d\",\"%s\",\"%s\"\n", out[i]->idx, out[i]->title,
  89. out[i]->date);
  90. printf("\"%d\",\"%s\",\"%s\"\n", out[i]->idx, out[i]->title,
  91. out[i]->date);
  92. }
  93. }
  94.  
  95. int main(int argc, char *argv[]) {
  96. char str[255];
  97. // 構造体の配列
  98. struct Record record[100];
  99. // 構造体のポインタの配列(ソート用)
  100. struct Record *sorted[100];
  101. int i = 0, size;
  102. // fopen(ファイル名, オプション)でファイルを開きます
  103. FILE* fp = fopen(argv[1], "r");
  104. // ファイルを開けない場合、FILEのポインタがNULLになります
  105. if (fp == NULL ) {
  106. puts("ファイルが開けないよ!");
  107. return EXIT_FAILURE;
  108. }
  109. printf("sort前\n");
  110. // fgets(読み込むバッファ, バッファのサイズ, FILEのポインタ)で一行ずつ読み込みます
  111. while (fgets(str, 255, fp)) {
  112. // 読み込んだ内容をそのまま出力
  113. printf(str);
  114. // ポイント1 読み込んだテキストを、分解して構造体の配列に設定します。
  115. // Record構造体にデータを設定
  116. setRecord(&record[i], str);
  117. i++;
  118. }
  119. // 入力ファイルをクローズ
  120. fclose(fp);
  121. // サイズを保存
  122. size = i;
  123.  
  124. // ポイント2 構造体の配列をソートします
  125. sort(record, sorted, size);
  126.  
  127. // 出力ファイルを開きます
  128. fp = fopen(argv[2], "w");
  129. // ファイルを開けない場合、FILEのポインタがNULLになります
  130. if (fp == NULL ) {
  131. puts("ファイルが開けないよ!");
  132. return EXIT_FAILURE;
  133. }
  134. // 出力ファイルに書き込みます
  135. output(fp, sorted, size);
  136. // 出力ファイルをクローズ
  137. fclose(fp);
  138.  
  139. return EXIT_SUCCESS;
  140. }
  141.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty