【convdx.cのソースコード】
/*
* JCAMP-DX形式のファイルを2種類のCSVファイル
* (ヘッダファイル、データファイル)に変換するプログラム
* (convdx.c: convert dx)
*/
#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 input_fnamein(void);
char *strtolower(char *ss);
void open_fin(void);
void gen_fname(char *fnamein, char *fnameoutheader, char *fnameoutdata);
void open_fout(void);
void read_fin(void);
void write_fout(void);
void close_f(void);
bool retry(void);
/*
* グローバル変数
*/
FILE *finp, *foutheaderp, *foutdatap;
char fnamein[BUF_SIZE], fnameoutheader[BUF_SIZE], fnameoutdata[BUF_SIZE];
char title[BUF_SIZE], datatype[BUF_SIZE];
char origin[BUF_SIZE], owner[BUF_SIZE];
char strdate[BUF_SIZE], strtime[BUF_SIZE];
char strsystem[BUF_SIZE], xunits[BUF_SIZE], yunits[BUF_SIZE];
char xydata[BUF_SIZE], *datap;
int npoints, i, lasti;
double version, resolution;
long double deltax, xfactor, yfactor;
long double firstx, lastx, firsty;
long double xdata[NUM_DATA], ydata[NUM_DATA];
/*
* メイン関数
*/
int main(void)
{
while (1) {
/* プログラムの説明 */
print_title();
/* 入力ファイルの名前の入力 */
input_fnamein();
/* 入力ファイルを開く処理 */
open_fin();
/* 出力ファイルの名前の生成 */
gen_fname(fnamein, fnameoutheader, fnameoutdata);
/* 出力ファイルを開く処理 */
open_fout();
/* 入力ファイルの読み込み */
read_fin();
/* 出力ファイルへの書き込み */
write_fout();
/* ファイルを閉じる処理 */
close_f();
/* 操作を続けるかどうかの選択 */
if (!retry())
break;
}
return EXIT_SUCCESS;
}
/*
* プログラムの説明をする関数
*/
void print_title(void)
{
printf("【JCAMP-DX形式ファイル変換プログラム】\n");
printf("JCAMP-DX形式のスペクトルデータ(*.dx)を変換し、新たな2種類のCSVファイル\n");
printf("(ヘッダファイル{*h.csv}とデータファイル{*d.csv})として出力します。\n\n");
}
/*
* 入力ファイルの名前を入力する関数
* strtolower()関数を使用する。
*/
void input_fnamein(void)
{
while (1) {
printf("入力ファイルの名前(*.dx)を入力してください。\n");
fgets(fnamein, sizeof fnamein, stdin);
fnamein[strlen(fnamein) - 1] = '\0';
if (strcmp(strtolower(&fnamein[strlen(fnamein) - 3]), ".dx") != 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 gen_fname(char *fnamein, char *fnameoutheader, char *fnameoutdata)
{
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(fnameoutheader, fnamebodyin);
strcpy(fnameoutdata, fnamebodyin);
fnameoutheader = strcat(fnameoutheader, "h.csv");
fnameoutdata = strcat(fnameoutdata, "d.csv");
}
/*
* 出力ファイルを開く関数
*/
void open_fout(void)
{
foutheaderp = fopen(fnameoutheader, "w");
if (foutheaderp == NULL) {
printf("ファイル%sを開けません。", fnameoutheader);
printf("終了します。\n");
exit(EXIT_FAILURE);
}
foutdatap = fopen(fnameoutdata, "w");
if (foutdatap == NULL) {
printf("ファイル%sを開けません。", fnameoutdata);
printf("終了します。\n");
exit(EXIT_FAILURE);
}
}
/*
* 入力ファイルを読み込む関数
*/
void read_fin(void)
{
char buf[BUF_SIZE];
i = 0;
while(fgets(buf, BUF_SIZE, finp) != NULL) {
buf[strlen(buf) - 1] = '\0';
/* ファイルヘッダ部の読み込み */
if (strncmp(buf, "##TITLE=", 8) == 0)
strcpy(title, &buf[9]);
if (strncmp(buf, "##JCAMP-DX=", 11) == 0)
version = atof(&buf[12]);
if (strncmp(buf, "##DATA TYPE=", 12) == 0)
strcpy(datatype, &buf[13]);
if (strncmp(buf, "##ORIGIN=", 9) == 0)
strcpy(origin, &buf[10]);
if (strncmp(buf, "##OWNER=", 8) == 0)
strcpy(owner, &buf[9]);
if (strncmp(buf, "##DATE=", 7) == 0)
strcpy(strdate, &buf[8]);
if (strncmp(buf, "##TIME=", 7) == 0)
strcpy(strtime, &buf[8]);
if (strncmp(buf, "##SPECTROMETER/DATA SYSTEM=", 27) == 0)
strcpy(strsystem, &buf[28]);
if (strncmp(buf, "##RESOLUTION=", 13) == 0)
resolution = atof(&buf[14]);
if (strncmp(buf, "##DELTAX=", 9) == 0)
deltax = atof(&buf[10]);
if (strncmp(buf, "##XUNITS=", 9) == 0)
strcpy(xunits, &buf[10]);
if (strncmp(buf, "##YUNITS=", 9) == 0)
strcpy(yunits, &buf[10]);
if (strncmp(buf, "##XFACTOR=", 10) == 0)
xfactor = atof(&buf[11]);
if (strncmp(buf, "##YFACTOR=", 10) == 0)
yfactor = atof(&buf[11]);
if (strncmp(buf, "##FIRSTX=", 9) == 0) {
firstx = atof(&buf[10]);
xdata[i] = firstx;
}
if (strncmp(buf, "##LASTX=", 8) == 0)
lastx = atof(&buf[9]);
if (strncmp(buf, "##NPOINTS=", 10) == 0)
npoints = atoi(&buf[11]);
if (strncmp(buf, "##FIRSTY=", 9) == 0)
firsty = atof(&buf[10]);
if (strncmp(buf, "##XYDATA=", 9) == 0)
strcpy(xydata, &buf[10]);
/* データ部の読み込み */
if (strncmp(buf, "##", 2) != 0) {
datap = strtok(buf, " ");
while ((datap = strtok(NULL, " ")) != NULL) {
ydata[i++] = atof(datap) * yfactor;
xdata[i] = xdata[i - 1] + deltax * xfactor;
}
}
}
lasti = i;
}
/*
* 出力ファイルへ書き込む関数
*/
void write_fout(void)
{
/* ファイルヘッダ部の書き込み */
fprintf(foutheaderp, "##TITLE=,%s\n", title);
fprintf(foutheaderp, "##JCAMP-DX=,%.2f\n", version);
fprintf(foutheaderp, "##DATA TYPE=,%s\n", datatype);
fprintf(foutheaderp, "##ORIGIN=,%s\n", origin);
fprintf(foutheaderp, "##OWNER=,%s\n", owner);
fprintf(foutheaderp, "##DATE=,%s\n", strdate);
fprintf(foutheaderp, "##TIME=,%s\n", strtime);
fprintf(foutheaderp, "##SPECTROMETER/DATA SYSTEM=,%s\n", strsystem);
fprintf(foutheaderp, "##RESOLUTION=,%.1f\n", resolution);
fprintf(foutheaderp, "##DELTAX=,%LE\n", deltax);
fprintf(foutheaderp, "##XUNITS=,%s\n", xunits);
fprintf(foutheaderp, "##YUNITS=,%s\n", yunits);
fprintf(foutheaderp, "##XFACTOR=,%LE\n", xfactor);
fprintf(foutheaderp, "##YFACTOR=,%LE\n", yfactor);
fprintf(foutheaderp, "##FIRSTX=,%LE\n", firstx);
fprintf(foutheaderp, "##LASTX=,%LE\n", lastx);
fprintf(foutheaderp, "##NPOINTS=,%d\n", npoints);
fprintf(foutheaderp, "##FIRSTY=,%LE\n", firsty);
fprintf(foutheaderp, "##XYDATA=,%s\n", xydata);
/* データ部の書き込み */
for (i = 0; i < lasti; i++)
fprintf(foutdatap, "%LE,%LE\n", xdata[i], ydata[i]);
}
/*
* ファイルを閉じる関数
*/
void close_f(void)
{
fclose(finp);
fclose(foutheaderp);
fclose(foutdatap);
}
/*
* 操作を続けるかどうかを選択する関数
* true: 繰り返す、false: 終了する
*/
bool retry(void)
{
bool ret;
char buf[BUF_SIZE], ch, zz;
while (1) {
printf("続けますか?(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;
}
##TITLE= サンプルA
##JCAMP-DX= 4.24
##DATA TYPE= INFRARED SPECTRUM
##ORIGIN=
##OWNER=
##DATE= 02/03/22
##TIME= 17:44:19
##SPECTROMETER/DATA SYSTEM= JEOL WIN SPEC-50
##RESOLUTION= 4.0
##DELTAX= 1.928490E+00
##XUNITS= 1/CM
##YUNITS= TRANSMITTANCE
##XFACTOR= 1.000000E+00
##YFACTOR= 1.926880E-06
##FIRSTX= 399.1975
##LASTX= 3999.6887
##NPOINTS= 1868
##FIRSTY= 3.631946E-02
##XYDATA= (X++(Y..Y))
399.197 26095 25108 25437 25631 25573 25621 24846 24722 25099 24592 23281
420.411 23563 23951 23787 23732 23232 23134 23881 24190 23855 24527 25102
(中略)
3963.047 24014 24130 24118 24070 24044 24051 24046 24077 24141 24147 24103
3984.261 24129 24086 24099 24118 24166 24129 24121 24119 24118
##END=
D:\test>convdx
【JCAMP-DX形式ファイル変換プログラム】
JCAMP-DX形式のスペクトルデータ(*.dx)を変換し、新たな2種類のCSVファイル
(ヘッダファイル{*h.csv}とデータファイル{*d.csv})として出力します。
入力ファイルの名前(*.dx)を入力してください。
sk232201.d
ファイル名が正しくありません。
入力ファイルの名前(*.dx)を入力してください。
sk232201.dx
続けますか?(y/n) n
D:\test>dir
(中略)
2023-05-14 08:14 138,240 convdx.exe
2002-03-22 17:57 13,146 SK232201.DX ←元のJCAMP-DXファイル(*.dx)
2023-05-14 08:16 50,436 sk232201d.csv ←作成されたデータファイル(*d.csv)
2023-05-14 08:16 430 sk232201h.csv ←作成されたヘッダファイル(*h.csv)
##TITLE=,サンプルA
##JCAMP-DX=,4.24
##DATA TYPE=,INFRARED SPECTRUM
##ORIGIN=,
##OWNER=,
##DATE=,02/03/22
##TIME=,17:44:19
##SPECTROMETER/DATA SYSTEM=,JEOL WIN SPEC-50
##RESOLUTION=,4.0
##DELTAX=,1.928490E+00
##XUNITS=,1/CM
##YUNITS=,TRANSMITTANCE
##XFACTOR=,1.000000E+00
##YFACTOR=,1.926880E-06
##FIRSTX=,3.991975E+02
##LASTX=,3.999689E+03
##NPOINTS=,1868
##FIRSTY=,3.631946E-02
##XYDATA=,(X++(Y..Y))
3.991975E+02,5.028193E-02
4.011260E+02,4.838010E-02
4.030545E+02,4.901405E-02
4.049830E+02,4.938786E-02
4.069115E+02,4.927610E-02
(中略)
3.991974E+03,4.656498E-02
3.993903E+03,4.649369E-02
3.995831E+03,4.647827E-02
3.997760E+03,4.647442E-02
3.999688E+03,4.647249E-02