You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:20:40