简体   繁体   English

在C中执行程序

[英]Executing a program in C

At some point of my program, I'd like to run another program (which is getting parameters from stdin), with paramaters I have prepared in a text file. 在我的程序的某些时候,我想运行另一个程序(从stdin获取参数),用我在文本文件中准备的参数。 Then, I'd like to write the program's output into another file. 然后,我想将程序的输出写入另一个文件。

I'm new to linux, fork, and such. 我是linux,fork等新手。 Tried breaking my head for HOURS without success. 试图打破我的头,没有成功。 I read that I should associate my input file with stdin and output file with stdout, something like that. 我读到我应该将我的输入文件与stdin和输出文件与stdout相关联,就像那样。

This is the code I wrote: 这是我写的代码:

//move on all sub-directories .....
while((indir=readdir(dir))!=NULL)
{
    pid_t pid;
    DIR *currDir;
    struct dirent *cfile;
    char *fullpath, *outpath, *outputpath;

    //ignore hidden files
    if(indir->d_name[0]=='.')
        continue;

    //create the full path of c file
    fullpath=(char*)calloc(strlen(dirpath)+strlen(indir->d_name)+1,sizeof(char));
    strcpy(fullpath,dirpath);
    fullpath=strcat(fullpath,indir->d_name);
    fullpath=strcat(fullpath,"/");
    //open current directory
    currDir=opendir(fullpath);
    //get the c file, ignore hidden files
    while((cfile=readdir(currDir))!=NULL)
    {
        if(cfile->d_name[0]!='.')
            break;
    }
    /*compile c file*/

    //child process
    if((pid=fork())==0)
    {
        fullpath=realloc(fullpath, sizeof(char)*(strlen(fullpath)+strlen(cfile->d_name)+1));
        outpath=(char*)calloc(strlen(fullpath)+strlen(OUT_NAME)+1,sizeof(char));
        strcpy(outpath,fullpath);
        strcat(fullpath,cfile->d_name);
        strcat(outpath,OUT_NAME);
        execl("/usr/bin/gcc", "/usr/bin/gcc", "-o", outpath, fullpath,NULL);
    }
    else
    {
        wait(NULL);
    }


    //create output file path
    outputpath=calloc(strlen(fullpath)+strlen(OUTPUTFILE_NAME)+1,sizeof(char));
    strcpy(outputpath,fullpath);
    strcat(outputpath,OUTPUTFILE_NAME);

    inputpath=(char*)calloc(strlen(buff)+1,sizeof(char));
    //get input file path from buffer
    for(j=0,buffIndex++;buff[buffIndex]!='\n';buffIndex++,j++)
    {
        inputpath[j]=buff[buffIndex];
    }

////Untill here works perfectly////
    //child process
    if((pid=fork())==0)
    {
        fullpath=realloc(fullpath, sizeof(char)*(strlen(fullpath)+strlen(OUT_NAME)+1));
        strcat(fullpath, OUT_NAME);
        //re-open input file and associate it with stdin
        freopen(inputpath, "r", stdin);
        //re-open output file and associate it with stdout
        freopen(outputpath, "w", stdout);
        execl(fullpath,inputpath, NULL);
    }
    else
    {
        wait(NULL);
    }

}

*inputpath is the full path of the file I prepared with inputs for the program. * inputpath是我用程序输入准备的文件的完整路径。

*outputpath is the full path of a file where I want to save the program's output. * outputpath是我想保存程序输出的文件的完整路径。

I'm definitely doing something wrong, since I get the following error: 我肯定做错了什么,因为我收到以下错误:

/home/aviad/workspace/test/dean/input.txt~: file not recognized: File truncated
collect2: error: ld returned 1 exit status
/home/aviad/workspace/test/jjang/fileoutput.txt: file not recognized: File truncated
collect2: error: ld returned 1 exit status

Any help? 有帮助吗?

There's not enough information in your post to confirm, but I suspect you are being bitten by choosing the same name as a build tool, eg ld , for your program's name. 您的帖子中没有足够的信息来确认,但我怀疑您是因为您的程序名称选择与构建工具相同的名称(例如ld而被咬。 If you do so and run 如果你这样做并运行

ld 1.txt 2.txt

there's a very good chance you are not executing your ld , but rather the GNU linker or similar ( /usr/bin/ld ). 你很可能没有执行你的 ld ,而是GNU链接器或类似的( /usr/bin/ld )。 Normally system directories are searched before . 通常,之前会搜索系统目录. , if . 如果. is in PATH at all. PATH中。 This avoids some unpleasant surprises like if you had run ls in a directory with a binary named ls in it, you probably still wanted /bin/ls . 这避免了一些令人不快的意外,例如,如果你在一个名为ls的二进制文件的目录中运行ls ,你可能仍然想要/bin/ls

This is why it's a good idea to run things in your cwd prefixed with ./ , so instead you'd say: 这就是为什么在你的cwd中运行前缀为./东西是个好主意,所以相反你会说:

./ld 1.txt 2.txt

and the system ld would not longer be a candidate. 系统ld将不再是候选人。 You can determine which one will run by using which ld and which ./ld . 您可以通过使用which ldwhich ./ld来确定将运行which ./ld

So, in reality you are not running your program at all. 所以,实际上你根本就没有运行你的程序。 This has bitten a few people I've known, including myself. 这已经咬了一些我认识的人,包括我自己。 My first unix program was named "test" ;). 我的第一个unix程序被命名为“test”;)。

EDIT: based on the output, the name cc might be a better candidate than ld , but same idea. 编辑:基于输出,名称cc可能是比ld更好的候选人,但同样的想法。

EDIT: 编辑:

Based on your update, it seems you are calling gcc after all, and by reading directory contents. 根据您的更新,您似乎最终调用了gcc ,并通过读取目录内容。 There doesn't appear to be any check that the file you're compiling is even a .c file, are you sure that you're not calling this code in the directories where these text files live? 似乎没有检查您正在编译的文件甚至是.c文件,您确定您没有在这些文本文件所在的目录中调用此代码吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM