can we compile b.cpp by running a.cpp?

i have koolplot project to draw plot.
this plot should appear in the middle of the program, and if the plot is closed, the whole program terminates immadiately. To avoid that, i tried to make 2 cpp files. One for the main, and the other one for creating the plot. Let's say the main is main.cpp, and one is plot.cpp.

User can input the function in main.cpp, and the plot.cpp should redraw the plot for different input. The problem is, after user input the function, plot.cpp should be recompiled again in order to be able to run plot.exe.

can someone help me with that? or do you have other suggestions rather than separate it into 2 files?

Thanks

Recommended Answers

All 12 Replies

can we compile b.cpp by running a.cpp?

i have koolplot project to draw plot.
this plot should appear in the middle of the program, and if the plot is closed, the whole program terminates immadiately. To avoid that, i tried to make 2 cpp files. One for the main, and the other one for creating the plot. Let's say the main is main.cpp, and one is plot.cpp.

User can input the function in main.cpp, and the plot.cpp should redraw the plot for different input. The problem is, after user input the function, plot.cpp should be recompiled again in order to be able to run plot.exe.

can someone help me with that? or do you have other suggestions rather than separate it into 2 files?

Thanks

I really doubt that the answer is to recompile anything during runtime. I'm guessing a program redesign would be a better solution. You can use the dreaded system command, or better would be to run a shell command. I've never run a shell command from C++ in Windows. in Linux, you'd run execvp or something similar. I'm sure there's a Windows equivalent.

If you wanted to use the system command, you could probably stick this line in your program:

system ("g++ plot.cpp -o plot.exe");

Please do a google on the system command for all the reasons why it can be a really bad idea. Basically I'm giving you an answer, but also suggesting you not use it, if that makes sense. Definitely research the Windows equivalent of execvp. It's preferred. But system is quick and easy to use.

And to reiterate, compiling during the program really sounds like a bad idea. There's gotta be a better way.

I think you need to display the plot in a separate thread. This operation will vary from OS to OS.

thanks a lot guys.
@daviddoria : i will try the multi threading first, seems it's simpler.

@VernonDozier : i think that can't work. the koolplot always terminate immediately. I think the library koolplot.h must be changed, to terminate the koolplot and return to main function. What do you think bout that?

thanks a lot guys.
@daviddoria : i will try the multi threading first, seems it's simpler.

@VernonDozier : i think that can't work. the koolplot always terminate immediately. I think the library koolplot.h must be changed, to terminate the koolplot and return to main function. What do you think bout that?

I've never used koolplot, so I have no experience at all on how to make it work. Researching online, it looks like you may need something called Quincy? I'm not familiar with Quincy either. I am familiar with C++ and using external libraries and how programs terminate, though, and based on that, I'm really skeptical that anything should be recompiled during execution in order to keep the program from terminating. In particular, your comment about koolplot.h changing seems highly doubtful to me. If koolplot.h is a library provided by whoever created koolplot, and it appears that it is, it seems highly unlikely that it would change in the middle of your program. In fact, I almost guarantee that it doesn't.

With no familiarity with koolplot and not seeing your code, it's very hard to speculate.

i have solved the problem with multi threading :D

so in the new thread, i can process different graph and create new graph. now i only have 1 problem left, to kill the existing thread.

yes i use quincy 2005. 1 thing i don't like from this koolplot is, if i close the graph window, the cmd window will terminate too. now i'm looking a way to overcome that.

oh, sorry sir, here is the code :

#include<iostream>
#include<math.h>
#include<string.h>
#include<iomanip>
#include<windows.h>
#include<process.h>
#include<vector>
#include "koolplot.h"
using namespace std;

string post[100];  //menampung bentuk postfix dari fungsi yang diinput user
int ukuranPost=0;  //banyak sel post yang terisi
string input;
double xkiri,xkanan;

double shunting(double); //shunting-yard algorithm
void postfix();  //mengubah infix menjadi postfix
double convert(string);  //mengubah angka dalam string menjadi angka dalam double
double satuOperand(string,double);  //operasi aritmatik dengan 1 operand
double duaOperand(string,double,double);  //operasi aritmatik dengan 2 operand
void grafik(void*); //metode grafik beta
void bisection(double); //metode bisection
void falsePosition(double);  //metode false position
void secant(double);  //secant methods

double convert(string inputnya)
{
    int start=inputnya.length();
    double total=0;
    for (int i=0;i<inputnya.length();i++)
    {
        if(inputnya[i]=='.')
            start=i;
    }
    if(start==inputnya.length()) //tidak ada koma
    {
        for(int i=0;i<start;i++)
        {
            total+=(int(inputnya[i])-48)*pow(10.0,start-i-1);
        }
    }
    else
    {
        for(int i=0;i<start;i++)
        {
            total+=(int(inputnya[i])-48)*pow(10.0,start-i-1);
        }
        for(int i=start+1;i<inputnya.length();i++)
        {
            total+=(int(inputnya[i])-48)*pow(10.0,start-i);
        }
    }
    return total;
}

double satuOperand(string operatorr,double operand)
{
    if (operatorr=="sin")
        return sin(operand);
    else if (operatorr=="cos")
        return cos(operand);
    else if (operatorr=="tan")
        return tan(operand);
    else if (operatorr=="log")
        return log10(operand);
    else if (operatorr=="ln")
        return log(operand);
}

double duaOperand(string operatorr, double operand1, double operand2)
{
    if (operatorr=="+")
        return (operand1+operand2);
    else if (operatorr=="-")
        return (operand1-operand2);
    else if (operatorr=="*")
        return (operand1*operand2);
    else if (operatorr=="/")
        return (operand1/operand2);
    else if (operatorr=="^")
        return (pow(operand1,operand2));
}

int prioritas(string operatorr)
{
    if (operatorr=="sin" || operatorr=="cos" || operatorr=="tan" || operatorr=="log" || operatorr=="ln")
        return 1;
    else if (operatorr=="^")
        return 2;
    else if (operatorr=="*" || operatorr=="/")
        return 3;
    else if (operatorr=="+" || operatorr=="-")
        return 4;
    else
    {
        //tidak mungkin terjadi, karena asumsi tidak ada error handling
    }
}


void postfix()
{
     string stack[100];
     int flagPost=0;
     int flagStack=0;
     
     for (int i=0;i<input.length();i++)
     {
         int mark=i;
         if (isdigit(input[i]))
         {
             while(isdigit(input[i+1]) || input[i+1]=='.')
             {
                  i++;
             }
             post[flagPost]=input.substr(mark,i-mark+1);
             flagPost++;
         }
         else if(input[i]=='-' && i==0 || input[i]=='-' && !isdigit(input[i-1]) && input[i-1]!='x' && input[i-1]!=')')
         {
              input=input.substr(0,i)+"(0-1)*"+input.substr(i+1);
              i--;
         }
		 else if(input[i]=='x')
		 {
			 post[flagPost]="x";
			 flagPost++;
		 }
		 else if(input[i]=='(')
		 {
              stack[flagStack]="(";
              flagStack++;
         }
         else if(input[i]==')')
         {
              while (stack[flagStack-1]!="(")
              {
                    post[flagPost]=stack[flagStack-1];
                    flagPost++;
                    flagStack--;
              }
              if(flagStack>0)
                    flagStack--;
         }
         else
         {
             if (!isalpha(input[i]))
             {
                  //bengong
             }
             else
             {
                  while(!isdigit(input[i+1]) && input[i+1]!='x' && input[i+1]!='(')
                  {
                       i++;
                  }
             }
             string tmp = input.substr(mark,i-mark+1);
             
             //push ke stack operator
             if (flagStack==0 || stack[flagStack-1]=="(")  //stack kosong, langsung push
             {
                  stack[flagStack]=tmp;
                  flagStack++;  //flag top stack
             }
/*             else if(flagStack!=0 && stack[flagStack-1]=="(")  // langsung push kalo ketemu kurung buka
             {
                  stack[flagStack]=tmp;
                  flagStack++;
             }
*/
             else
             {   //prioritas diperhatikan
                 int stackOpTrakir = prioritas(stack[flagStack-1]); //priortitas top stack
                 while (prioritas(tmp)>=stackOpTrakir && stack[flagStack-1]!="(")
                 {
                      post[flagPost]=stack[flagStack-1];
                      flagPost++;
                      flagStack--;
                      if(flagStack==0)
                          break;
                      else
                          stackOpTrakir = prioritas(stack[flagStack-1]);
                 }
                 stack[flagStack]=input.substr(mark,i-mark+1);
                 flagStack++;
             }
         }
         //cout<<"iterasi "<<i<<endl;
         //cout<<"post  : ";
         //for (int b=0;b<flagPost;b++)
         //    cout<<post[b]<<" ";
         //cout<<endl;
         //cout<<"stack : ";
         //for (int b=0;b<flagStack;b++)
         //    cout<<stack[b]<<" ";
         //cout<<endl<<endl;
     }
     for (int i=flagStack-1;i>=0;i--)
     {
         post[flagPost]=stack[i];
         flagPost++;
     }
     cout<<endl;
     
     //block ini berguna untuk memeriksa hasil postfix
     //for (int a=0;a<flagPost;a++)
     //{
     //    cout<<post[a]<<endl;
     //}
     
     
     //menghitung berapa isi sel post yang terpakai
     //berguna pada fungsi int shunting di bawah
     while(post[ukuranPost]!="")
     {
         ukuranPost++;
     }

}

double shunting(double x)
{
    double tmp[100];
    int flagTmp=0;
    //flagTmp menunjuk ke sel yang akan diisi
    //flagStack dan flagPost menunjuk ke sel yang akan diisi
    
    for (int i=0;i<ukuranPost;i++)
    {
        if (isdigit(post[i][0]))
        {
            //ubah menjadi integer            //masukan ke stack tmp;
            tmp[flagTmp]=convert(post[i]);
            flagTmp++;
        }
        else if(post[i]=="x")
        {
             //post int x ke stack tmp;
             tmp[flagTmp]=x;
             flagTmp++;
        }
        else
        {
            //bagian2 operator
            if(post[i]=="sin" || post[i]=="cos" || post[i]=="tan" || post[i]=="log" || post[i]=="ln")
            {    //1 operand
                tmp[flagTmp-1]=satuOperand(post[i],tmp[flagTmp-1]);
            }
            else
            {
                tmp[flagTmp-2]=duaOperand(post[i],tmp[flagTmp-2],tmp[flagTmp-1]);
                flagTmp--;
            } 
        }
    }
    return tmp[0];
}

void grafik(void* arg)
{
	//Plotdata x(xkiri,xkanan),y=sin(x);
	vector<double> vx,vy;
	for (double x=xkiri;x<=xkanan;x+=0.001)
	{
		vx.push_back(x);
		vy.push_back(shunting(x));
	}
	plot(vx,vy);
}

void bisection(double es)
{
    double ea=100; //approximation error
    int iterasi=0; //menghitung berapa iterasi yang diperlukan
    
    //Bagian ini adalah bisection
    cout<<"\n\nMetode pertama : Bisection\n";
    double xl,xr,xm; //xl adalah x left, xr adalah x right, dan xm adalah x mid
    cout<<"Masukkan nilai x kiri : ";
    cin>>xl;
    cout<<"Masukkan nilai x kanan : ";
    cin>>xr;
    
    double fxl,fxr,fxm; //f(xl),f(xr),f(xm)
    fxl=shunting(xl);
    fxr=shunting(xr);
    cout<<fxl<<" "<<fxr<<endl;
    while(fxl*fxr>=0)
    {
        if(fxl==0)
        {
            cout<<"Akarnya adalah "<<xl<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto bisectionoff;
        }
        else if (fxr==0)
        {
            cout<<"Akarnya adalah "<<xr<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto bisectionoff;
        }
        else if (xl==xr)
        {
            cout<<"Input xl dan xr dengan angka yang berbeda, harap diulangi.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
        else
        {
            cout<<"Tidak ada akar di antara "<<xl<<" dan "<<xr<<endl;
            cout<<"Coba ulangi dengan kombinasi xl dan xr yang berbeda.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
    }
    //sampai sini input f(xl)*f(xr) sudah lebih kecil dari nol. Inisialisasi selesai.
    double tampung; //menampung xm pada iterasi sebelumnya.
    printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n","xl","xm","xr","f(xl)","f(xm)","f(xr)","ea");
    while(ea>es)
    {
        iterasi++;
        xm=(xl+xr)/2;
        if(iterasi>1)
        {
            ea=fabs((xm-tampung)/xm)*100;
        }
        fxm=shunting(xm);
        printf("%-11f %-11f %-11f %-11f %-11f %-11f %-11f\n",xl,xm,xr,fxl,fxm,fxr,ea);
        if(fxl*fxm<0)
        {
            xr=xm;
            fxr=shunting(xr);
        }
        else
        {
            xl=xm;
            fxl=shunting(xl);
        }
        tampung=xm;
    }
    cout<<"Akarnya adalah : "<<xm<<" dan ditemukan pada iterasi ke-"<<iterasi<<endl;
bisectionoff:
             ;
}

void falsePosition(double es)
{
    double ea=100; //approximation error
    int iterasi=0; //menghitung berapa iterasi yang diperlukan
    
    //Bagian ini adalah bisection
    cout<<"\n\nMetode kedua : False Position\n";
    double xl,xr,xm; //xl adalah x left, xr adalah x right, dan xm adalah x mid
ulangfalse: ;
    ea=100;
    iterasi=0;    
    cout<<"Masukkan nilai x kiri : ";
    cin>>xl;
    cout<<"Masukkan nilai x kanan : ";
    cin>>xr;
    
    double fxl,fxr,fxm; //f(xl),f(xr),f(xm)
    fxl=shunting(xl);
    fxr=shunting(xr);
    while(fxl*fxr>=0)
    {
        if(fxl==0)
        {
            cout<<"Akarnya adalah "<<xl<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto falseoff;
        }
        else if (fxr==0)
        {
            cout<<"Akarnya adalah "<<xr<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto falseoff;
        }
        else if (xl==xr)
        {
            cout<<"Input xl dan xr dengan angka yang berbeda, harap diulangi.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
        else
        {
            cout<<"Tidak ada akar di antara "<<xl<<" dan "<<xr<<endl;
            cout<<"Coba ulangi dengan kombinasi xl dan xr yang berbeda.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
    }
    //sampai sini input f(xl)*f(xr) sudah lebih kecil dari nol. Inisialisasi selesai.
    double tampung; //menampung xm pada iterasi sebelumnya.
    printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n","xl","xm","xr","f(xl)","f(xm)","f(xr)","ea");
    while(ea>es)
    {
        iterasi++;
        xm=xr-fxr*(xl-xr)/(fxl-fxr);
        if(iterasi>1)
        {
            ea=fabs((xm-tampung)/xm)*100;
        }
        fxm=shunting(xm);
        printf("%-11f %-11f %-11f %-11f %-11f %-11f %-11f\n",xl,xm,xr,fxl,fxm,fxr,ea);
        if(fxl*fxm<0)
        {
            xr=xm;
            fxr=shunting(xr);
        }
        else
        {
            xl=xm;
            fxl=shunting(xl);
        }
        tampung=xm;
        if(iterasi==5000)
        {
            cout<<"Kombinasi xl dan xr ini tidak memungkinkan kita memperoleh akarnya.\n";
            cout<<"Coba ulangi dengan kombinasi xl dan xr yang berbeda.\n";
            goto ulangfalse;
        }
    }
    cout<<"Akarnya adalah : "<<xm<<" dan ditemukan pada iterasi ke-"<<iterasi<<endl;
falseoff:
             ;
}

void secant(double es)
{
    double ea=100; //approximation error
    int iterasi=0; //menghitung berapa iterasi yang diperlukan
    
    //Bagian ini adalah secant methods
    cout<<"\n\nMetode ketiga : Secant Methods\n";
    double x1,x2,x3; //xl adalah x left, xr adalah x right, dan xm adalah x mid
    cout<<"Masukkan dua buah nilai x untuk inisialisasi.\n";
ulangsecant:
            ;
    ea=100;
    iterasi=0; 
    cout<<"x1 = "; cin>>x1;
    cout<<"x2 = "; cin>>x2;
    
    double fx1,fx2,fx3; //f(xl),f(xr),f(xm)
    fx1=shunting(x1);
    fx2=shunting(x2);
    while(fx1==0 ||fx2==0 || x1==x2)
    {
        if(fx1==0)
        {
            cout<<"Akarnya adalah "<<x1<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto secantoff;
        }
        else if (fx2==0)
        {
            cout<<"Akarnya adalah "<<x2<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto secantoff;
        }
        else if (x1==x2)
        {
            cout<<"Input x1 dan x2 dengan angka yang berbeda, harap diulangi.\n";
            cout<<"Masukkan nilai x1 : ";
            cin>>x1;
            cout<<"Masukkan nilai x2 : ";
            cin>>x2;
            fx1=shunting(x1);
            fx2=shunting(x2);
        }
    }
    //sampai sini input f(xl)*f(xr) sudah lebih kecil dari nol. Inisialisasi selesai.
    printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n","x1","x2","x3","f(x1)","f(x2)","f(x3)","ea");
    while(ea>es)
    {
        iterasi++;
        x3=x2-fx2*(x1-x2)/(fx1-fx2);
        if(iterasi>1)
        {
            ea=fabs((x3-x2)/x3)*100;
        }
        fx3=shunting(x3);
        printf("%-11f %-11f %-11f %-11f %-11f %-11f %-11f\n",x1,x2,x3,fx1,fx2,fx3,ea);
        x1=x2;
        x2=x3;
        fx1=shunting(x1);
        fx2=shunting(x2);
        if(iterasi==5000)
        {
            cout<<"Tidak ada akar yang bisa ditemukan dengan kombinasi x1 dan x2 ini.\n";
            cout<<"Coba masukkan kombinasi yang lain.\n";
            goto ulangsecant;
        }
    }
    cout<<"Akarnya adalah : "<<x3<<" dan ditemukan pada iterasi ke-"<<iterasi<<endl;
secantoff:
          ;
}

int main()
{ 
    cout<<"\t\tSelamat Datang di Program Penarikan Akar Secara Numerik\n\n";
    cout<<"Masukkan fungsi dalam x yang hendak dicari akarnya.\nJangan lupa membaca petunjuk pada laporan."<<endl;
    cout<<"Fungsi : ";
    cin>>input; //infix
    postfix(); //mengubah input menjadi postfix
    
    double s; //s adalah jumlah bilangan signifikan yang diinginkan
    double es; //prespecified error
    
    cout<<"Masukkan jumlah bilangan signifikan yang diinginkan : ";
    cin>>s;
    es=0.5*pow(10,2-s);
    
    //tes metode grafik
	char ulang='Y'; //menentukan apakah user akan mencoba grafik dengan batas x yang lain
	
	while (ulang=='Y' || ulang=='y')
	{
		cout<<"Masukkan nilai x kiri dan x kanan : ";
		cin>>xkiri;
		cin>>xkanan;
		_beginthread( grafik, 0, (void*)12 );
		cin>>ulang;
		_endthread;
	}
	
	//mengerjakan bagian bisection
    bisection(es);
    
    //mengerjakan bagian false position
    falsePosition(es);
    
    //mengerjakan bagian secant
    secant(es);
        
    cin>>input;
    return 0;
}

i'm sorry, the comments are written in bahasa indonesia.
thanks a lot.

the standard koolplot says that it can be :
Plotdata x(0,0), y=sin(x);

but since i design the program to read function y from user input, i use vector instead of that Plotdata type.

if we build koolplot with a graph window, then if the graph is closed, the entire code will terminate.
can we close the graph without terminate the program?

The problem appears to be in winbgim.a -- The function cls_OnClose() calls exit(). If you download the source to that library you can change that behavior. But if you do that it may have other unintentional consequences, such as memory leaks.

commented: Nice answer! +14

If you are lucky and if you haven't change the code very much you could get 0 memory leaks. You should make a backup.

If you are lucky and if you haven't change the code very much you could get 0 memory leaks. You should make a backup.

The memory leaks I was talking about was in the libraries, not the OPs program. The writers of those libraries may have just been too lazy to clean up after themselves when finished.

I tried to compile those libraries and had to change the file extensions from *.c to *.cpp in order to get them to compile with Code::Blocks because they contained c++ code. I don't know how the authors ever got them to compile as C files.

i'm afraid to change the library and mess things up. so i let the graphics windows opened. But i'm afraid about memory and processing time.
i have reduced the loop needed to draw, from 100000 times to about 1000 times, and it still needs more than 5s to draw sin(x)+x^2 in x E (0,100). if i try to repeat the program, means adding new graphic window, i'm afraid that it will consumes lot of memories, since the unused graphic windows still open.

about changing the library, i will try to see it.

anyway, thanks all guys. my project's deadline is about 5 hours again. this daniweb.com really helps me, especially with information about koolplot.h.

thank you very much guys.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.