0

This function returns an array of strings with a list of files in a folder. It looks like this:

"folder//xyz.txt"

How can I make it look like this?

folder//xyz.txt

Its the same but without "".

vector<string> list_of_files(string folder_name)                           
{
    vector<string> files;
    string path = folder_name;

    for (const auto& entry : fs::directory_iterator(path))      
    { 
        stringstream ss;
        ss << entry.path();        //convert entry.path() to string
        string str = ss.str();                  
                    
        files.push_back(ss.str());
    }  

    return files;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 12
    The quotes are how you delimit string literals, but they're almost certainly not actually in the string. Where do you get the idea there are actual quotes in the string's data? – ShadowRanger Oct 26 '20 at 20:54
  • 2
    Why are you using `std::stringstream` in this manner? Just use `string str = entry.path();` instead, as [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path) has a [conversion operator](https://en.cppreference.com/w/cpp/filesystem/path/native) to `std::string` (which you are invoking when constructing the `stringstream`). – Remy Lebeau Oct 26 '20 at 20:56
  • You can use a `trim()`function like this https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/25385766#25385766 – Galik Oct 26 '20 at 21:00
  • 5
    The quotes are coming from the `<<` operator. [`operator <<(std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path/operator_ltltgtgt) says: **std::quoted is used so that spaces do not cause truncation when later read by stream input operator.** – Barmar Oct 26 '20 at 21:03
  • @KubaWójcik See my answer. – Asteroids With Wings Oct 26 '20 at 21:05
  • @RemyLebeau Actually, it's a conversion operator to `std::basic_string`, which is not necessarily (and, on Windows, is not) `std::string`. ([read more](https://stackoverflow.com/q/57377349/4386278)) – Asteroids With Wings Oct 26 '20 at 22:50

1 Answers1

3

Erasing the first and last characters of a string is easy:

if (str.size() >= 1)
   str.erase(0, 1);   // from 1st char (#0), len 1; bit verbose as not designed for this

if (str.size() >= 1)
   str.pop_back();    // chop off the end

Your quotes have come from inserting the path to a stream (quoted is used to help prevent bugs due to spaces down the line).

Fortunately, you don't need any of this: as explored in the comments, the stringstream is entirely unnecessary; the path already converts to a string if you ask it to:

vector<string> list_of_files(string folder_name)
{
    vector<string> files;

    for (const auto& entry : fs::directory_iterator(folder_name))
        files.push_back(entry.path().string());

    return files;
}
Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • This is probably the best way to do it currently. But this looks like such a good application of C++20 ranges, where `list_of_files` could be a one liner with a `ranges::views::transform` on `fs::directory_iterator` to compute `.path()` o each element. Until you actually try to do it and stumble on the current complication of converting the range to a `std::vector`. I guess let's have hope for C++23. – darcamo Oct 26 '20 at 21:35
  • Im getting 2 errors when im not using stringstream https://imgur.com/a/NmcV2st – Kuba Wójcik Oct 26 '20 at 21:38
  • @KubaWójcik The implicit conversion should have been enough, but try it with `.string()` to be clear. Probably a VS thing. – Asteroids With Wings Oct 26 '20 at 22:36
  • 1
    @darcamo Dunno, a simple for loop is much simpler and easier to read than all of that complicated stuff. – Asteroids With Wings Oct 26 '20 at 22:37
  • @KubaWójcik Ah, my mistake, it was because the implicit conversion is actually to the _"native"_ string type, which for Windows is `wstring`, not `string. ([read more](https://stackoverflow.com/q/57377349/4386278)) – Asteroids With Wings Oct 26 '20 at 22:50
  • @KubaWójcik Note that this may be important, if you have paths with non-ASCII characters in them. Consider having a vector of something else, or performing a conversion to UTF-8. – Asteroids With Wings Oct 26 '20 at 22:52
  • The result of `path().string()` on Windows is unspecified: "*Otherwise, if `path::value_type` is `wchar_t`, **conversion, if any, is unspecified**. This is the case on Windows, where `wchar_t` is 16 bit and the native encoding is UTF-16.*" So yes, a `vector` would be a better choice in that case, and then you can use `path().wstring()` instead of `path().string()`. Or, why not just use a `vector` instead, and do all processing on `path`s as much as possible? Don't convert `path`s to `string`s unless you need to interact with platform APIs that require file path strings. – Remy Lebeau Oct 27 '20 at 01:44