c++ 函数向文件路径添加额外的"\"?

c++ Function to add an extra '' to a filepath?

本文关键字:添加 函数 文件 路径 c++      更新时间:2023-10-16

我有大约3500个完整的文件路径要通过(ex. "C:UsersNickDocumentsReadInsNC_000852.gbk")进行排序。我刚刚了解到,在读取文件路径时,c++无法识别单个反斜杠。我正在读取大约3500个文件路径,因此手动更改每个路径会过于乏味。

我有一个for循环,它查找单个反斜杠并在该索引处插入一个双反斜杠。此:

string line = "C:UsersNickDocumentsReadInsNC_000852.gbk";
    for (unsigned int i = 0; i < filepath.size(); i++) {
        if(filepath[i] == '') {
            filepath.insert(i, '');
        }
    }

但是,由于反斜杠字符,c++,特别是在c::b上,不会编译。有没有办法用函数添加额外的反斜杠字符?

我从一个文本文件中读取文件路径,所以它们被读取到string filepath变量中,这只是一个测试。

使用双反斜杠作为''"C:\Users..."。因为带有下一个字符的单个反斜杠构成转义
此外,string::insert()方法的第二个参数需要的字符数在代码中丢失
有了所有这些修复,它编译得很好:

  string filepath = "C:\Users\Nick\Documents\ReadIns\NC_000852.gbk";
  //                   ^^     ^^    ^^         ^^       ^^
    for (unsigned int i = 0; i < filepath.size(); i++) {
        if(filepath[i] == '') {
        //                 ^^
            filepath.insert(i, 1, ''); 
        }   //                 ^^^^^^^
    }   

我不确定上述逻辑是如何运作的。但下面是我喜欢的方式:

for(auto pos = filepath.find(''); pos != string::npos; pos = filepath.find('', ++pos))
  filepath.insert(++pos, 1, '');

如果您只有一个字符需要替换(例如linux系统或可能在windows中支持);然后,您也可以使用std::replace()来避免这个答案中提到的循环:

std::replace(filepath.begin(), filepath.end(), '', '/');

我假设,您已经创建了一个包含单个反斜杠的文件,并且正在使用它进行解析
但从你的评论中,我注意到你显然是在运行时直接获得文件路径的(即在运行.exe时)。在这种情况下,正如@MSchangers所提到的,你不必担心这样的转换(即更改反斜杠)。

您看到的问题是,在C++中,字符串文字通常用""引号括起来。这带来了一个小问题:如何将引号放在字符串文字中,而该引号将结束字符串文字。解决方案是转义。这也可以用于向字符串中添加一些其他字符,例如n(换行符)。由于现在在字符串文字中有一个特殊的含义,它也被用来转义自己。所以"\"是一个只包含一个字符的字符串(当然还有一个尾随的NUL)。

这也适用于字符文字:char example[4] = {'a', '', 'b', 0}是编写"a\b"的另一种方式。

现在,这一切都与编译时有关,此时编译器需要分离C++代码和字符串内容。一旦运行了可执行文件,反斜杠就只是一个字符。std::cout << "a\b"打印一个反斜杠,因为内存中只有一个。std::String word; std::cin >> word将读取一个单词,如果您输入一个反斜杠,则word将包含一个反斜线。编译器与此无关。

因此,如果您从std::ifstream list_of_filenames读取3500个文件名,然后使用它来创建另外的3500个std::ifstream,那么在指定代码中的第一个文件名时只需要担心反斜杠。如果你从argv[1]中获取文件名,你根本不需要在意。

摆脱反斜杠特殊处理的一种方法是将所有文件名保存在一个单独的磁盘文件中,并使用文件流对象(如ifstream)获取C++格式的文件名。

TCHAR tcszFilename[MAX_PATH] = {0};
ifstream ObjInFiles( "E:\filenames.txt" );
ObjInFiles.getline( tcszFilename, MAX_PATH );
ObjInFiles.close();

假设存储在filenames.txt中的第一个文件名是"e:\temp\abc.txt",那么在执行上面的getline()之后,变量tcszFilename将保存"e:\\temp\\abc.txt"。