简体   繁体   中英

How do I read the output of a batch file into a string in C++

I'm trying to make a small program that will create a Batch file, do something in it and then return a string from it, and after it delete the Batch.

I would like to store the output of the batch file in the variable line .

I tried using getline() but I think it work with .txt files only. I can be wrong.

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
using namespace std;

int main(int argc, char *argv[]) {
    ofstream batch;
    string line;

    batch.open("temp.bat", ios::out);
    batch <<"@echo OFF\nwmic os get caption /value\nwmic path win32_videocontroller get description /value\npause\nexit";
    batch.close();

    system("temp.bat");
    remove("temp.bat");
};

In my code I simply using system with my Batch file. I'd like to use cout<<line .

I expect string called line would be equal to the output of the Batch file.

A possible, though admittedly not ideal solution would be to have the batch file write it's output to a .txt file and then read in that file into your program. Look at this SO thread to see how to do this.

You need to redirect output when using system():

#include <cstdio>   // std::remove(const char*)
#include <cstdlib>  // std::system(const char*)
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>

int main()
{
  std::string foo_bat = "foo.bat";
  std::string foo_out = "foo.out";

  // Write the batch file
  {
    std::ofstream f( foo_bat );
    f << R"z(
      @echo off
      wmic os get caption /value
      wmic path win32_videocontroller get description /value
    )z";
  }

  // Execute the batch file, redirecting output using the current (narrow) code page
  if (!!std::system( (foo_bat + " | find /v \"\" > " + foo_out + " 2> NUL").c_str() ))
  {
    // (Clean up and complain)
    std::remove( foo_bat.c_str() );
    std::remove( foo_out.c_str() );
    std::cout << "fooey!\n";
    return 1;
  }

  // Read the redirected output file
  std::unordered_map <std::string, std::string> env;
  {
    std::ifstream f( foo_out );
    std::string s;
    while (getline( f >> std::ws, s ))
    {
      auto n = s.find( '=' );
      if (n != s.npos)
        env[ s.substr( 0, n ) ] = s.substr( n+1 );
    }
  }

  // Clean up
  std::remove( foo_bat.c_str() );
  std::remove( foo_out.c_str() );

  // Show the user what we got
  for (auto p : env)
    std::cout << p.first << " : " << p.second << "\n";
}

WMIC is a problematic program when it comes to controlling the output code page , hence the weird pipe trick we use with system() .

But, after all that, you should use the WMI API directly to get this kind of information .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM