#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
int cols;
int rows;
float** p;
}CSV;
// メモリ解放
void csv_free(CSV* csv)
{
int r;
if(csv != NULL){
if(csv->p != NULL){
for(r = 0; r < csv->rows; r++){
if(csv->p[r] != NULL)free(csv->p[r]);
}
free(csv->p);
}
free(csv);
}
}
// 入力
CSV* csv_read(const char* ifname)
{
FILE* ifp;
CSV* csv = NULL;
char buf[1024];
char* p;
int r, c;
ifp = fopen(ifname, "r");
if(ifp != NULL){
csv = calloc(1, sizeof(CSV));
for(r = 0; fgets(buf, 1024, ifp) != NULL; r++){
// 1行目のみカラム数を計算し、以降の行はカラム数が1行目と同じものと仮定する
if(r == 0){
p = buf;
csv->cols = 1;
for(;;){
p = strstr(p, ",");
if(p == NULL)break;
p++;
csv->cols++;
}
}
// 入力データ用メモリの行拡張
csv->p = (float**)realloc(csv->p, sizeof(float*) * (r + 1));
csv->p[r] = (float*)calloc(csv->cols, sizeof(float));
// 列読込み
p = buf;
for(c = 0; ; c++){
if(sscanf(p, "%f", &(csv->p[r][c])) <= 0)break;
p = strstr(p, ",");
if(p == NULL)break;
p++;
}
csv->rows = r + 1;
}
fclose(ifp);
return csv;
}else{
return NULL;
}
}
// 出力
int csv_write(const char* ofname, CSV* csv)
{
int r, c;
FILE* ofp;
ofp = fopen(ofname, "w");
if(ofp != NULL){
for(r = 0; r < csv->rows; r++){
for(c = 0; c < csv->cols; c++){
if(c > 0)fprintf(ofp, ", ");
fprintf(ofp, "%f", csv->p[r][c]);
}
fprintf(ofp, "\n");
}
fclose(ofp);
return 1;
}else{
return 0;
}
}
// >>956 正規化
void normalize(CSV* csv)
{
int r, c;
float max, min;
for(c = 0; c < csv->cols; c++){
max = 0.0;
min = 99999999.0;
for(r = 0; r < csv->rows; r++){
if(max < csv->p[r][c])max = csv->p[r][c];
if(min > csv->p[r][c])min = csv->p[r][c];
}
for(r = 0; r < csv->rows; r++){
if(max - min == 0){
csv->p[r][c] = 0.0;
}else{
csv->p[r][c] = (csv->p[r][c] - min) / (max - min);
}
}
}
}
int main()
{
const char* ifname = "sitei.csv";
const char* ofname2 = "2.csv";
CSV* csv;
// >>956 正規化
csv = csv_read(ifname);
if(csv != NULL){
normalize(csv);
csv_write(ofname2, csv);
csv_free(csv);
}
return 0;
}