我要做的是先走一条路径,然后按目录不断擦除路径目录,检查它是否是任何一点的符号链接。这就是我所拥有的:
static bool isLinkDirInSymLink (std::string linkPath)
{
DIR *baseDir;
struct dirent *currentDir;
do
{
baseDir = opendir(linkPath.c_str());
if (baseDir)
{
currentDir = readdir(baseDir);
if (currentDir->d_type == DT_LNK)
return true;
}
linkPath.erase (linkPath.find_last_of("/") + 1, linkPath.find_first_of("\0"));
} while (strcmp(linkPath.c_str(), "") != 0);
return false;
}
这会陷入无限循环。当我在gdb
中运行该程序时,我发送了linkPath
/home/user/test/linktest/out/mDirs/testDir1/test
的{{1}},当成功删除并且我留下的是/home/user/test/linktest/out/mDirs/testDir1
时,这就是无限循环开始。即使它与进入erase
的第一条路径的格式相同,也没有任何反应。我尝试了erase
linkPath.append('\0')
的许多不同版本,但似乎都没有。我也试过char realPath[MAX_FILELENGTH];
do
{
if (realpath (linkPath.c_str(), realPath) != NULL)
if (strcmp(linkPath.c_str(), realPath) != 0)
return true;
size_t eraseFrom = linkPath.rfind('/');
if (std::string::npos != eraseFrom)
linkPath.erase(eraseFrom);
} while ( !linkPath.empty() );
return false;
,因为我觉得这可能是最后一个空字符的问题。
谢谢大家,这就是我最终的目标:
<button data-key="some value" name="" id="">click me</button>
答案 0 :(得分:3)
linkPath.find_last_of("/") + 1
应该是;
linkPath.find_last_of("/")
第一次擦除会留下尾随/
,因此下一次擦除会尝试从字符串末尾擦除到结尾,因此循环。擦除应包括目录分隔符/
。
不需要linkPath.find_first_of("\0")
,您可以使用npos
删除字符串的末尾。使用find_first_of
会给出尺寸类型结果,因此使用以下形式的擦除basic_string& erase( size_type index = 0, size_type count = npos );
。
答案 1 :(得分:3)
由于您在擦除呼叫中+ 1
,您正在删除从/
之后到字符串结尾之前的字符,删除以下字符:
/home/user/test/linktest/out/mDirs/testDir1/test\0
^^^^
循环的第一次迭代将删除test
,留下/home/user/test/linktest/out/mDirs/testDir1/
。对erase
的所有后续调用都不会执行任何操作,因为/
和\0
之间的字符数为零。
您应该从擦除调用中移除+ 1
linkPath.find_last_of("/") + 1
,以便删除尾部斜杠。
此外,erase(size_t, size_t)
重载实际上将部件的 length 擦除为第二个参数 - find_first_of
返回找到的字符的索引,而不是迭代器它。您的代码只能偶然使用。使用std::string::npos
,它将删除所有内容,直到结尾,而不是\0
字符的位置(如果您尚未调用c_str()
,则可能不会出现在字符串中)。
答案 2 :(得分:1)
我猜你在查看调试器时错过了斜杠。这可能更好:
linkPath.erase (linkPath.begin()+linkPath.find_last_of("/"), linkPath.end());
另一个问题是std::string::erase
的错误重载被调用:this list中的#1(“pos + len”),而你可能想要#3(“范围”)。这是因为std::string::find_last_of返回size_t
,而不是迭代器。或者,为了节省输入,您可以使用:
linkPath.resize(linkPath.find_last_of("/"));
答案 3 :(得分:0)
我认为你的意思如下:
#include <iostream>
#include <string>
int main()
{
std::string linkPath( "http://stackoverflow.com/questions/31590945/"
"continually-erasing-string-leads-to-infinite-loop" );
do
{
std::cout << linkPath << std::endl;
auto n = linkPath.rfind( '/' );
n = n == std::string::npos ? 0 : n;
linkPath.erase( n );
} while ( !linkPath.empty() );
}
程序输出
http://stackoverflow.com/questions/31590945/continually-erasing-string-leads-to-infinite-loop
http://stackoverflow.com/questions/31590945
http://stackoverflow.com/questions
http://stackoverflow.com
http:/
http:
当然,您可以根据需要修改代码。它演示了完成任务的方法。
至于你的代码然后这个电话
linkPath.find_first_of("\0")
将始终返回std::string::npos
。所以它不是男性意识。
并使用此表达式
linkPath.find_last_of("/") + 1
将始终保留第一个找到的字符&#39; /&#39;在字符串中。
答案 4 :(得分:0)
更正确和简化的实施
static bool isLinkDirInSymLink(std::string linkPath) {
DIR * baseDir;
struct dirent * currentDir;
do {
baseDir = opendir(linkPath.c_str());
if (baseDir) {
currentDir = readdir(baseDir);
if (currentDir->d_type == DT_LNK) return true;
}
std::string::size_type it = linkPath.rfind('/');
if (it != std::string::npos) linkPath.erase(it);
} while (!linkPath.empty());
return false;
}