現在、データベースを一般化(匿名化)し、それが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
//以下未完成
}
}