How to retain filesystem path while converting to string? - c++

#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;
}

Related

Remove dot prefix "./" from std::filesystem::path

Is there a simple way to strip away the starting ./ of a path. For example: I have a path ./x/y and i want to convert it to x/y (without the first dot and slash). Is there a standard way of doing it?
#include <iostream>
#include <filesystem>
namespace filesystem = std::filesystem;
int main() {
auto path = filesystem::path{"./x/y"};
std::cout << path << std::endl;
std::cout << ???? << std::endl; // How do I do this?
}
Apparently the problem could be solved with std::filesystem::relative():
#include <iostream>
#include <filesystem>
namespace filesystem = std::filesystem;
int main() {
auto path = filesystem::path{"./x"};
std::cout << path << std::endl;
std::cout << filesystem::relative(path, "./") << std::endl; //
}
Produces
"./x"
"x"

why path::root_name() has different behavior with <filesystem> and <experimental/filesystem>

For last couple of days I have been experimenting the behavior of few of the functions of filesystem and experimental/filesystem library.
Note: I ran the code on https://godbolt.org/
below is the code snippet with its output
1. experimental/filesystem
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main()
{
auto p = fs::path("//net");
std::cout<<"p = " << p
<<"\np.root_name= "<< p.root_name()
<<"\nand p.root_Dir= "<< p.root_directory()
<<"\np.is_absolute= "<<p.is_absolute()<<std::endl;
}
output:
p = "//net"
p.root_name= "//net"
and p.root_Dir= ""
p.is_absolute= 0
2. filesystem
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
auto p = fs::path("//net");
std::cout<<"p = " << p
<<"\np.root_name= "<< p.root_name()
<<"\nand p.root_Dir= "<< p.root_directory()
<<"\np.is_absolute= "<<p.is_absolute()<<std::endl;
}
output:
p = "//net"
p.root_name= ""
and p.root_Dir= "/"
p.is_absolute= 1
Is there any way to look into the implementation of these functions ?

Error while trying to show files using <filesystem> in 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.

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).

getting a sub string of a std::wstring

How can I get a substring of a std::wstring which includes some non-ASCII characters?
The following code does not output anything:
(The text is an Arabic word contains 4 characters where each character has two bytes, plus the word "Hello")
#include <iostream>
#include <string>
using namespace std;
int main()
{
wstring s = L"سلام hello";
wcout << s.substr(0,3) << endl;
wcout << s.substr(4,5) << endl;
return 0;
}
This should work: live on Coliru
#include <iostream>
#include <string>
#include <boost/regex/pending/unicode_iterator.hpp>
using namespace std;
template <typename C>
std::string to_utf8(C const& in)
{
std::string result;
auto out = std::back_inserter(result);
auto utf8out = boost::utf8_output_iterator<decltype(out)>(out);
std::copy(begin(in), end(in), utf8out);
return result;
}
int main()
{
wstring s = L"سلام hello";
auto first = s.substr(0,3);
auto second = s.substr(4,5);
cout << to_utf8(first) << endl;
cout << to_utf8(second) << endl;
}
Prints
سلا
hell
Frankly though, I think your substring calls are making weird assumptions. Let me suggest a fix for that in a minute: