दिलचस्प पोस्ट
टूलबार होम बटन क्लिक ईवेंट को नहीं पकड़ सकता ग्रहण "सर्वर स्थान" अनुभाग अक्षम किया गया है और टॉमकेट स्थापना का उपयोग करने के लिए बदलने की आवश्यकता है NHibernate गतिशील कॉलम संख्या एंड्रॉइड एनीमेशन पुनरावृत्ति नहीं करता है टैब या विंडो सक्रिय नहीं होने पर ब्राउज़र कैसे जावास्क्रिप्ट को रोकते हैं? Link_to से querystring पैरामीटर जोड़ें सबलेट फिल्टर का उपयोग करके प्रतिक्रिया में सामग्री डालने के लिए एक उदाहरण की तलाश में Magento – उपयोगकर्ता इनपुट पर आधारित उद्धरण / आदेश उत्पाद आइटम विशेषता मैं कॉफी स्क्रिप्ट में वैश्विक चर को कैसे परिभाषित करूं? क्या पीडीएफ फाइल का प्रिंट संवाद जावास्क्रिप्ट के साथ खोला जा सकता है? SQLite और साझा वरीयताओं के पेशेवरों और विपक्ष आईएसओ प्रोलॉग की जटिलता का अनुमान है कमांड लाइन पर सीएसवी में XLS कन्वर्ट करें सीतनिद्रा में होना / जेपीए – एनोटेटिंग बीन विधि बनाम फ़ील्ड मैं एंड्रॉइड में एसक्यूलाइट में तैयार बयानों का उपयोग कैसे करूं?

कैसे एक आदेश को निष्पादित करें और सी + + के भीतर सी + + के आउटपुट को POSIX का उपयोग करें?

मैं एक आदेश के आउटपुट को प्राप्त करने का एक तरीका तलाश रहा हूं, जब वह सी ++ प्रोग्राम से चलाया जाता है मैंने सिस्टम () फ़ंक्शन का उपयोग करने पर ध्यान दिया है, लेकिन वह सिर्फ एक कमांड निष्पादित करेगा यहां मैं क्या देख रहा हूं इसका एक उदाहरण है:

std::string result = system( "./some_command" ) ; 

मुझे एक मनमाने ढंग से कमान चलाने की जरूरत है और इसे आउटपुट मिलता है। मैंने Boost.org को देखा है लेकिन मुझे कुछ भी नहीं मिला है जो मुझे मुझे प्रदान करने की आवश्यकता होगी।

वेब के समाधान से एकत्रित समाधान "कैसे एक आदेश को निष्पादित करें और सी + + के भीतर सी + + के आउटपुट को POSIX का उपयोग करें?"

 #include <cstdio> #include <iostream> #include <memory> #include <stdexcept> #include <string> #include <array> std::string exec(const char* cmd) { std::array<char, 128> buffer; std::string result; std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose); if (!pipe) throw std::runtime_error("popen() failed!"); while (!feof(pipe.get())) { if (fgets(buffer.data(), 128, pipe.get()) != std::nullptr) result += buffer.data(); } return result; } 

प्री-सी + 11 संस्करण:

 #include <iostream> #include <stdexcept> #include <stdio.h> #include <string> std::string exec(const char* cmd) { char buffer[128]; std::string result = ""; FILE* pipe = popen(cmd, "r"); if (!pipe) throw std::runtime_error("popen() failed!"); try { while (!feof(pipe)) { if (fgets(buffer, 128, pipe) != NULL) result += buffer; } } catch (...) { pclose(pipe); throw; } pclose(pipe); return result; } 

Windows के लिए popen और _popen साथ popen और pclose बदलें।

दोनों stdout और stderr (और यहां तक ​​कि stdin को लिखना, यहाँ नहीं दिखाया जा रहा है) मेरे pstreams शीर्षक के साथ आसान peasy है, जो iostream वर्गों को परिभाषित करता है जो popen तरह काम करता है:

 #include <pstream.h> #include <string> #include <iostream> int main() { // run a process and create a streambuf that reads its stdout and stderr redi::ipstream proc("./some_command", redi::pstreams::pstdout | redi::pstreams::pstderr); std::string line; // read child's stdout while (std::getline(proc.out(), line)) std::cout << "stdout: " << line << '\n'; // read child's stderr while (std::getline(proc.err(), line)) std::cout << "stderr: " << line << '\n'; } 

मैं पॉपिन () (++ वकास) का इस्तेमाल करता हूं

लेकिन कभी-कभी आपको पढ़ने और लिखने की ज़रूरत है …

ऐसा लगता है जैसे कोई भी चीजें किसी भी कठिन तरीके से ज्यादा नहीं करता।

(एक यूनिक्स / लिनक्स / मैक पर्यावरण, या शायद एक पॉसिक्स संगतता परत के साथ विंडोज …) मान लें

 enum PIPE_FILE_DESCRIPTERS { READ_FD = 0, WRITE_FD = 1 }; enum CONSTANTS { BUFFER_SIZE = 100 }; int main() { int parentToChild[2]; int childToParent[2]; pid_t pid; string dataReadFromChild; char buffer[ BUFFER_SIZE + 1 ]; ssize_t readResult; int status; ASSERT_IS(0, pipe(parentToChild)); ASSERT_IS(0, pipe(childToParent)); switch ( pid = fork() ) { case -1: FAIL( "Fork failed" ); exit(-1); case 0: /* Child */ ASSERT_NOT(-1, dup2( parentToChild[ READ_FD ], STDIN_FILENO ) ); ASSERT_NOT(-1, dup2( childToParent[ WRITE_FD ], STDOUT_FILENO ) ); ASSERT_NOT(-1, dup2( childToParent[ WRITE_FD ], STDERR_FILENO ) ); ASSERT_IS( 0, close( parentToChild [ WRITE_FD ] ) ); ASSERT_IS( 0, close( childToParent [ READ_FD ] ) ); /* file, arg0, arg1, arg2 */ execlp( "ls", "ls", "-al", "--color" ); FAIL( "This line should never be reached!!!" ); exit(-1); default: /* Parent */ cout << "Child " << pid << " process running..." << endl; ASSERT_IS( 0, close( parentToChild [ READ_FD ] ) ); ASSERT_IS( 0, close( childToParent [ WRITE_FD ] ) ); while ( true ) { switch ( readResult = read( childToParent[ READ_FD ], buffer, BUFFER_SIZE ) ) { case 0: /* End-of-File, or non-blocking read. */ cout << "End of file reached..." << endl << "Data received was (" << dataReadFromChild.size() << "):" << endl << dataReadFromChild << endl; ASSERT_IS( pid, waitpid( pid, & status, 0 ) ); cout << endl << "Child exit staus is: " << WEXITSTATUS(status) << endl << endl; exit(0); case -1: if ( (errno == EINTR) || (errno == EAGAIN) ) { errno = 0; break; } else { FAIL( "read() failed" ); exit(-1); } default: dataReadFromChild . append( buffer, readResult ); break; } } /* while ( true ) */ } /* switch ( pid = fork() )*/ } 

आप भी चयन () के साथ खेलने के लिए और गैर-अवरुद्ध पढ़ना चाहते हैं।

 fd_set readfds; struct timeval timeout; timeout.tv_sec = 0; /* seconds */ timeout.tv_usec = 1000; /* microseconds */ FD_ZERO(&readfds); FD_SET( childToParent[ READ_FD ], &readfds ); switch ( select ( 1 + childToParent[READ_FD], &readfds, (fd_set*)NULL, (fd_set*)NULL, & timeout ) ) { case 0: /* Timeout expired */ break; case -1: if ( (errno == EINTR) || (errno == EAGAIN) ) { errno = 0; break; } else { FAIL( "Select() Failed" ); exit(-1); } case 1: /* We have input */ readResult = read( childToParent[ READ_FD ], buffer, BUFFER_SIZE ); // However you want to handle it... break; default: FAIL( "How did we see input on more than one file descriptor?" ); exit(-1); } 

विंडोज popen भी काम करता है, लेकिन यह कंसोल विंडो खोलता है – जो आपके यूआई ऐप्लिकेशन पर जल्दी से चमकती है। यदि आप एक पेशेवर बनना चाहते हैं, तो यह "फ्लैशिंग" अक्षम करने के लिए बेहतर है (विशेषकर यदि अंतिम उपयोगकर्ता इसे रद्द कर सकता है)।

तो यहां विंडोज के लिए मेरा अपना संस्करण है:

(यह कोड आंशिक रूप से कोड प्रोजेक्ट और एमएसडीएन नमूनों में लिखे गए विचारों से पुनः संयोजित)

 // // Execute a command and get the results. (Only standard output) // CStringA ExecCmd( const wchar_t* cmd // [in] command to execute ) { CStringA strResult; HANDLE hPipeRead, hPipeWrite; SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) }; saAttr.bInheritHandle = TRUE; //Pipe handles are inherited by child process. saAttr.lpSecurityDescriptor = NULL; // Create a pipe to get results from child's stdout. if ( !CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0) ) return strResult; STARTUPINFO si = { sizeof(STARTUPINFO) }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.hStdOutput = hPipeWrite; si.hStdError = hPipeWrite; si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. Requires STARTF_USESHOWWINDOW in dwFlags. PROCESS_INFORMATION pi = { 0 }; BOOL fSuccess = CreateProcessW( NULL, (LPWSTR)cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); if (! fSuccess) { CloseHandle( hPipeWrite ); CloseHandle( hPipeRead ); return strResult; } bool bProcessEnded = false; for (; !bProcessEnded ;) { // Give some timeslice (50ms), so we won't waste 100% cpu. bProcessEnded = WaitForSingleObject( pi.hProcess, 50) == WAIT_OBJECT_0; // Even if process exited - we continue reading, if there is some data available over pipe. for (;;) { char buf[1024]; DWORD dwRead = 0; DWORD dwAvail = 0; if (!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL)) break; if (!dwAvail) // no data available, return break; if (!::ReadFile(hPipeRead, buf, min(sizeof(buf) - 1, dwAvail), &dwRead, NULL) || !dwRead) // error, the child process might ended break; buf[dwRead] = 0; strResult += buf; } } //for CloseHandle( hPipeWrite ); CloseHandle( hPipeRead ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return strResult; } //ExecCmd 

दो संभावित दृष्टिकोण

1 / मुझे नहीं लगता कि popen() सी ++ मानक का भाग है (यह स्मृति से पॉसिक्स का हिस्सा है) परन्तु यह हर यूनिक्स पर उपलब्ध है जिसमे मैंने काम किया है (और आप यूनिक्स को लक्षित करते हैं क्योंकि आपका आदेश है " ./some_command ")।

2 / बंद-मौका पर कि कोई popen() , आप system( "./some_command >/tmp/some_command.out" ) ; उपयोग कर सकते हैं system( "./some_command >/tmp/some_command.out" ) ; फिर आउटपुट फ़ाइल को संसाधित करने के लिए सामान्य I / O फ़ंक्शन का उपयोग करें।

आप पुस्तकालय बूस्ट का उपयोग कर सकते हैं। प्रक्रिया यह आधिकारिक तौर पर बढ़ावा देने का हिस्सा नहीं है। मैंने इसे दूसरों के लिए अच्छी तरह से काम किया है दुर्भाग्य से, बढ़ावा.प्रक्रिया प्रगति जाहिरा तौर पर स्थगित कर दिया गया है। pstreams एक और (जाहिरा तौर पर सक्रिय) परियोजना है निश्चित रूप से एक कोशिश मैं कहूँगा लायक – लेकिन यह केवल posix संगत ऑपरेशन सिस्टम के लिए है

यह एक पोर्टेबल समाधान हो सकता है मानकों का पालन करता है

 #include<iostream> #include<fstream> #include<string> #include<cstdlib> #include<sstream> std::string ssystem (const char *command) { char tmpname [L_tmpnam]; std::tmpnam ( tmpname ); std::string scommand = command; std::string cmd = scommand + " >> " + tmpname; std::system(cmd.c_str()); std::ifstream file(tmpname, std::ios::in ); std::string result; if (file) { while (!file.eof()) result.push_back(file.get()); file.close(); } remove(tmpname); return result; } //for cygwin int main(int argc, char *argv[]) { std::string bash = "FILETWO=/cygdrive/c/*\nfor f in $FILETWO\ndo\necho \"$f\"\ndone "; std::string in; std::string s = ssystem(bash.c_str()); std::istringstream iss(s); std::string line; while ( std::getline(iss, line) ) { std::cout << "LINE-> " + line + " length: " << line.length() << std::endl; } std::cin >> in; return 0; } 

मैं समझ नहीं सका कि क्यों Popen / pclose Codeblocks / MinGW से गुम है इसलिए मैंने इसके बजाय CreateProcess () और CreatePipe () का उपयोग करके समस्या के आसपास काम किया यहाँ मेरे लिए काम करने वाला समाधान है:

 //C++11 #include <cstdio> #include <iostream> #include <windows.h> #include <cstdint> #include <deque> #include <string> #include <thread> using namespace std; int SystemCapture( string CmdLine, //Command Line string CmdRunDir, //set to '.' for current directory string& ListStdOut, //Return List of StdOut string& ListStdErr, //Return List of StdErr uint32_t& RetCode) //Return Exit Code { int Success; SECURITY_ATTRIBUTES security_attributes; HANDLE stdout_rd = INVALID_HANDLE_VALUE; HANDLE stdout_wr = INVALID_HANDLE_VALUE; HANDLE stderr_rd = INVALID_HANDLE_VALUE; HANDLE stderr_wr = INVALID_HANDLE_VALUE; PROCESS_INFORMATION process_info; STARTUPINFO startup_info; thread stdout_thread; thread stderr_thread; security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); security_attributes.bInheritHandle = TRUE; security_attributes.lpSecurityDescriptor = nullptr; if (!CreatePipe(&stdout_rd, &stdout_wr, &security_attributes, 0) || !SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0)) { return -1; } if (!CreatePipe(&stderr_rd, &stderr_wr, &security_attributes, 0) || !SetHandleInformation(stderr_rd, HANDLE_FLAG_INHERIT, 0)) { if (stdout_rd != INVALID_HANDLE_VALUE) CloseHandle(stdout_rd); if (stdout_wr != INVALID_HANDLE_VALUE) CloseHandle(stdout_wr); return -2; } ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION)); ZeroMemory(&startup_info, sizeof(STARTUPINFO)); startup_info.cb = sizeof(STARTUPINFO); startup_info.hStdInput = 0; startup_info.hStdOutput = stdout_wr; startup_info.hStdError = stderr_wr; if(stdout_rd || stderr_rd) startup_info.dwFlags |= STARTF_USESTDHANDLES; // Make a copy because CreateProcess needs to modify string buffer char CmdLineStr[MAX_PATH]; strncpy(CmdLineStr, CmdLine.c_str(), MAX_PATH); CmdLineStr[MAX_PATH-1] = 0; Success = CreateProcess( nullptr, CmdLineStr, nullptr, nullptr, TRUE, 0, nullptr, CmdRunDir.c_str(), &startup_info, &process_info ); CloseHandle(stdout_wr); CloseHandle(stderr_wr); if(!Success) { CloseHandle(process_info.hProcess); CloseHandle(process_info.hThread); CloseHandle(stdout_rd); CloseHandle(stderr_rd); return -4; } else { CloseHandle(process_info.hThread); } if(stdout_rd) { stdout_thread=thread([&]() { DWORD n; const size_t bufsize = 1000; char buffer [bufsize]; for(;;) { n = 0; int Success = ReadFile( stdout_rd, buffer, (DWORD)bufsize, &n, nullptr ); printf("STDERR: Success:%dn:%d\n", Success, (int)n); if(!Success || n == 0) break; string s(buffer, n); printf("STDOUT:(%s)\n", s.c_str()); ListStdOut += s; } printf("STDOUT:BREAK!\n"); }); } if(stderr_rd) { stderr_thread=thread([&]() { DWORD n; const size_t bufsize = 1000; char buffer [bufsize]; for(;;) { n = 0; int Success = ReadFile( stderr_rd, buffer, (DWORD)bufsize, &n, nullptr ); printf("STDERR: Success:%dn:%d\n", Success, (int)n); if(!Success || n == 0) break; string s(buffer, n); printf("STDERR:(%s)\n", s.c_str()); ListStdOut += s; } printf("STDERR:BREAK!\n"); }); } WaitForSingleObject(process_info.hProcess, INFINITE); if(!GetExitCodeProcess(process_info.hProcess, (DWORD*) &RetCode)) RetCode = -1; CloseHandle(process_info.hProcess); if(stdout_thread.joinable()) stdout_thread.join(); if(stderr_thread.joinable()) stderr_thread.join(); CloseHandle(stdout_rd); CloseHandle(stderr_rd); return 0; } int main() { int rc; uint32_t RetCode; string ListStdOut; string ListStdErr; cout << "STARTING.\n"; rc = SystemCapture( "C:\\Windows\\System32\\ipconfig.exe", //Command Line ".", //CmdRunDir ListStdOut, //Return List of StdOut ListStdErr, //Return List of StdErr RetCode //Return Exit Code ); if (rc < 0) { cout << "ERROR: SystemCapture\n"; } cout << "STDOUT:\n"; cout << ListStdOut; cout << "STDERR:\n"; cout << ListStdErr; cout << "Finished.\n"; cout << "Press Enter to Continue"; cin.ignore(); return 0; }