C++中system()函数无法将命令输出存入变量的问题求助
问题分析
你遇到的核心问题是误解了system()函数的作用:它的返回值是命令执行的退出状态码(比如0表示成功,非0表示失败),而非命令输出的内容。所以你用hostname = system(cmd)根本拿不到主机名字符串,自然输出为空。
解决方案
下面分两种场景给出实现方案,优先推荐直接调用系统API的方式(更高效、可控),其次是如果需要调用外部命令时的输出捕获方法。
一、直接调用系统API获取信息(推荐)
Linux 环境
获取主机名可以用<unistd.h>里的gethostname()函数,获取IP地址可以通过getifaddrs()遍历网络接口:
#include <iostream> #include <unistd.h> #include <ifaddrs.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fstream> using namespace std; int main() { // 获取主机名 char hostname[256]; if (gethostname(hostname, sizeof(hostname)) == 0) { cout << "主机名:" << hostname << endl; // 写入文本文件 ofstream outfile("host_info.txt"); outfile << "主机名," << hostname << endl; } else { perror("获取主机名失败"); } // 获取IP地址 struct ifaddrs *ifap, *ifa; struct sockaddr_in *sa; char addr[INET_ADDRSTRLEN]; if (getifaddrs(&ifap) == 0) { for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family == AF_INET && ifa->ifa_name[0] != 'l') { // 跳过回环接口 sa = (struct sockaddr_in *) ifa->ifa_addr; inet_ntop(AF_INET, &sa->sin_addr, addr, sizeof(addr)); cout << "IP地址:" << addr << endl; ofstream outfile("host_info.txt", ios::app); outfile << "IP地址," << addr << endl; } } freeifaddrs(ifap); } else { perror("获取IP地址失败"); } return 0; }
Windows 环境
获取主机名用<windows.h>里的GetComputerName(),IP地址用GetAdaptersAddresses():
#include <iostream> #include <windows.h> #include <iphlpapi.h> #include <fstream> #pragma comment(lib, "iphlpapi.lib") using namespace std; int main() { // 获取主机名 TCHAR hostname[MAX_COMPUTERNAME_LENGTH + 1]; DWORD size = MAX_COMPUTERNAME_LENGTH + 1; if (GetComputerName(hostname, &size)) { cout << "主机名:" << hostname << endl; ofstream outfile("host_info.txt"); outfile << "主机名," << hostname << endl; } else { cout << "获取主机名失败,错误码:" << GetLastError() << endl; } // 获取IP地址 IP_ADAPTER_ADDRESSES *pAddresses = NULL; ULONG outBufLen = 0; GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen); pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen); if (GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen) == NO_ERROR) { IP_ADAPTER_ADDRESSES *pCurrAddresses = pAddresses; while (pCurrAddresses) { IP_ADAPTER_UNICAST_ADDRESS *pUnicast = pCurrAddresses->FirstUnicastAddress; while (pUnicast) { if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) { sockaddr_in *sa = (sockaddr_in *)pUnicast->Address.lpSockaddr; char addr[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &sa->sin_addr, addr, sizeof(addr)); cout << "IP地址:" << addr << endl; ofstream outfile("host_info.txt", ios::app); outfile << "IP地址," << addr << endl; } pUnicast = pUnicast->Next; } pCurrAddresses = pCurrAddresses->Next; } } else { cout << "获取IP地址失败,错误码:" << GetLastError() << endl; } free(pAddresses); return 0; }
二、捕获外部命令的输出(如果必须调用system类命令)
如果因为某些原因必须调用外部命令(比如hostname、ipconfig),需要通过管道捕获输出:
Linux 环境
用popen()打开管道读取命令输出:
#include <iostream> #include <cstdio> #include <cstring> #include <fstream> using namespace std; int main() { char hostname[256]; FILE *pipe = popen("hostname", "r"); if (pipe) { fgets(hostname, sizeof(hostname), pipe); // 去掉换行符 hostname[strcspn(hostname, "\n")] = '\0'; cout << "主机名:" << hostname << endl; ofstream outfile("host_info.txt"); outfile << "主机名," << hostname << endl; pclose(pipe); } else { perror("执行命令失败"); } return 0; }
Windows 环境
用CreatePipe()和CreateProcess()重定向标准输出:
#include <iostream> #include <windows.h> #include <fstream> using namespace std; int main() { SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; HANDLE hReadPipe, hWritePipe; CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0); SetHandleInformation(hReadPipe, HANDLE_FLAG_INHERIT, 0); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.hStdOutput = hWritePipe; si.hStdError = hWritePipe; si.dwFlags |= STARTF_USESTDHANDLES; // 执行hostname命令 if (CreateProcess(NULL, "hostname", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { CloseHandle(hWritePipe); char hostname[256]; DWORD bytesRead; ReadFile(hReadPipe, hostname, sizeof(hostname)-1, &bytesRead, NULL); hostname[bytesRead] = '\0'; // 去掉换行符 hostname[strcspn(hostname, "\r\n")] = '\0'; cout << "主机名:" << hostname << endl; ofstream outfile("host_info.txt"); outfile << "主机名," << hostname << endl; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } else { cout << "执行命令失败,错误码:" << GetLastError() << endl; } CloseHandle(hReadPipe); return 0; }
写入CSV文件提示
如果要生成标准CSV格式,注意处理包含逗号、引号的字段(比如主机名里有逗号的话,需要用双引号包裹),示例:
void writeToCSV(const string& key, const string& value) { ofstream outfile("host_info.csv", ios::app); // 处理包含特殊字符的情况 string escapedValue = value; size_t pos = 0; while ((pos = escapedValue.find('"')) != string::npos) { escapedValue.replace(pos, 1, "\"\""); pos += 2; } if (escapedValue.find(',') != string::npos || escapedValue.find('"') != string::npos) { escapedValue = "\"" + escapedValue + "\""; } outfile << key << "," << escapedValue << endl; }
内容的提问来源于stack exchange,提问作者Thomas Morey
相关产品推荐
相关产品推荐

