【问题标题】:Run a C program from within a C program从 C 程序中运行 C 程序
【发布时间】:2015-02-17 01:18:44
【问题描述】:

这个问题本身就很好解释了我有三个不同的 C 程序并尝试比较它们的效率我尝试通过让它们运行几次来改变它们的参数(与所用时间成正比)来测试它们的运行时间并写下它需要多长时间让每个程序针对特定参数运行(以便稍后我可以绘制结果)。

以下是我的代码

   # include <stdio.h> 
    # include <stdlib.h>
    # include <math.h>
    # include <time.h>  

   int main(void){

    int i;
    struct timeval bni, bmi, bfi, bnf, bmf, bff;
    FILE *in;
    char filename1[30] = "shuff.dat";
    int a1,a2,b1,b2,c1,c2;
    char command[100];

    in = fopen(filename1, "w");
    //for(i = 0; i<=100000; i +=100){
    for(i = 0; i<=10; i +=1){

        if (snprintf(command, sizeof(command), "./barajas_n.x %d", i) < sizeof(command)){
        a1 = gettimeofday(&bni , NULL);
        system(command);
        a2 = gettimeofday(&bnf , NULL);
        }

        if (snprintf(command, sizeof(command), "./barajas_m.x %d", i) < sizeof(command)){
        b1 = gettimeofday(&bmi , NULL);
        system(command);
        b2 = gettimeofday(&bmf , NULL);
        }

        if (snprintf(command, sizeof(command), "./barajas_fy.x %d", i) < sizeof(command)){
        c1 = gettimeofday(&bfi , NULL);
        system(command);
        c2 = gettimeofday(&bff , NULL);
        }
        fprintf(in, "%d %d %d %d \n", i, (a2-a1),(b2-b1),(c2-c1));
    }
    fclose(in);
}

我在终端窗口收到以下消息:

这意味着这个程序正在运行它的所有步骤,只是没有正确执行我想要计时的程序。

我已经像这样在终端中单独测试了所有三个程序

./barajas_*.x i
  1. 谁能告诉我为什么 system() 将其输入作为目录,并且,
  2. 如何告诉 system() 它停止将其作为目录并执行它?

编辑:在聊天室中长时间讨论后,问题正如 Jonathan Leffler 所说:“存在的实际命令名称与程序试图运行的命令名称不匹配。”

iharob 的贡献回答了实际问题,如果命令名称与程序正在运行的命令名称匹配,任何对他提供的 sn-p 感兴趣的人都应该工作。

【问题讨论】:

  • 如果你解决了问题,不要修复问题中的代码,因为那样看起来你从来没有遇到过问题。我撤消了 - 如果我犯了错误,请告诉我。
  • @immibis 你确实犯了一个错误!正如我试图解释但不能因为显然有更多声誉的人编辑了我的编辑并且我无法完成我的编辑,更改语法是 system() 的参数符合其要求并不能解决问题,但让程序进入 for lop 并为所有三个文件显示相同的错误 i 次。
  • @immibis 您能撤消您的编辑,以便我更新问题正文吗?
  • 我看到有人提供了答案,您更新了问题以合并答案。但是,如果您认为我错了,请继续并恢复我的回复 - 我只是另一个 Stack Overflow 用户,我没有获得超能力或任何东西,因为我拥有很多声誉(除了编辑帖子而不需要审查我的编辑,并且能够看到已删除的帖子)。
  • 在聊天中经过一番讨论并查看了运行程序的实际结果后,我们发现问题是一个错字——实际存在的命令名称与程序的命令名称不匹配正在尝试运行。

标签: c runtime system sh


【解决方案1】:

system() 函数只接受一个const char * 类型的参数,如果您需要构建命令,请尝试使用snprintf(),像这样

char command[100];

if (snprintf(command, sizeof(command), "barajas_n.x %d", i) < sizeof(command))
{
    a1 = gettimeofday(&bni , NULL);
    system(command);
    a2 = gettimeofday(&bfi , NULL);
}

另外,gettimeofday() 的返回值对于计算时间差没有用处。只是为了检查错误,你可以使用这个函数来获取经过时间

float elapsed_time(struct timeval *end, struct timeval *start)
{    
    struct timeval result;
    if (end->tv_usec - start->tv_usec > 1.0E6)
    {
        double adjust;

        adjust          = (end->tv_usec - start->tv_usec) / 1.0E6;
        start->tv_usec += 1.0E6 * adjust;
        start->tv_sec  -= adjust;
    }
    result.tv_sec  = end->tv_sec  - start->tv_sec;
    result.tv_usec = end->tv_usec - start->tv_usec;

    return result.tv_sec + result.tv_usec / 1.0E6;
}

然后打印经过的时间

printf("Elapsed time: %f\n", elapsed_time(&bni, &bfi);

正如另一个答案提到的,您需要添加一个斜杠来执行程序,./programname 而不是.programname,但这是另一种解决方案:

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>

#include <sys/time.h>
#include <time.h>

/* This function, just calculates the difference in seconds, between end and start */
float elapsed_time(struct timeval *end, struct timeval *start)
{
    struct timeval result;
    if (end->tv_usec - start->tv_usec > 1.0E6)
    {
        float adjust;

        adjust          = (end->tv_usec - start->tv_usec) / 1.0E6;
        start->tv_usec += 1.0E6 * adjust;
        start->tv_sec  -= adjust;
    }
    result.tv_sec  = end->tv_sec  - start->tv_sec;
    result.tv_usec = end->tv_usec - start->tv_usec;

    return result.tv_sec + result.tv_usec / 1.0E6;
}

/* this function will execute the command and wrap the system call
 * with 'gettimeofday()' so you can return the elapsed time while
 * the called program was running.
 *
 * It also builds the command string with the right parameter. 
 */
float run_command_and_return_time(const char *const program, int parameter)
{
    char           command[100];
    struct timeval start;
    struct timeval end;
    int            result;
    /* check that sprintf didn't need more characters */
    result = snprintf(command, sizeof(command), "%s %d", program, parameter);
    if ((result >= sizeof(command)) || (result < 0))
        return -1.0;
    gettimeofday(&start, NULL);
    system(command);
    gettimeofday(&end, NULL);

    return elapsed_time(&end, &start);
}

int
main(int argc, char **argv)
{
    char        cwd[PATH_MAX];
    const char *filename;
    FILE       *output;

    filename = "shuff.dat";
    output   = fopen(filename, "w");
    if (output == NULL)
        return -1;
    /* get the current working directory */
    getcwd(cwd, sizeof(cwd));
    /* add the cwd to the PATH variable, so your barajas_*.x programs are found,
     * this way you don't need the ./bara... anymore, just bara... will do it.
     */
    setenv("PATH", cwd, 1);
    /* from here it's pretty evident what the program does */
    for (int i = 0 ; i < 10 ; ++i)
    {
        float a, b, c;

        a = run_command_and_return_time("barajas_n.x", i);
        b = run_command_and_return_time("barajas_m.x", i);
        c = run_command_and_return_time("barajas_fy.x", i);

        fprintf(output, "%d %f %f %f \n", i, a, b, c);
    }
    /* don't forget to close the output file */
    fclose(output);

    return 0;
}

【讨论】:

  • 你能扩展你的答案吗?我是 C 新手
  • @CarlosSanchez listo, que te parece?
  • Pues veo que lo estas explicando bien pero tengo un par de dudas, entiendo cual era el questiona con system(), y entiendo que gettimeofday() no sea una buena opcion, pero por ejemplo veo que se está ejecutando el programa en fprintf(stderr, "Elapsed time: %f\n", elapsed_time(&bni, &bfi); pero no se que es stderr ni como bni y bfi me marcan el inicio y fin de un programa.
  • 另外 snprintf() 对我得到的错误没有帮助,我仍然有它,只是现在代码实际上进入了 for 循环,因为它被打印了多次。
  • @CarlosSanchez gettimeofday() solo llena la estructura con los segundos y micro segundos de la hora actual, entonces elapsed_time() calcula la diferencia。问题可能是 barajas_* 文件与您的 c 程序编译的可执行文件不在同一目录中。
【解决方案2】:

我注意到您的代码当前为:

if (snprintf(command, sizeof(command), ".barajas_n.x %d", i) < sizeof(command)){

在我看来你好像少了一个斜线:

if (snprintf(command, sizeof(command), "./barajas_n.x %d", i) < sizeof(command)){

如果这只是一个错字,那么剩下的一个问题是gettimeofday() 总是返回 0:

gettimeofday() 函数应返回 0,并且不应保留任何值来指示错误。

任何经过的时间都可以通过struct timeval 结构的计算找到,或多或少如iharobanswer 所示。

聊天后概要

我邀请卡洛斯和我一起chat

在聊天中进行了一些讨论并查看了运行程序的实际结果后,我们发现问题出在拼写错误 - 存在的实际命令名称与程序试图运行的命令名称不匹配。

【讨论】:

  • 您好@JonathanLeffler,这是问题正文中的错字,我会立即修复它,但它仍然无法正常工作。
  • 我在发布答案后确实注意到了这种情况。 OP在我回答后修改了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 2012-02-25
相关资源
最近更新 更多