csvファイルから配列への読み込みについて(C言語)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
K3

csvファイルから配列への読み込みについて(C言語)

#1

投稿記事 by K3 » 8年前

初めて質問させていただきます。

現在、データベースを一般化(匿名化)し、それがk-匿名性を満たしているかどうかを判定するプログラムを作成しています。

処理手順としては、
1.匿名化
2.kの値を指定
3.k-匿名性を満たしているか判定
です。

扱うデータベースは以下のようになっており、4332行あります。
12346 f 1951/8/14 United_Kingdom atopic_dermatitis
12347 f 1983/7/11 Iceland apoplexy
12348 f 1956/5/17 Finland atopic_dermatitis
12349 f 1950/12/2 Italy asthma
12350 f 1962/2/1    Norway atopic_dermatitis
12352 f 1959/6/20 Norway asthma
12353 f 1954/2/22 Bahrain pneumonia
.
.
.
.

ここで、関数k_judge()のファイルの読み込みがうまくいきません。
具体的には、
.
.
.
4294,f,1950,Scandinavia,cancer
4295,f,1960,Scandinavia,pneumonia
4296,f,1950,S,
4297,,0,,
4298,,0,,
.
.
.
と言う風になっています。
本来、元のcsvファイルは4332行あるのですが、最後まで読み込まれず、途中で切れてしまっている状況です。
また、csvファイルを3999行などに変更しても、同様に3127行など途中までしか読み込む(表示する)ことができません。
どうかお力添え頂きたく思います。。。
よろしくお願いします。

ソースコードは以下です。(mac)

コード:

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

#define ROW 4333

int k_input();
void k_judge(FILE *g, int k);
void k_anony(FILE *f, FILE *p, int n);


int main(){
  //ファイルオープン
  FILE *f = fopen("Master.csv", "r");
  FILE *g = fopen("Anony.csv", "r");
  FILE *p = fopen("Anony.csv", "w");

  //csvが存在しない場合
  if (g == NULL){
    printf("\nFile cannnot opened.\n");
    return -1;
  }

  int n = 0;
  printf("\nデータを一般化します。\n");
  printf("番号を入力してください。\n");
  printf("---------------------------------------\n");
  printf("  0:生年月日の月日を削除\n");
  printf("  1:0に加え、誕生年の最小位を切り捨て\n");
  printf("  2:1に加え、国籍を地域に統合\n");
  printf("---------------------------------------\n");
  printf("番号:");
  scanf("%d", &n);

  k_anony(f, p, n);
  int k = k_input();
  k_judge(g, k);

  //ファイルクローズ
  fclose(f);
  fclose(g);
  return 0;
}


//kの入力 整数が入力されるまで繰り返す
int k_input(){
  double k = 0.1;
  printf("\n匿名化されたファイルがk-匿名性を満たしているか検証します。\n");
  while ((int)k != k) {
    printf("'k'の値を入力してください。:");
    scanf("%lf", &k);
    if ((int)k == k) break;
    printf("[ERROR]入力されたkの値が整数ではありません。\n");
  }
  printf("\n");
  return k;
}

void k_judge(FILE *g, int k){
  int i, j, count, solocount, cmin;
  char number[ROW][5], gender[ROW], country[ROW][20], disease[ROW][16];
  int birth[ROW];

  //ファイルの読み込み
  for (i = 0; i < ROW; i++) {
    fscanf( g, "%[^,],%c,%d,%[^,],%s", number[i], &gender[i], &birth[i], country[i], disease[i]);
    printf("%d,%c,%d,%s,%s\n", i+1,gender[i], birth[i], country[i], disease[i]);
  }

  //初期値の設定
  count = 0; cmin = ROW; solocount = 0;
  printf("---------------------------------------\n");
  printf("  行数 性別 誕生年      国籍\n");

  //同じレコードの組み合わせがあるか比較
  for (i = 0; i < ROW; i++) {
    for (j = 0; j < ROW; j++){
      //同一データが存在すればcountを加算
      if (gender[i] == gender[j]
          && birth[i] == birth[j]
          && strcmp(country[i], country[j]) == 0
        /*&& strcmp(disease[i], disease[j]) == 0*/){
        count++;
      }
    }
    //cminにcountの最小値を記憶
    if (count < cmin) cmin = count;
    if (count == 1){
      printf("  %d", i+1);
      printf("\t%c    %d   %s\n", gender[i], birth[i], country[i]/*, disease[i]*/);
      //単一データのカウント
      solocount++;
    }
    //countの初期化
    count = 0;
  }
  printf("---------------------------------------\n");
  printf("以上の%d件の単一データが存在します。\n", solocount);

  //cminが入力されたkを満たしているか判定
  if (cmin < k) {
    printf("\n[FALSE...] このデータベースは %d-匿名性を満たしていません。\n", (int)k);
    printf("\t   同一データの最小件数は %d 件です。\n\n", cmin);
  } else if (cmin >= k) {
    printf("\n[CLEAR!!!] このデータベースは %d-匿名性を満たしています。\n\n", (int)k);
  }
  //return cmin;
}

void k_anony(FILE *f, FILE *g, int n){
  char sex, country[25], disease[20];
  int number, year, month, day;
  int i;

  if (n == 0) { //month, dayを消去
    for (i = 0; i < ROW; i++) {
      fscanf( f, "%d,%c,%d/%d/%d,%[^,],%s", &number, &sex, &year, &month, &day, country, disease);
      fprintf(g, "XXXXX,%c,%d,%s,%s\n", sex, year, country, disease);
    }
  } else if (n == 1) {  //yearの最小位を切り捨て
    for (i = 0; i < ROW; i++) {
      fscanf( f, "%d,%c,%d/%d/%d,%[^,],%s", &number, &sex, &year, &month, &day, country, disease);
      if (year > 1930 && year < 1940) year = 1930;
      else if (year > 1940 && year < 1950) year = 1940;
      else if (year > 1950 && year < 1960) year = 1950;
      else if (year > 1960 && year < 1970) year = 1960;
      else if (year > 1970 && year < 1980) year = 1970;
      else if (year > 1980 && year < 1990) year = 1980;
      fprintf(g, "XXXXX,%c,%d,%s,%s\n", sex, year, country, disease);
    }
  } else if (n == 2) {  //地域を統合 レベル1
    for (i = 0; i < ROW; i++) {
      fscanf(f, "%d,%c,%d/%d/%d,%[^,],%s", &number, &sex, &year, &month, &day, country, disease);

      if (year > 1930 && year < 1940) year = 1930;
      else if (year > 1940 && year < 1950) year = 1940;
      else if (year > 1950 && year < 1960) year = 1950;
      else if (year > 1960 && year < 1970) year = 1960;
      else if (year > 1970 && year < 1980) year = 1970;
      else if (year > 1980 && year < 1990) year = 1980;

      //中東
      if (strcmp(country, "Bahrain") == 0
      || strcmp(country, "Israel") == 0
      || strcmp(country, "Lebanon") == 0
      || strcmp(country, "Saudi_Arabia") == 0
      || strcmp(country, "United_Arab_Emirates") == 0) {
        strcpy(country, "Middle_East");
      //北ヨーロッパ
      } else if (strcmp(country, "Denmark") == 0
      || strcmp(country, "Finland") == 0
      || strcmp(country, "Iceland") == 0
      || strcmp(country, "Lithuania") == 0
      || strcmp(country, "Norway") == 0
      || strcmp(country, "Sweden") == 0
      || strcmp(country, "United_Kingdom") == 0) {
        strcpy(country, "Scandinavia");
      //南ヨーロッパ
      } else if (strcmp(country, "Cyprus") == 0
      || strcmp(country, "Greece") == 0
      || strcmp(country, "Italy") == 0
      || strcmp(country, "Malta") == 0
      || strcmp(country, "Portugal") == 0
      || strcmp(country, "Spain") == 0) {
        strcpy(country, "Southern_Europe");
      //東ヨーロッパ
      } else if (strcmp(country, "Czech_Republic") == 0
      || strcmp(country, "Poland") == 0) {
        strcpy(country, "Eastern_Europe");
      //西ヨーロッパ
      } else if (strcmp(country, "Austria") == 0
      || strcmp(country, "Belgium") == 0
      || strcmp(country, "France") == 0
      || strcmp(country, "Germany") == 0
      || strcmp(country, "Netherlands") == 0
      || strcmp(country, "Switzerland") == 0) {
        strcpy(country, "Western_Europe");
      //オセアニア
      } else if (strcmp(country, "Australia") == 0) {
        strcpy(country, "Oceania");
      //北アメリカ
      } else if (strcmp(country, "Canada") == 0
      || strcmp(country, "USA") == 0) {
        strcpy(country, "North_America");
      //南アメリカ
      } else if (strcmp(country, "Brazil") == 0
      || strcmp(country, "USA") == 0) {
        strcpy(country, "South_America");
      //東アジア
      } else if (strcmp(country, "Japan") == 0) {
        strcpy(country, "East_Asia");
      //東南アジア
      } else if (strcmp(country, "Singapore") == 0) {
        strcpy(country, "Southeast_Asia");
      }
      //printf("XXXXX,%c,%d,%s,%s\n", sex, year, country, disease);
      fprintf(g, "XXXXX,%c,%d,%s,%s\n", sex, year, country, disease);
    }
  } else if (n == 3) {  //地域を統合 レベル2
      //以下未完成
  }
}


K3

Re: csvファイルから配列への読み込みについて(C言語)

#2

投稿記事 by K3 » 8年前

すみません。
解決しまた。
ファイルの扱い(f,p,g)を間違えていました。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る