【convta.cのソースコード】
/*
* 透過率-吸光度変換プログラム
* convta.c(convert transmittance-absorbance)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen(), strcmp(), strcpy(), strcat() */
#include <ctype.h> /* tolower() */
#include <math.h> /* log10(), log(), exp() */
#define BUF_SIZE 256
#define NUM_DATA 4000
/*
* 自作のbool型の定義
*/
typedef enum {
false, /* 0 */
true /* 1 */
} bool;
/*
* ユーザー定義関数のプロトタイプ宣言
*/
void print_title(void);
void input_fnamein(void);
char *strtolower(char *ss);
void open_fin(void);
void read_data(void);
void select_dir(void);
void conv_data(void);
void gen_fname(char *fnamein, char *fnameout);
void open_fout(void);
void write_data(void);
void close_f(void);
bool retry(void);
/*
* グローバル変数
*/
FILE *finp, *foutp;
char fnamein[BUF_SIZE], fnameout[BUF_SIZE];
char conv_dir;
int n, last_n;
long double x_tmp, x[NUM_DATA], y_tmp, y[NUM_DATA];
/*
* メイン関数
*/
int main(void)
{
/* 標題および説明の表示 */
print_title();
while (1) {
n = last_n = 0;
/* 入力ファイルの名前の入力 */
input_fnamein();
/* 入力ファイルを開く処理 */
open_fin();
/* 入力ファイルからのデータの読み込み */
read_data();
/* 変換の向きの選択 */
select_dir();
/* 変換処理 */
conv_data();
/* 出力ファイルの名前の生成 */
gen_fname(fnamein, fnameout);
/* 出力ファイルを開く処理 */
open_fout();
/* 出力ファイルへのデータの書き込み */
write_data();
/* ファイルを閉じる処理 */
close_f();
/* 操作を続けるかどうかの選択 */
if (!retry())
break;
}
return EXIT_SUCCESS;
}
/*
* 標題および説明を表示する関数
*/
void print_title(void)
{
printf("【透過率-吸光度変換プログラム】\n\n");
printf("CSV形式のスペクトルデータの\n");
printf("「パーセント透過率⇔吸光度」\n");
printf("の変換を行います。\n\n");
}
/*
* 入力ファイルの名前を入力する関数
* 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 *ss)
{
char *p;
for (p = ss; *p; p++)
*p = tolower(*p);
return ss;
}
/*
* 入力ファイルを開く関数
*/
void open_fin(void)
{
finp = fopen(fnamein, "r");
if (finp == NULL) {
printf("ファイル%sを開けません。", fnamein);
printf("終了します。\n");
exit(EXIT_FAILURE);
}
}
/*
* 入力ファイルからデータを読み込む関数
*/
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++;
}
last_n = n;
}
/*
* 変換の向き(conv_dir)を選択する関数
* conv_dir == '1': 「パーセント透過率→吸光度」
* conv_dir == '2': 「吸光度→パーセント透過率」
*/
void select_dir(void)
{
char buf[BUF_SIZE], zz;
while (1) {
printf("変換の向き(1または2)を入力してください。\n");
printf("\t「パーセント透過率→吸光度」なら1\n");
printf("\t「吸光度→パーセント透過率」なら2\n");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c%c", &conv_dir, &zz);
if (((conv_dir != '1') && (conv_dir != '2'))
|| (zz != '\n')) {
printf("無効な入力です。\n");
printf("1または2を入力してください。\n\n");
continue;
} else
break;
}
}
/*
* データの変換をする関数
*/
void conv_data(void)
{
int i;
switch (conv_dir) {
case '1':
for (i = 0; i < last_n; i++)
y[i] = 2.0 - log10(y[i]);
break;
case '2':
for (i = 0; i < last_n; i++)
y[i] = exp((2.0 - y[i]) * log(10.0));
break;
default:
break;
}
}
/*
* 出力ファイルの名前を生成する関数
*/
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);
switch (conv_dir) {
case '1':
fnameout = strcat(fnameout, "_a.csv");
break;
case '2':
fnameout = strcat(fnameout, "_t.csv");
break;
default:
break;
}
}
/*
* 出力ファイルを開く関数
*/
void open_fout(void)
{
foutp = fopen(fnameout, "w");
if (foutp == NULL) {
printf("ファイル%sを開けません。", fnameout);
printf("終了します。\n");
exit(EXIT_FAILURE);
}
}
/*
* 出力ファイルへデータを書き込む関数
*/
void write_data(void)
{
int i;
for (i = 0; i < last_n; i++)
fprintf(foutp, "%LE,%LE\n", x[i], y[i]);
}
/*
* ファイルを閉じる関数
*/
void close_f(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\n");
}
return ret;
}
D:\test>dir
(中略)
2023-05-14 07:35 50,436 sk232201d.csv ←元の(パーセント透過率の)データファイル。
D:\test>convta
【透過率-吸光度変換プログラム】
CSV形式のスペクトルデータの
「パーセント透過率⇔吸光度」
の変換を行います。
入力ファイルの名前(*.csv)を入力してください。
sk232201d.c
ファイル名が正しくありません。
入力ファイルの名前(*.csv)を入力してください。
sk232201d.csv
変換の向き(1または2)を入力してください。
「パーセント透過率→吸光度」なら1
「吸光度→パーセント透過率」なら2
1 ←1を入力する。
続けますか?(y/n) n
D:\test>dir
(中略)
2023-05-14 07:35 50,436 sk232201d.csv ←元の(パーセント透過率の)データファイル。
2023-05-22 20:32 50,436 sk232201d_a.csv ←作成された吸光度のデータファイル。