【detpeak.cのソースコード】
/*
* CSV形式のスペクトルデータからピークを検出し、
* ピーク位置とそのときの値の一覧表(list)を
* 新たなCSVファイルとして出力するプログラム
* detpeak.c(detect peak)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen(), strcmp(), strcpy(), strcat() */
#include <ctype.h> /* tolower() */
#define BUF_SIZE 256
#define NUM_DATA 4000
/*
* 自作のbool型の定義
*/
typedef enum {
false, /* 0 */
true /* 1 */
} bool;
/*
* ユーザー定義関数の関数原型宣言
*/
void print_title(void);
void init_val(void);
void input_fnamein(void);
char *strtolower(char *sp);
void open_fin(void);
void input_datatype(void);
void read_data(void);
void gen_fname(char *fnamein, char *fnameout);
void open_fout(void);
void write_data(void);
void close_fio(void);
bool retry(void);
/*
* グローバル変数
*/
char fnamein[BUF_SIZE], fnameout[BUF_SIZE], datatype;
int n, numpeak;
long double x_tmp, x[NUM_DATA], y_tmp, y[NUM_DATA];
FILE *finp, *foutp;
int main(void)
{
while (1) {
/* 表題・説明 */
print_title();
/* 変数の初期化 */
init_val();
/* 入力ファイルの名前の入力 */
input_fnamein();
/* 入力ファイルを開く処理 */
open_fin();
/* データの種類の入力 */
input_datatype();
/* 入力ファイルからのデータの読み込み */
read_data();
/* 出力ファイルの名前の生成 */
gen_fname(fnamein, fnameout);
/* 出力ファイルを開く処理 */
open_fout();
/* 出力ファイルへのデータの書き込み */
write_data();
/* 入出力ファイルを閉じる処理 */
close_fio();
/* 操作を続けるかどうかの選択 */
if (!retry())
break;
}
return EXIT_SUCCESS;
}
/*
* 表題およびプログラムの説明を表示する関数
*/
void print_title(void)
{
printf("【ピーク検出プログラム】\n");
printf("CSV形式のスペクトルデータ(*.csv)からピークを検出し、\n");
printf("ピーク位置とそのときの値の一覧表(list)を\n");
printf("新たなCSVファイル(*_l.csv)として出力します。\n\n");
}
/*
* 変数を初期化する関数
*/
void init_val(void)
{
n = 0;
numpeak = 1;
}
/*
* 入力ファイルの名前を入力する関数
* strtolower()関数を使用する。
*/
void input_fnamein(void)
{
while (1) {
printf("入力ファイルの名前(*.csv)を入力してください。\n");
fgets(fnamein, sizeof fnamein, stdin);
fnamein[strlen(fnamein) - 1] = '\0';
if (strcmp(strtolower(&fnamein[strlen(fnamein) - 4]), ".csv") != 0) {
printf("ファイル名が正しくありません。\n");
continue;
} else
break;
}
}
/*
* 文字列単位で英大文字を小文字に変換する関数
*/
char *strtolower(char *sp)
{
char *p;
for (p = sp; *p; p++)
*p = tolower(*p);
return sp;
}
/*
* 入力ファイルを開く関数
*/
void open_fin(void)
{
finp = fopen(fnamein, "r");
if (finp == NULL) {
printf("ファイル%sを開けません。終了します。\n", fnamein);
exit(EXIT_FAILURE);
}
}
/*
* データの種類を入力する関数
*/
void input_datatype(void)
{
char buf[BUF_SIZE], zz;
while (1) {
printf("\nデータの種類を入力してください。\n");
printf("\tピークが上向きのデータ(吸光度など) -> 1\n");
printf("\tピークが下向きのデータ(透過率など) -> 2\n");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c%c", &datatype, &zz);
if (((datatype != '1') && (datatype != '2')) || (zz != '\n')) {
printf("無効な入力です。\n");
printf("1または2を入力してください。\n\n");
continue;
} else
break;
}
}
/*
* 入力ファイルからデータを読み込む関数
*/
void read_data(void)
{
char zz;
while(fscanf(finp, "%lf,%lf%c", &x_tmp, &y_tmp, &zz) != EOF) {
x[n] = x_tmp;
y[n] = y_tmp;
n++;
}
}
/*
* 出力ファイルの名前を生成する関数
*/
void gen_fname(char *fnamein, char *fnameout)
{
int i;
char fnamebodyin[BUF_SIZE];
strcpy(fnamebodyin, fnamein);
for (i = strlen(fnamebodyin) - 1; i > 0; i--)
if (fnamebodyin[i] == '.') {
fnamebodyin[i] = '\0';
break;
}
strcpy(fnameout, fnamebodyin);
fnameout = strcat(fnameout, "_l.csv");
}
/*
* 出力ファイルを開く関数
*/
void open_fout(void)
{
foutp = fopen(fnameout, "w");
if (foutp == NULL) {
printf("ファイル%sを開けません。終了します。\n", fnameout);
exit(EXIT_FAILURE);
}
}
/*
* 出力ファイルにデータを書き込む関数
*/
void write_data(void)
{
int k;
long double d0, d1;
fprintf(foutp, "ピーク番号,ピーク位置,ピークの値\n");
for(k = 1; k < n - 1; k++) {
d0 = y[k] - y[k - 1];
d1 = y[k + 1] - y[k];
switch (datatype) {
case '1':
if ((d0 > 0) && (d1 < 0))
fprintf(foutp, "%d,%LE,%LE\n", numpeak++, x[k], y[k]);
break;
case '2':
if ((d0 < 0) && (d1 > 0))
fprintf(foutp, "%d,%LE,%LE\n", numpeak++, x[k], y[k]);
break;
default:
break;
}
}
}
/*
* 入出力ファイルを閉じる関数
*/
void close_fio(void)
{
fclose(finp);
fclose(foutp);
}
/*
* 操作を続けるかどうかを選択する関数
* true: 繰り返す、false: 終了する。
*/
bool retry(void)
{
bool ret;
char buf[BUF_SIZE], ch, zz;
while (1) {
printf("\n続けますか?(y/n) ");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c%c", &ch, &zz);
if (((ch == 'y') || (ch == 'Y')) && (zz == '\n')) {
printf("\n+++++\n\n");
ret = true;
break;
} else if (((ch == 'n') || (ch == 'N')) && (zz == '\n')) {
ret = false;
break;
}
printf("無効な入力です。\n");
printf("yまたはnを入力してください。\n");
}
return ret;
}
C:\Users\skonishi\Documents>dir
2022/04/06 20:19 9,216 delta.csv ←元のデータファイル(*.csv)
2024/01/14 10:08 148,992 detpeak.exe
C:\Users\skonishi\Documents>detpeak
【ピーク検出プログラム】
CSV形式のスペクトルデータ(*.csv)からピークを検出し、
ピーク位置とそのときの値の一覧表(list)を
新たなCSVファイル(*_l.csv)として出力します。
入力ファイルの名前(*.csv)を入力してください。
delta.csv
データの種類を入力してください。
ピークが上向きのデータ(吸光度など) -> 1
ピークが下向きのデータ(透過率など) -> 2
1 ←ピークが上向きなので1
続けますか?(y/n) n
C:\Users\skonishi\Documents>dir
2022/04/06 20:19 9,216 delta.csv
2024/01/14 10:17 267 delta_l.csv ←作成されたピークデータリスト(list)のファイル(*_l.csv)
2024/01/14 10:08 148,992 detpeak.exe