从C ++中的文件路径中提取文件名
extracting a file name from file path in c++
我有一个存储文件路径的字符串,我正在做一些字符串处理,索引一个 std::string
对象,但是输出字符串很奇怪,代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string x = "C:\Users\lenovo\Desktop\QBFdata.txt";
string temp = "";
for(int i = x.length() - 1; i > 0; i--)
{
if(x[i] == '\')
break;
else
temp.append(&x[i]);
}
cout << temp << "\n";
}
但输出显然很奇怪,它再次将 temp
的内容附加到它。
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt
请不要提出任何替代方案,因为我已经有了解决方案
int main()
{
string x = "C:\Users\NK\Desktop\QBFdata.txt";
int pos = x.find_last_of('\');
string temp = x.substr(pos + 1);
cout << temp;
}
它工作正常。
我想知道第一个代码有什么问题
谢谢。
我正在使用代码块 16.01
您得到此输出的原因是因为当您这样做时:
temp.append(&x[i]);
它不附加一个字母,
而是来自索引 i
的 字符串 的整个后缀。
这是我在每次迭代中打印 temp 时的代码输出
temp.append(&x[i]);
cout << temp << "\n";
输出显示您首先附加单个字母 t,然后是 xt,然后是 txt,等等。
t
txt
txttxt
txttxt.txt
txttxt.txta.txt
txttxt.txta.txtta.txt
txttxt.txta.txtta.txtata.txt
txttxt.txta.txtta.txtata.txtdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt
好的,是这样的:
您的原始代码首先从字符串的后面开始,因此您的代码第一次运行 if(x[i] == '\')
行时,它会查看 x[34]
.
x[34]
是路径末尾的 "t"
。
接下来您的代码将其附加到尚未为空的临时字符串。
下次迭代时它会查看 x[33]
.
x[33]
是对 'x'
字符的引用。现在,如果您一次只附加一个字符,一切都会很好(除了您的字符串会向后)。然而,一个字符串的追加函数追加了另一个字符串,所以我认为发生了什么(如果我错了,请更有经验的程序员纠正我),我认为编译器正在从 char*
进行隐式转换(这是什么一个 C 风格的字符串如果它以 null 结尾)到一个 std::string
对象并附加那个字符串。
这意味着它附加了从 'x'
字符开始的 c 字符串,所以这次它将 "xt"
从上方附加到 t 的后面。
下一次迭代引用从 x[32] 开始的 C 字符串,因此它附加 "txt"
下一次迭代引用从 x[31] 开始的 C 字符串,因此它附加 ".txt"
下一次迭代引用从 x[30] 开始的 c 字符串,因此它附加 "a.txt"
然后 "ta.txt"
依此类推...
总计它为您提供了以下所有按以下顺序附加的字符串:
"t" + "xt" + "txt" + ".txt" + "a.txt" + "ta.txt" + "ata.txt" + "data.txt" + "Fdata.txt" + "BFdata.txt" + "QBFdata.txt"
将您的最终字符串呈现为:"txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt"
希望这对您有所帮助。
编码愉快! :)
正如其他人所说,问题是您使用了错误的 std::string::append()
重载,因此您在每次循环迭代中附加了整个子字符串,而不是单个字符。
要一次附加一个字符,请改用以下之一:
temp.append(&x[i], 1);
temp.push_back(x[i]);
temp += x[i];
然而,由于你是向后循环,你需要 prepend 字符串前面的每个字符而不是 append 到 BACK :
temp.insert(0, &x[i], 1);
temp = x[i] + temp;
我有一个存储文件路径的字符串,我正在做一些字符串处理,索引一个 std::string
对象,但是输出字符串很奇怪,代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string x = "C:\Users\lenovo\Desktop\QBFdata.txt";
string temp = "";
for(int i = x.length() - 1; i > 0; i--)
{
if(x[i] == '\')
break;
else
temp.append(&x[i]);
}
cout << temp << "\n";
}
但输出显然很奇怪,它再次将 temp
的内容附加到它。
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt
请不要提出任何替代方案,因为我已经有了解决方案
int main()
{
string x = "C:\Users\NK\Desktop\QBFdata.txt";
int pos = x.find_last_of('\');
string temp = x.substr(pos + 1);
cout << temp;
}
它工作正常。
我想知道第一个代码有什么问题
谢谢。
我正在使用代码块 16.01
您得到此输出的原因是因为当您这样做时:
temp.append(&x[i]);
它不附加一个字母,
而是来自索引 i
的 字符串 的整个后缀。
这是我在每次迭代中打印 temp 时的代码输出
temp.append(&x[i]);
cout << temp << "\n";
输出显示您首先附加单个字母 t,然后是 xt,然后是 txt,等等。
t
txt
txttxt
txttxt.txt
txttxt.txta.txt
txttxt.txta.txtta.txt
txttxt.txta.txtta.txtata.txt
txttxt.txta.txtta.txtata.txtdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt
txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt
好的,是这样的:
您的原始代码首先从字符串的后面开始,因此您的代码第一次运行 if(x[i] == '\')
行时,它会查看 x[34]
.
x[34]
是路径末尾的 "t"
。
接下来您的代码将其附加到尚未为空的临时字符串。
下次迭代时它会查看 x[33]
.
x[33]
是对 'x'
字符的引用。现在,如果您一次只附加一个字符,一切都会很好(除了您的字符串会向后)。然而,一个字符串的追加函数追加了另一个字符串,所以我认为发生了什么(如果我错了,请更有经验的程序员纠正我),我认为编译器正在从 char*
进行隐式转换(这是什么一个 C 风格的字符串如果它以 null 结尾)到一个 std::string
对象并附加那个字符串。
这意味着它附加了从 'x'
字符开始的 c 字符串,所以这次它将 "xt"
从上方附加到 t 的后面。
下一次迭代引用从 x[32] 开始的 C 字符串,因此它附加 "txt"
下一次迭代引用从 x[31] 开始的 C 字符串,因此它附加 ".txt"
下一次迭代引用从 x[30] 开始的 c 字符串,因此它附加 "a.txt"
然后 "ta.txt"
依此类推...
总计它为您提供了以下所有按以下顺序附加的字符串:
"t" + "xt" + "txt" + ".txt" + "a.txt" + "ta.txt" + "ata.txt" + "data.txt" + "Fdata.txt" + "BFdata.txt" + "QBFdata.txt"
将您的最终字符串呈现为:"txttxt.txta.txtta.txtata.txtdata.txtFdata.txtBFdata.txtQBFdata.txt"
希望这对您有所帮助。
编码愉快! :)
正如其他人所说,问题是您使用了错误的 std::string::append()
重载,因此您在每次循环迭代中附加了整个子字符串,而不是单个字符。
要一次附加一个字符,请改用以下之一:
temp.append(&x[i], 1);
temp.push_back(x[i]);
temp += x[i];
然而,由于你是向后循环,你需要 prepend 字符串前面的每个字符而不是 append 到 BACK :
temp.insert(0, &x[i], 1);
temp = x[i] + temp;