The code bellow extracts the file name of a file using its path.
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout << "Program operating..." << endl;
string s = "C:\\Users\\user\\Pictures\\Strategic_Offense_Logo_1";
string name;
for (unsigned int i = s.size() - 1; i > 0; i--) {
if (s[i] == '\\') {
for (unsigned int j = i 1; j < s.size(); j ) {
if (s[j] == '.' || j == s.size() - 1) {
if (j == s.size() - 1)
j ;
vector<char> v(j - i - 1);
unsigned int l = 0;
for (unsigned int k = i 1; k < j; k ) {
v[l ] = s[k];
}
char* vectorAsArray = &v[0];
name = vectorAsArray;
name.resize(v.size());
break;
}
}
break;
}
}
cout << name << endl;
}
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout << "Program operating..." << endl;
string s = "C:\\Users\\user\\Pictures\\Strategic_Offense_Logo_1.png";
string name;
for (unsigned int i = s.size() - 1; i > 0; i--) {
if (s[i] == '\\') {
for (unsigned int j = i 1; j < s.size(); j ) {
if (s[j] == '.' || j == s.size() - 1) {
if (j == s.size() - 1)
j ;
vector<char> v(j - i - 1);
unsigned int l = 0;
for (unsigned int k = i 1; k < j; k ) {
v[l ] = s[k];
}
char* vectorAsArray = &v[0];
name = vectorAsArray;
name.resize(v.size());
break;
}
}
break;
}
}
cout << name << endl;
}
Is there a more efficient way to do this?
Purpose: I am making a texture class and I want to refer the texture by its name instead of its path or a made up ID.
Note: library does not work at all with the visual studio compiler. If you know how to fix it or have an alternative solution, please post.

CodePudding user response:
Use std::filesystem::path::filename.
That said, you should refer to the texture by its fully qualified path or a unique ID; otherwise, you will get collisions for textures with the same name in different folders.
CodePudding user response:
The simplest solution is to use the <filesystem> library in C 17 onward, specifically the std::filesystem::path class and its stem() method:
Returns the filename identified by the generic-format path stripped of its extension.
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
using namespace std;
int main() {
cout << "Program operating..." << endl;
//fs::path p = "C:" / "Users" / "user" / "Pictures" / "Strategic_Offense_Logo_1.png";
fs::path p = "C:\\Users\\user\\Pictures\\Strategic_Offense_Logo_1.png";
fs::path name = p.stem();
cout << name << endl;
}
However, if that is not an option, there is a simple solution using the available methods of std::string, such as rfind() and substr():
#include <iostream>
#include <string>
using namespace std;
int main() {
cout << "Program operating..." << endl;
string s = "C:\\Users\\user\\Pictures\\Strategic_Offense_Logo_1.png";
string name = s.substr(s.rfind('\\') /* or: s.find_last_of("\\/") */ 1);
name.resize(name.rfind('.'));
cout << name << endl;
}
CodePudding user response:
Visual Studio defaults to C 14. To be able to access <filesystem> and all of its features (like extracting file names), one has to go into the solution properties under C and change the version to the latest. Then, and only then, <filesystem> will work, as everyone in the Internet and StackOverflow talks about.
