-2

I'm trying to create a folder named by todays date (on Ubuntu) and then check if it's empty or not.

The empty-or-not check will be done several times daily.

#include <cstdlib>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <typeinfo>
#include <chrono>
#include <time.h>
#include <iomanip>

using namespace std; 

int main() {
  //Pull out system date and create a folder named by system date
  auto const now = std::chrono::system_clock::now();
  auto const in_time_t = std::chrono::system_clock::to_time_t(now);
  std::stringstream ss;
  ss << std::put_time(std::localtime(&in_time_t), "%d_%m_%Y"); 
    
  // Creating todays date folder with entry folder
  string str_2=std::string("mkdir -p " + string(ss.str()) + "/entry");
  const char *com2=str_2.c_str();
  system(com2);
   
  //check if directory is empty or not
  int check;
  char is_empty[100];
  FILE * output;
  output = popen("ls " + ss.str() + "/entry | wc -l","r") ; 
  fgets (is_empty, 100, output); //write to the char
  pclose (output);
  check = atoi(is_empty);
  if (check == 0) {
    cout << "The folder is empty" << endl;
  } 
}

I'm getting this error when compiling this code:

error: no match for ‘operator+’ (operand types are ‘const char [4]’ 
    and ‘std::stringstream {aka std::__cxx11::basic_stringstream<char>}’)
         output = popen("ls " +ss+ "/entry | wc -l","r") ;
ocrdu
  • 2,172
  • 6
  • 15
  • 22
  • Do `std::string cmd = "ls " +ss+ "/entry | wc -l"; output = popen(cmd.c_str(),"r");` instead. – πάντα ῥεῖ Jan 17 '21 at 09:03
  • error: no match for ‘operator+’ (operand types are ‘const char [4]’ and ‘std::stringstream {aka std::__cxx11::basic_stringstream}’) std::string cmd="ls " +ss+ "/entry | wc -l"; del.cpp:58:27: note: candidate: operator+(const char*, long int) del.cpp:58:27: note: no known conversion for argument 2 from ‘std::stringstream {aka std::__cxx11::basic_stringstream}’ to ‘long int’ – Anita Shukla Jan 17 '21 at 10:11
  • Can anyone please help !!! – Anita Shukla Jan 17 '21 at 10:19
  • You can also [append a `s` to your string literals](https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s), to work with them easier when building a string: `std::string cmd = "ls "s +ss+ "/entry | wc -l"s;`. That makes it easier. You cannot concatenate raw c-style using `+`. That's essentially the problem you're facing. – πάντα ῥεῖ Jan 17 '21 at 10:19
  • Tried that but still the error :- error: no match for ‘operator+’ (operand types are ‘std::__cxx11::basic_string’ and ‘std::stringstream {aka std::__cxx11::basic_stringstream}’) std::string cmd = "ls "s +ss+ "/entry | wc -l"s; – Anita Shukla Jan 17 '21 at 10:25
  • That feature is available from c++14 onwards. If your compiler supports it tell it to use with the flag `-std=c++14`. – πάντα ῥεῖ Jan 17 '21 at 10:27
  • I dont know whats happening but this error isnt going away. >> g++ -std=c++14 del.cpp -o del del.cpp: In function ‘int main()’: del.cpp:60:30: error: no match for ‘operator+’ (operand types are ‘std::__cxx11::basic_string’ and ‘std::stringstream {aka std::__cxx11::basic_stringstream}’) std::string cmd = "ls "s +ss+ "/entry | wc -l"s; ~~~~~~~^~~ – Anita Shukla Jan 17 '21 at 10:31
  • Oh. `ss` is a `std::stringstream`, I overlooked that sorry. You can put the value to `ss` using the `<<` output operator. To call `popen()` you need `ss.str().c_str()` as parameter then. – πάντα ῥεῖ Jan 17 '21 at 10:34
  • Its still not working(same error again). Can you please try it out and post in the answer. Ill accept it if it works. – Anita Shukla Jan 17 '21 at 10:40
  • I don't believe it's good to give learners just a code in an answer which may work for them, but they don't understand why and how. Better inform yourself [here](https://en.cppreference.com/w/cpp), and from your textbook what the classes you're using do, and how to use them. May be someone else is willing to write out a complete answer with code here. Just be patient. – πάντα ῥεῖ Jan 17 '21 at 10:43
  • OK buddy , I'll wait. – Anita Shukla Jan 17 '21 at 10:48
  • Why do you show so much code? Most of it is not relevant. Please learn about [mcve]. Also the title has nothing to do with the problem that you describe. – Werner Henze Jan 17 '21 at 12:12

1 Answers1

0

This solved it for me

int check;
char is_empty[100];
FILE * output;

string cmd = std::string("ls " + string(ss.str())+ "/entry | wc -l") ;
const char *com4 = cmd.c_str(); 
output = popen(com4,"r");
fgets(is_empty, 100, output);
pclose (output);
check = atoi(is_empty);
//cout << check<<endl;
if (check == 0){
    cout << "The folder is empty" << endl;
   }
  • 1
    Don't parse the output from `ls`. Add `-std=c++17` (or a later standard) when compiling and use a [`std::filesystem::directory_iterator`](https://en.cppreference.com/w/cpp/filesystem/directory_iterator) instead. – Ted Lyngmo Jan 17 '21 at 12:05
  • @TedLyngmo filesystem isnt working on my ubuntu. Tried everything but its not getting detected at all, even though its there in the /usr/lib and I linked and included in path etc etc.. – Anita Shukla Jan 17 '21 at 14:23
  • Does [how to use std::filesystem on gcc 8?](https://stackoverflow.com/a/53202056/7582247) help? – Ted Lyngmo Jan 17 '21 at 14:31
  • still the same error : undefined reference to `boost::system::generic_category()' – Anita Shukla Jan 17 '21 at 16:49
  • #include #include int main() { if ( !boost::filesystem::exists( "myfile.txt" ) ) { std::cout << "Can't find my file!" << std::endl; } } – Anita Shukla Jan 17 '21 at 16:53
  • IYou need to link with the boost libray too but if you have a proper c++ compilator you don't need boost. `#include ` and use `std::filesystem` instead. – Ted Lyngmo Jan 17 '21 at 16:57