在C程序中调用其他C程序:system()与execv()使用故障求助
问题分析与解决方案
我来帮你理清楚这里的问题哈~你想要调用另一个程序后回到原程序继续执行,这两个函数的特性其实差异很大,咱们一个个说:
为什么execv没达到你的预期?
首先要明确:execv系列函数会直接用新程序替换当前进程的全部内存空间,一旦execv调用成功,当前进程里在execv之后的代码(比如你写的put...)根本不会有机会执行!而且你传的参数也有问题——execv的第二个参数必须是一个字符串数组,第一个元素是程序名,最后以NULL结尾,你直接传NULL会导致调用失败。
system函数的正确使用方式
system函数才是符合你需求的选择:它会自动创建一个子进程来执行指定的命令,子进程执行完后,控制流会回到父进程(也就是你的调用程序)继续运行。如果之前用system没得到预期结果,大概率是这几个原因:
- test1程序没正确编译,或者路径不对(比如你运行调用程序时,当前目录下有没有
./test1?) - test1没有可执行权限(需要执行
chmod +x test1) - 输出缓冲区的问题(不过puts是行缓冲,一般不会有这个问题)
先给你补全完整的代码:
被调用程序 test1.c
#include <stdio.h> #include <stdlib.h> // 必须包含这个头文件才能用EXIT_SUCCESS int main(void) { puts("executing this prog from another prog"); return EXIT_SUCCESS; }
调用程序(用system)
#include <stdio.h> #include <stdlib.h> int main(void) { // 调用system并检查返回值,方便排查错误 int result = system("./test1"); if (result == -1) { perror("Failed to execute system command"); return EXIT_FAILURE; } // 这里的代码会在test1执行完后运行 puts("Back to the calling program after system()!"); return EXIT_SUCCESS; }
如果你非要用execv(需要配合fork)
要是你因为某些原因必须用execv,那一定要先通过fork()创建子进程,在子进程里调用execv,父进程等待子进程结束,这样才能保证原程序继续执行。代码示例如下:
调用程序(用execv+fork)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main(void) { pid_t child_pid = fork(); if (child_pid == -1) { perror("Failed to fork child process"); return EXIT_FAILURE; } else if (child_pid == 0) { // 这是子进程,执行execv char *args[] = {"./test1", NULL}; // 正确的参数格式 execv("./test1", args); // 如果走到这里,说明execv调用失败了 perror("execv failed to run test1"); exit(EXIT_FAILURE); } else { // 父进程等待子进程执行完毕 wait(NULL); puts("Back to the calling program after child process finished!"); } return EXIT_SUCCESS; }
编译运行步骤
不管用哪种方式,都要先正确编译程序:
- 编译test1:
gcc test1.c -o test1 - 给test1加可执行权限:
chmod +x test1 - 编译调用程序(假设叫caller.c):
gcc caller.c -o caller - 运行调用程序:
./caller
这样就能看到test1的输出,然后看到原程序后续的输出啦~
内容的提问来源于stack exchange,提问作者karra
相关产品推荐
相关产品推荐

