How can I call two C applications from within another C application?
e.g. :
pg1.c can be run as ./a.out pg1_args
pg2.c can be run as ./a.out pg2_args
I would like to write a program that can be run as:
./a.out pg1_args pg2_args
With the result being equivalent to :
./a.out pg1_args
./a.out pg2_args
./a.out pg1_args
./a.out pg2_args
the pg1 here is svm_scale and pg2 here is svm_predict , both taken from libsvm : http://www.csie.ntu.edu.tw/~cjlin/libsvm/
[ edit ]
@Jonathan ,
I wrote these programs for trying out this concept..
pg1.c
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
FILE *fin;
fin=fopen("pg1file.txt","a");
fprintf(fin,"%s",argv[1]);
fflush(fin);
fclose(fin);
}
pg2.c
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
FILE *fin;
fin=fopen("pg2file.txt","a");
fprintf(fin,"%s",argv[1]);
fflush(fin);
fclose(fin);
}
pg3.c :
#include<stdio.h>
#include<string.h>
int main(int argc,char **argv)
{
int i;
const char *cmd1 = strcat("./pg1 ",argv[1]);
const char *cmd2 = strcat("./pg2 ",argv[2]);
for(i=0;i<4;i++)
{
if (system(cmd1) != 0)
printf("\n error executing pg 1");
if (system(cmd2) != 0)
printf("\n error executing pg 2");
}
}
[root@localhost trinity]# ./a.out fi开发者_如何学编程rst second
Segmentation fault (core dumped)
[root@localhost trinity]#
Could somebody explain what I've done wrong?
From your latest code, here is your problem:
const char *cmd1 = strcat("./pg1 ",argv[1]);
const char *cmd2 = strcat("./pg2 ",argv[2]);
That's bad for a couple of reasons (string literals are usually put in read only memory and they to do not have memory allocated for concatenating new data at the end).
Change that to:
size_t len = snprintf(NULL, 0, "./pg1 %s", argv[1]);
char *cmd1 = malloc(len + 1);
snprintf(cmd1, len, "./pg1 %s", argv[1]);
size_t len = snprintf(NULL, 0, "./pg2 %s", argv[2]);
char *cmd2 = malloc(len + 1);
snprintf(cmd2, len, "./pg2 %s", argv[2]);
A very simple solution is to use the system() function. Pass a program's command line to it to run the program.
Probably the simplest technique is to build the two calls (are the two 'different' programs really both called a.out?) as a string and then use the system()
function:
const char *cmd1 = "./a.out pg1_args";
const char *cmd2 = "./a.out pg2_args";
if (system(cmd1) != 0)
...report trouble...
if (system(cmd2) != 0)
...report trouble...
Clearly, you would normally build those command lines from the arguments passed to your program, rather than hard-wiring them as shown. Just be wary of buffer overflows and unexpected characters when you build the command lines.
const char *cmd1 = strcat("./pg1 ",argv[1]);
const char *cmd2 = strcat("./pg2 ",argv[2]);
is wrong. "./pg1 "
is a read-only string. You can't append anything to it. You haven't got access to the memory after the string "./pg1 "
ends anyway. So, you need to get access to memory where you can write your strings.
Try:
char *cmd1 = malloc(strlen("./pg1 ") + strlen(argv[1]) + 1);
char *cmd2 = malloc(strlen("./pg2 ") + strlen(argv[2]) + 1);
if (cmd1 == NULL || cmd2 == NULL) { /* deal with error */ }
sprintf(cmd1, "./pg1 %s", argv[1]);
sprintf(cmd1, "./pg1 %s", argv[1]);
and then remember to free the memory when you're done. Or you can declare them as arrays with a big enough size:
char cmd1[32] = "./pg1 ";
char cmd1[32] = "./pg2 ";
strcat(cmd1, argv[1]);
strcat(cmd1, argv[2]);
but the above will be bad if there is not enough space in cmd1
or cmd2
.
精彩评论