C++ 替换文件扩展名时崩溃

C++ 替换文件扩展名时崩溃,c++,string,replace,C++,String,Replace,我正在尝试创建字符串,使用.replace命令将目录中的.png和.jpg文件(其中所有文件仅包含这些扩展名)替换为.txt,如下所示: //say path is directory path.replace(path.end()-3, path.end()-1, "txt"); 但它一直在破坏我的程序,我做错了什么?它正确地找到了“png”部分,但替换不起作用 当我这样做的时候会发生什么 string a = dir.getPath(i); //this is ..\data\image

我正在尝试创建字符串,使用.replace命令将目录中的.png和.jpg文件(其中所有文件仅包含这些扩展名)替换为.txt,如下所示:

//say path is directory
path.replace(path.end()-3, path.end()-1, "txt");
但它一直在破坏我的程序,我做错了什么?它正确地找到了“png”部分,但替换不起作用

当我这样做的时候会发生什么

string a = dir.getPath(i); //this is ..\data\images\Test0.png
string b = dir.getPath(i).replace(dir.getPath(i).end()-3, dir.getPath(i).end(), "txt"); //crashes

从第二个参数中删除-1

string path = "filename.png";
path.replace(path.end() - 3, path.end(), "txt");
导致路径存储:

"filename.txt"
因为第一个参数指示从何处开始替换字符,第二个参数指示从何处停止(您在替换最后一个字符后停止,而不是在它前面的一个位置),最后一个参数指定替换它的内容

更新:
对于更新后的问题,可以通过询问您自己dir.getPath(i)返回什么来回答您的问题?字符串的新实例。您正在尝试从一个字符串中的迭代器遍历到另一个字符串中的迭代器。

如果要替换最后三个字符,需要提供一个包含三个字符的范围。目前,您的范围只有两个字符,即从
end()-3
(含)到
end()-1
(不含)

需要

string b = dir.getPath(i);
b.replace(b.end()-3, b.end(), "txt"); // Does not crash

可以通过以下方式完成

#include <iostream>
#include <string>

int main() 
{
    std::string s( "..\\data\\images\\Test0.png" );

    std::cout << s << std::endl;

    std::string::size_type pos;

    if ( ( ( pos = s.rfind( ".png" ) ) != std::string::npos ) ||
         ( ( pos = s.rfind( ".jpg" ) ) != std::string::npos ) )
    {        
        s.replace( pos, std::string::npos, ".txt" );
    }

    std::cout << s << std::endl;

    return 0;
}

@这个参数很奇怪。尝试在前后添加一些打印输出,并检查字符串是否足够长,以便替换。如果在运行此代码段之前一切正常,请运行内存探查器,以确保您看到的错误不是由前面的某个错误引起的。我认为这是因为我需要获取文件的绝对路径,而不是相对路径,请参见更新question@parameter就这样!您在同一个表达式中多次使用
dir.getPath(i)
,不能这样做。您需要使用
b.end()-3,b.end()
。看到edit.wow,我不认为这会有什么不同,你有没有理由必须先将它重新分配给不同的字符串?谢谢@参数当通过值返回
getPath
时,每个调用都会生成不同的
std::string
对象。通过
begin
end
获得的迭代器仅在它们自己的副本中有效。如果将不同副本中的迭代器传递到任何算法或成员函数中,例如
replace
,则会得到未定义的行为。我打赌
dir.getPath(I)
每次调用时都会返回一个新字符串。因此
dir.getPath(i.end()-3
dir.getPath(i.end()
是两个不同字符串的迭代器,它们都不是您调用的
replace
。相反,请执行
a.replace(a.end()…)
-调用
getPath
一次,将结果存储在变量中,然后操作该变量。@parameter请参阅我的答案。
string b = dir.getPath(i);
b.replace(b.end()-3, b.end(), "txt"); // Does not crash
#include <iostream>
#include <string>

int main() 
{
    std::string s( "..\\data\\images\\Test0.png" );

    std::cout << s << std::endl;

    std::string::size_type pos;

    if ( ( ( pos = s.rfind( ".png" ) ) != std::string::npos ) ||
         ( ( pos = s.rfind( ".jpg" ) ) != std::string::npos ) )
    {        
        s.replace( pos, std::string::npos, ".txt" );
    }

    std::cout << s << std::endl;

    return 0;
}
..\data\images\Test0.png
..\data\images\Test0.txt