Error while trying to show files using <filesystem> in C++ - c++

I have an error when I try to list a simple .pdf on my desktop.
#include <string>
#include <iostream>
#include <filesystem>
#include <vector>
using namespace std;
namespace fs = std::filesystem;
int main()
{
unsigned long int nbFile = 0;
unsigned long size = 0;
string path = R"(C:\Users\Adam\Desktop\)";
for ( const auto &entry : fs::recursive_directory_iterator((path), fs::directory_options::skip_permission_denied)) {
if (fs::is_regular_file(entry.path())){
cout << entry.path() << endl;
nbFile++;
size += entry.file_size();
}
}
cout << "Nombre de fichier : " << nbFile << "\nSize : " << size << endl;
system("pause");
return 0;
}

I find the problem the program can't convert caracter from a pdf file so i use wstring.

Related

How to retain filesystem path while converting to string?

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
using namespace std;
int main()
{
fs::path p = fs::current_path();
cout << p << endl;
string p_string = p.string();
cout << p_string << endl;
return 0;
}
When printing out 'p' the path is shown as this.
"C:\\Users\\tp\\source\\repos\\test"
But after the conversion to a string it comes out like this.
C:\Users\tp\source\repos\test
Is there a way I could retain the original form of the path?
From cppreference's page on operator<<(std::filesystem::path):
Performs stream input or output on the path p. std::quoted is used so that spaces do not cause truncation when later read by stream input operator.
So we'll get the same string by manually calling std::quoted:
#include <iostream>
#include <iomanip>
#include <filesystem>
namespace fs = std::filesystem;
using namespace std;
int main()
{
fs::path p = fs::current_path();
// Should be same
cout << p << endl;
cout << std::quoted(p.string());
return 0;
}

Unable to create a folder with todays date in c++

Im trying to create a folder with todays date in c++. WHile in python its very easy , in c++ im finding it challenging.
I tried this code where first I tried to print the date and then use the date values to create a folder. I even tried inserting unix commands but even those didnt work.
I simply want to create a directory like : DD_MM_YYYY or DD_MM_YY
#include <bits/stdc++.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include "time.h"
//#include "date/tz.h"
using namespace std;
using namespace std::chrono;
int main()
{ //option 1
time_t my_time =time(NULL);
cout << ctime(&my_time)<<endl;
///option 2
time_t t = time(NULL);
struct tm tm = *localtime(&t);
printf("now: %d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
printf("Date: %d_%d_%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
// EXPERIMENT SECTION : ALL OF THESE THROWING ERRORS
//sub_fol=(tm.tm_year+1900).ToString()+"."+tm.tm_mon.ToString();
//sub_fol=tm.tm_mon;
string str="date +'%d_%m_%y'";
//str="mkdir "+ str;
const char *command=str.c_str();
//string dr=system(command);
//printf(string(tm.tm_mon));
// THIS ONES WORKING
if (mkdir("test_", 0777) == -1)
cerr << "Error : " << strerror(errno) << endl;
else
cout << "Directory created";
// THIS ONE ISNT WORKING
if (mkdir(system(command), 0777) == -1)
cerr << "Error : " << strerror(errno) << endl;
else
cout << "Directory created";
}
You can make use of std::localtime and std::puttime to get a formatted date.
For example:
#include <iostream>
#include <chrono>
#include <sstream>
#include <iomanip>
int main()
{
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");
std::cout << ss.str() << std::endl;
}
Will get you:
14_01_2021
You can see https://en.cppreference.com/w/cpp/io/manip/put_time for more formatting options.
Then you can use mkdir or make use of std::filesystem if you are using C++17 or above.
#include <filesystem>
...
std::filesystem::create_directory("abc");
See https://en.cppreference.com/w/cpp/filesystem/create_directory
For mkdir it expects a const char *path rather than a std::string but you can get a char pointer via c_str() e.g.:
mkdir(ss.str().c_str(), 0700);

How to print the fractional part of float number while converting to string

I have a code which will convert the float value to string, i have written like below
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
float myFloat= 10.80;
std::ostringstream ss;
ss << myFloat;
cout<<"value = " << ss.str();
std::string s(ss.str());
cout<<"value = " << s;
return 0;
}
But the problem is when my value is 10.66 its coming 10.66 but when its 10.80 its coming like 10.8 or when its 10.00 its coming 10 only .
How can i print the complete value
Try this code .
Use the setprecision function with '2' .
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main() {
float myFloat= 10.80;
stringstream stream;
stream << fixed << setprecision(2) << myFloat;
string s = stream.str();
cout<<"value = " << s;
return 0;
}
The trailing zeros are only kept if you set either fixed or scientific mode.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double x = 4.2;
cout << fixed << setprecision(2);
cout << x << endl;
return 0;
}
It seems you want something like below.
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;
int main() {
float myFloat= 10.80;
std::ostringstream ss;
ss << fixed << setprecision(2) << myFloat;
cout<<"value = " << ss.str();
std::string s(ss.str());
cout<<"value = " << s;
}
Probably the least complicated way would be to use printf instead of std::cout. There you can specifically specify how many digits are to be displayed.
#include "stdio.h"
printf("%3.2f",myfloat);
where 3 is the # of digits before and 2 the # of digits after the dot, either can be left out. Append '\n' to the string if you want a new line.
EDIT: Ok, I did not know about setprecision(2).

Lexical cast Partial conversion - Is it possible?

lexical_cast throws an exception in the following case. Is there a way to use lexical_cast and convert the string to integer.
#include <iostream>
#include "boost/lexical_cast.hpp"
#include <string>
int main()
{
std::string src = "124is";
int iNumber = boost::lexical_cast<int>(src);
std::cout << "After conversion " << iNumber << std::endl;
}
I understand, I can use atoi instead of boost::lexical_cast.
If I'm understanding your requirements correctly it seems as though removing the non-numeric elements from the string first before the lexical_cast will solve your problem. The approach I outline here makes use of the isdigit function which will return true if the given char is a digit from 0 to 9.
#include <iostream>
#include "boost/lexical_cast.hpp"
#include <string>
#include <algorithm>
#include <cctype> //for isdigit
struct is_not_digit{
bool operator()(char a) { return !isdigit(a); }
};
int main()
{
std::string src = "124is";
src.erase(std::remove_if(src.begin(),src.end(),is_not_digit()),src.end());
int iNumber = boost::lexical_cast<int>(src);
std::cout << "After conversion " << iNumber << std::endl;
}
The boost/lexical_cast uses stringstream to convert from string to other types,so you must make sure the string can be converted completely! or, it will throw the bad_lexical_cast exception,This is an example:
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#define ERROR_LEXICAL_CAST 1
int main()
{
using boost::lexical_cast;
int a = 0;
double b = 0.0;
std::string s = "";
int e = 0;
try
{
// ----- string --> int
a = lexical_cast<int>("123");//good
b = lexical_cast<double>("123.12");//good
// -----double to string good
s = lexical_cast<std::string>("123456.7");
// ----- bad
e = lexical_cast<int>("abc");
}
catch(boost::bad_lexical_cast& e)
{
// bad lexical cast: source type value could not be interpreted as target
std::cout << e.what() << std::endl;
return ERROR_LEXICAL_CAST;
}
std::cout << a << std::endl; // cout:123
std::cout << b << std::endl; //cout:123.12
std::cout << s << std::endl; //cout:123456.7
return 0;
}

boost::iostreams::counter doesn't seem to work

I'm playing around with boost::iostreams and the user guide talks about filter "counter". So I try it with this code:
#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/filter/counter.hpp>
namespace io = boost::iostreams;
int main()
{
io::counter cnt;
io::filtering_ostream out(cnt | io::null_sink());
out << "hello";
std::cout << cnt.lines() << " " << cnt.characters() << std::endl;
}
It always gives
0 0
which doesn't seem to be what I am expecting.
A preliminary tracing with gdb suggests the counter object that is doing the counting has a different address with object 'cnt'. I suppose it is some kind of copying in pipeline? If that's the case, how can filter "counter" be of any use?
Looking at the documentation you can use either:
#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/filter/counter.hpp>
namespace io = boost::iostreams;
int main()
{
io::counter cnt;
io::filtering_ostream out(cnt | io::null_sink());
out << "hello";
std::cout << out.component<io::counter>(0)->lines() << " " << out.component<io::counter>(0)->characters() << std::endl;
}
or:
#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/filter/counter.hpp>
#include <boost/ref.hpp>
namespace io = boost::iostreams;
int main()
{
io::counter cnt;
io::filtering_ostream out;
out.push(boost::ref(cnt));
out.push(io::null_sink());
out << "hello";
std::cout << cnt.lines() << " " << cnt.characters() << std::endl;
}