【问题标题】:How to copy the output of linux command to a C++ variable如何将linux命令的输出复制到C++变量
【发布时间】:2012-09-04 18:23:38
【问题描述】:

我正在从 C++ 程序中调用 LINUX 命令,该程序会创建以下输出。我需要将输出的第一列复制到 C++ 变量(比如 long int)。我该怎么做??如果这不可能,我如何将此结果复制到我可以使用的 .txt 文件中?

编辑

          0 +0
 2361294848 +2361294848
 2411626496 +50331648
 2545844224 +134217728
 2713616384 +167772160

我已将其存储为文件 file.txt,并且我正在使用以下代码 提取没有 0 的左列以将其存储为整数

string stringy="";
int can_can=0;
for(i=begin;i<length;i++)
{
if (buffer[i]==' ' && can_can ==1) //**buffer** is the whole text file read in char*
{
num=atoi(stringy.c_str());
array[univ]=num; // This where I store the values.
univ+=1;
can_can=1;
  }
  else if (buffer[i]==' ' && can_can ==0) 
 {
stringy="";  
}
else if (buffer[i]=='+')
{can_can=0;}
else{stringy.append(buffer[i]);}
}

我收到了一个分段错误。可以做什么?

提前致谢。

【问题讨论】:

  • 向我们展示代码!你是如何运行 Linux 命令的?
  • 如何首先检索到这个输出?

标签: c++ linux command


【解决方案1】:

只需在 popen() 周围创建一个简单的 streambuf 包装器

#include <iostream>
#include <stdio.h>

struct SimpleBuffer: public std::streambuf
{   
    typedef std::streambuf::traits_type traits;
    typedef traits::int_type            int_type;

    SimpleBuffer(std::string const& command)
        : stream(popen(command.c_str(), "r"))
    {   
        this->setg(&c[0], &c[0], &c[0]);
        this->setp(0, 0); 
    }   
    ~SimpleBuffer()
    {   
        if (stream != NULL)
        {   
            fclose(stream);
        }   
    }   
    virtual int_type underflow()
    {   
        std::size_t size = fread(c, 1, 100, stream);
        this->setg(&c[0], &c[0], &c[size]);

        return size == 0 ? EOF : *c; 
    }   

    private:
        FILE*   stream;
        char    c[100];

};  

用法:

int main()
{
    SimpleBuffer    buffer("echo 55 hi there Loki");
    std::istream    command(&buffer);

    int  value;
    command >> value;

    std::string line;
    std::getline(command, line);

    std::cout << "Got int(" << value << ") String (" << line << ")\n";
}

结果:

> ./a.out
Got int(55) String ( hi there Loki)

【讨论】:

    【解决方案2】:

    您可能正在寻找popen。试试

    man popen
    

    .

    或者看这个小例子:

    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    
    int main() 
    {
    
        FILE *in;
        char buff[512];
    
        if(!(in = popen("my_script_from_command_line", "r"))){
            return 1;
        }
    
        while(fgets(buff, sizeof(buff), in)!=NULL){
              cout << buff; // here you have each line 
                            // of the output of your script in buff
        }
        pclose(in);
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      不幸的是,这并不容易,因为平台 API 是为 C 编写的。以下是一个简单的工作示例:

      #include <cstdio>
      #include <iostream>
      
      int main() {
          char const* command = "ls -l";
      
          FILE* fpipe = popen(command, "r");
      
          if (not fpipe) {
              std::cerr << "Unable to execute commmand\n";
              return EXIT_FAILURE;
          }
      
          char buffer[256];
          while (std::fgets(buffer, sizeof buffer, fpipe)) {
              std::cout << buffer;
          }
      
          pclose(fpipe);
      }
      

      但是,我建议将 FILE* 句柄包装在 RAII 类中以处理资源管理。

      【讨论】:

        【解决方案4】:

        您可能想使用popen 来执行命令。这会给你一个FILE *,你可以从中读取它的输出。从那里,您可以解析出第一个数字(例如):

        fscanf(inpipe, "%d %*d", &first_num);
        

        就像从文件中读取一样,您通常会重复,直到收到文件结束指示,例如:

        long total = 0;
        
        while (1 == fscanf(inpipe, "%l %*d", &first_num))
            total = first_num;
        
        printf("%l\n", total);
        

        【讨论】:

        • 您的1 == fscanf 似乎不对:来自 man fscanf: '[..] 返回成功匹配和分配的输入项数,[..]'。在你的情况下是 2,不是吗?
        • @PatrickB.:不——“和分配”在这里很重要。第二次转换中的* 阻止分配其结果。
        • 好的,我刚刚看到只有一个参数...并且总数 == first_num?
        猜你喜欢
        • 1970-01-01
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-21
        相关资源
        最近更新 更多