C에서 외부 프로그램을 실행하고 출력을 구문 분석하려면 어떻게 해야 합니까?
-
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;
}