C에서 외부 프로그램을 실행하고 출력을 구문 분석하려면 어떻게 해야 합니까?

StackOverflow https://stackoverflow.com/questions/43116

  •  09-06-2019
  •  | 
  •  

문제

게임에 필요한 파일 목록을 출력하는 유틸리티가 있습니다.C 프로그램 내에서 해당 유틸리티를 실행하고 출력을 가져와 동일한 프로그램 내에서 작업할 수 있도록 하려면 어떻게 해야 합니까?

업데이트:정보 부족에 대한 좋은 전화입니다.이 유틸리티는 일련의 문자열을 생성하며 이는 Mac/Windows/Linux에서 완전히 이식 가능하다고 가정됩니다.저는 유틸리티를 실행하고 해당 출력(stdout으로 이동)을 유지하는 프로그래밍 방식을 찾고 있습니다.

도움이 되었습니까?

해결책

Unix-ish 환경의 간단한 문제에 대해서는 다음을 시도하십시오. popen().

매뉴얼 페이지에서:

popen() 함수는 파이프를 생성하고 쉘을 포크하고 호출하여 프로세스를 엽니다.

읽기 모드를 사용하는 경우 이것이 바로 귀하가 요청한 것입니다.Windows에서 구현되었는지는 모르겠습니다.

더 복잡한 문제의 경우 프로세스 간 통신을 찾아보고 싶을 것입니다.

다른 팁

다른 사람들이 지적했듯이, popen() 가장 표준적인 방법입니다.그리고 이 방법을 사용한 예제에 대한 답변이 제공되지 않았으므로 다음과 같습니다.

#include <stdio.h>

#define BUFSIZE 128

int parse_output(void) {
    char *cmd = "ls -l";    

    char buf[BUFSIZE];
    FILE *fp;

    if ((fp = popen(cmd, "r")) == NULL) {
        printf("Error opening pipe!\n");
        return -1;
    }

    while (fgets(buf, BUFSIZE, fp) != NULL) {
        // Do whatever you want here...
        printf("OUTPUT: %s", buf);
    }

    if(pclose(fp))  {
        printf("Command not found or exited with error status\n");
        return -1;
    }

    return 0;
}

popen은 Windows에서 지원됩니다. 여기를 참조하세요.

http://msdn.microsoft.com/en-us/library/96ayss4b.aspx

크로스 플랫폼이 되기를 원한다면 popen을 사용하는 것이 좋습니다.

글쎄요, Windows 환경의 명령줄을 사용한다고 가정하면 파이프나 명령줄 리디렉션을 사용할 수 있습니다.예를 들어,

commandThatOutputs.exe > someFileToStoreResults.txt

또는

commandThatOutputs.exe | yourProgramToProcessInput.exe

프로그램 내에서 C 표준 입력 함수를 사용하여 다른 프로그램 출력(scanf 등)을 읽을 수 있습니다. http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp .파일 예제를 사용하고 fscanf를 사용할 수도 있습니다.이는 Unix/Linux에서도 작동합니다.

이는 매우 일반적인 질문입니다. 출력 유형(텍스트만인가요, 아니면 바이너리 파일인가요?)과 출력 처리 방법 등 더 자세한 내용을 포함할 수 있습니다.

편집하다:만세!

STDOUT을 리디렉션하는 것은 번거로운 것 같습니다. .NET에서 이 작업을 수행해야 했고, 이로 인해 온갖 종류의 골칫거리가 생겼습니다.적절한 C 방식은 하위 프로세스를 생성하고 파일 포인터를 얻는 것인데 갑자기 머리가 아프게 됩니다.

임시 파일을 사용하는 해킹이 있습니다.간단하지만 작동해야 합니다.속도가 문제가 되지 않거나(디스크를 치는 것이 느림), 버리는 경우에 이것은 잘 작동합니다.엔터프라이즈 프로그램을 구축하는 경우 다른 사람들이 권장하는 방법을 사용하여 STDOUT 리디렉션을 조사하는 것이 가장 좋습니다.

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

int main(int argc, char* argv[])
{
    FILE * fptr;                    // file holder
    char c;                         // char buffer


    system("dir >> temp.txt");      // call dir and put it's contents in a temp using redirects.
    fptr = fopen("temp.txt", "r");  // open said file for reading.
                                    // oh, and check for fptr being NULL.
    while(1){
        c = fgetc(fptr);
        if(c!= EOF)
            printf("%c", c);        // do what you need to.
        else
            break;                  // exit when you hit the end of the file.
    }
    fclose(fptr);                   // don't call this is fptr is NULL.  
    remove("temp.txt");             // clean up

    getchar();                      // stop so I can see if it worked.
}

파일 권한을 확인하세요.지금은 단순히 exe와 동일한 디렉토리에 파일을 던질 것입니다.당신은 사용을 조사하고 싶을 수도 있습니다 /tmp nix에서 또는 C:\Users\username\Local Settings\Temp 비스타에서 또는 C:\Documents and Settings\username\Local Settings\Temp in 2K/XP.내 생각 엔 /tmp OSX에서도 작동하지만 저는 한번도 사용해본 적이 없습니다.

리눅스와 OS X에서는 popen() dmckee가 지적했듯이 두 OS 모두 해당 호출을 지원하므로 실제로 최선의 방법입니다.Windows에서는 다음이 도움이 됩니다. http://msdn.microsoft.com/en-us/library/ms682499.aspx

MSDN 문서화에 따르면 Windows 프로그램에 사용되는 경우 _Popen 함수는 유효하지 않은 파일 포인터를 반환하여 프로그램이 무기한으로 응답을 중지하게합니다._popen은 콘솔 응용 프로그램에서 제대로 작동합니다.입력 및 출력을 리디렉션하는 Windows 애플리케이션을 만들려면 Windows SDK에서 리디렉션된 입력 및 출력을 사용하여 하위 프로세스 만들기를 참조하세요.

당신이 사용할 수있는 system() 다음과 같이:

system("ls song > song.txt");

어디 ls 폴더 노래의 내용을 나열하는 명령 이름입니다. song 현재 디렉터리의 폴더입니다.결과 파일 song.txt 현재 디렉토리에 생성됩니다.

//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[262144];
    string data;
    string result;
    int dist=0;
    int size;
    //TIME_START
    while(!feof(pipe)) {
        size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
        data.resize(data.size()+size);
        memcpy(&data[dist],buffer,size);
        dist+=size;
    }
    //TIME_PRINT_
    pclose(pipe);
    return data;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top