user2601570 user2601570 - 1 month ago 10
Bash Question

Error when running shell command in C++ ubuntu linux

//all variables are declared in a struct StockPile
//...
string itemid;
string itemdesc;
string datepurchased;
string line;
int unitprice;
int totalsales;
std::string myline;
//...

void displaydailyreport() {

ifstream myfile("stockdatabase.txt");

for(int i=0;std::getline(myfile,myline);i++)
{
// Trying to grep all data with a specific date from a textfile,
cout<<system("grep "<<stockpile[i].datepurchased<<" stockdatabase.txt")<<endl;
}
cout<<endl;
}


When I try to compile it gives me this error :

note:template argument deduction/substitution failed:
Main.cpp:853:40: note: mismatched types ‘std::basic_ostream<_CharT, _Traits>’ and ‘const char [6]’
cout<<system("grep "<<stockpile[i].datepurchased<<" stockdatabase.txt")<<endl;


When I try to run with this it works fine :

cout<<system("grep '9oct16' stockdatabase.txt")


stockpile[i].datepurchased
is where I can
cout
the different dates stored in my textfile , I can print out
stockpile[i].datepurchased
values in the for loop.
It returns string 9oct16 , 10oct16 etc. but when I try to use shell command it wont compile .

Answer

The << operator is a stream operator. While you can concatenate strings (and c-strings) with them on a stream (like cout) it does not work that way without actually working on a stream.

Lets just take the statement inside your system call seperately

"grep "<<stockpile[i].datepurchased<<" stockdatabase.txt"

The << is not meant to be used that way without a stream object to "stream" into.

What you can do though is the following:

std::string command = "grep "
                      + stockpile[i].datepurchased
                      + " stockdatabase.txt"
system(command.c_str());

This does several things.

  • create a std::string to store the system command
  • because datepurchased is a std::string already you can use the + operator on the other c-strings to concatenate them.
  • system is expecting a const char* as argument. So to be able to pass the c-string to the function we use the c_str() function of the std::string

You can also shorten the statement to this:

system( ("grep "+stockpile[i].datepurchased+" stockdatabase.txt").c_str());

Because a temporary std::string will be created by the + operator you can access it's c_str() function directly.