Как вызвать две программы на Си из одной программы на Си? - PullRequest
1 голос
/ 22 января 2010

Как я могу вызвать два приложения C из другого приложения C?

например. :

pg1.c can be run as ./a.out pg1_args

pg2.c can be run as ./a.out pg2_args

Я хотел бы написать программу, которая может быть запущена как:

./a.out pg1_args pg2_args

С результатом, эквивалентным:

./a.out pg1_args

./a.out pg2_args

./a.out pg1_args

./a.out pg2_args

pg1 здесь svm_scale, а pg2 здесь svm_predict, оба взяты из libsvm: http://www.csie.ntu.edu.tw/~cjlin/libsvm/

[редактировать]

@ Джонатан,

Я написал эти программы для опробования этой концепции ..

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 first second
Segmentation fault (core dumped)
[root@localhost trinity]# 

Может кто-нибудь объяснить, что я сделал не так?

Ответы [ 4 ]

4 голосов
/ 22 января 2010

Из вашего последнего кода, вот ваша проблема:

const char *cmd1 = strcat("./pg1 ",argv[1]);
const char *cmd2 = strcat("./pg2 ",argv[2]);

Это плохо по нескольким причинам (строковые литералы обычно помещаются в постоянную память, и им не выделяется память для объединения новых данных в конце).

Измените это на:

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]);
4 голосов
/ 22 января 2010

Очень простое решение - использовать функцию system (). Передайте ей командную строку программы.

1 голос
/ 22 января 2010
const char *cmd1 = strcat("./pg1 ",argv[1]);
const char *cmd2 = strcat("./pg2 ",argv[2]);

неправильно. "./pg1 " - строка только для чтения. Вы не можете ничего добавить к этому. У вас нет доступа к памяти после того, как строка "./pg1 " все равно заканчивается. Итак, вам нужно получить доступ к памяти, где вы можете записать свои строки.

Попробуйте:

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]);

и затем не забудьте освободить память, когда закончите. Или вы можете объявить их как массивы с достаточно большим размером:

char cmd1[32] = "./pg1 ";
char cmd1[32] = "./pg2 ";
strcat(cmd1, argv[1]);
strcat(cmd1, argv[2]);

, но вышесказанное будет плохо, если в cmd1 или cmd2.

недостаточно места.
1 голос
/ 22 января 2010

Вероятно, самый простой метод состоит в том, чтобы построить два вызова (действительно ли обе «разные» программы называют a.out?) В виде строки и затем использовать функцию system():

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...

Очевидно, что вы обычно строите эти командные строки из аргументов, передаваемых в вашу программу, а не жестко их соединяете, как показано. Просто будьте осторожны с переполнением буфера и неожиданными символами при построении командной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...