본문 바로가기

c언어 문법

c언어 파일 입출력

c언어 프로그램에서 그래프를 그려야할 일이 있었다. 그래프를 그리기 위해 좌표를 각각 메모장에 저장하고 그래프를 그리는 코드를 작성했다. 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
struct React {
    double k;
    int m;
    double Ai;
}; //속도 상수, 반응 차수, 초기 농도를 저장하는 구조체 
double V(const struct React* info) {
    return info->k * pow(info->Ai, info->m);
} //반응 속도를 계산해주는 함수 
double HalfLife1(const struct React* info) {
    double ln2 = 0.6931471805599453;
    return ln2 / (info->k);
} //1차 반응의 반감기 계산 함수 
double HalfLife2(const struct React* info) {
    return 1 / (info->k * info->Ai);
} //2차 반응의 반감기 계산 함수 
double HalfLife0(const struct React* info) {
    return (info->Ai) / (info->k * 2);
} //0차 반응의 반감기 계산 함수 
double calculate_At(const struct React* info, double time) {
    if (info->m == 0) {
        return (info->Ai) - (info->k) * time;
    }
    else if (info->m == 1) {
        double e = 2.718281828459045;
        return (info->Ai) * pow(e, -(info->k) * time);
    }
    else {
        return 1 / (1 / (info->Ai) + (info->k) * time);
    }
} /*시간에 따른 농도 출력 함수
-------------------------------------------------------------------------------------------------*/
int main() {
    struct React reaction;
    printf("전체 반응 차수 입력: ");
    scanf("%d", &reaction.m);
    while (1) {
        if (reaction.m < 0 || reaction.m >2) {
            printf("반응차수는 0, 1, 2차만 지원합니다.\n");
            printf("전체 반응 차수 입력: ");
            scanf("%lf", &reaction.m);
        }
        else {
            break;
        }
    }
    printf("속도 상수 입력(M^%d/s): ", 1 - reaction.m);
    scanf("%lf", &reaction.k);
    while (1) {
        if (reaction.k < 0) {
            printf("다시하세요\n");
            printf("속도 상수 입력(M^%d/s): ", 1 - reaction.m);
            scanf("%lf", &reaction.k);
        }
        else {
            break;
        }
    }
    printf("초기 농도 입력(M): ");
    scanf("%lf", &reaction.Ai);
    while (1) {
        if (reaction.Ai < 0) {
            printf("다시 하세요\n");
            printf("초기 농도 입력(M): ");
            scanf("%lf", &reaction.Ai);
        }
        else {
            break;
        }
    }

    //사용자로부터 반응차수, 속도상수, 초기농도를 입력받아 구조체변수 reaction에 저장 

    FILE* gnuplotPipe = _popen("\"C:\\Program Files\\gnuplot\\bin\\gnuplot.exe\" -persist", "w");
    if (!gnuplotPipe) {
        fprintf(stderr, "Error opening Gnuplot pipe!\n");
        return 1;
    }
    system("gnuplot -persist plot_");
    FILE* noteFile;
    noteFile = fopen("result.txt", "w");
    if (noteFile == NULL) {
        return 1;
    }

    double rate = V(&reaction);
    printf("\n초기 반응 속도 =  k[Ai]^m = %.4lf (M/s)\n", rate);
    // 초기 반응 속도를 계산하여 rate에 저장 및 출력 
    double halfLife;
    if (reaction.m == 0) {
        halfLife = HalfLife0(&reaction);
        printf("반감기= [Ai]/2*k = %.7lf (s)\n", halfLife);
    }
    else if (reaction.m == 1) {
        halfLife = HalfLife1(&reaction);
        printf("반감기= ln2/k = %.7lf (s)\n", halfLife);
    }
    else {
        halfLife = HalfLife2(&reaction);
        printf("반감기= 1/k*[Ai] = %.7lf (s)\n", halfLife);
    }
    //반응 차수에 따라 다른 반감기 공식을 적용하여 반감기 계산 및 출력 
    printf("\n<시간에 따른 농도>\n");
    for (double time = 0; time <= 10; time += 0.125) {
        double concentration = calculate_At(&reaction, time);
        if (concentration >= 0) {
            printf("%.3lf초후 농도: %.7lf (M)\n", time, concentration);
            fprintf(noteFile, "%.3lf, %.7lf\n", time, concentration);
        }
        else {
            break;
        }
    }
    // 0초부터 10초까지 0.125초 간격으로 시간에 따른 농도 계산(농도가 0보다 작아지면 끝)  
    fprintf(gnuplotPipe, "set terminal wxt persist\n");
    fprintf(gnuplotPipe, "set xrange [0:10]\n");
    fprintf(gnuplotPipe, "set xlabel 'time'\n");
    fprintf(gnuplotPipe, "set ylabel 'Concentration'\n");
    fprintf(gnuplotPipe, "plot 'result.txt' with lines title 'Concentration'\n");
    fclose(noteFile);
    //그래프 출력
}

 

*그래프를 출력하기 위해서...

1) gnuplot을 다운로드 받아야함.

2) 코드에서 명시해놓은 gnuplot.exe file의 경로를 다시한번 확인하고 입력하도록 하자.

3) stdlib.h 헤더파일을 불러와야함