循环访问字符串片段

Iterate over string fragments

本文关键字:片段 字符串 访问 循环      更新时间:2023-10-16

我有lua路径,例如:

"/home/user/?.lua;/home/test/?/init.lua;./lua"

我想遍历每个片段(例如/home/user/?.lua/home/test/?/init.lua./lua(。由于某些原因,我的尝试无法正常工作:

size_t begin = 0;
size_t next = searchpath.find_first_of(";", 0);
do
{
if (next == std::string::npos)
next = searchpath.length();
std::string prefix = searchpath.substr(begin, next);
std::cout << "Trying: " << prefix << "n";
begin = next + 1;
next = searchpath.find_first_of(";", begin);
} while (begin < (int)searchpath.length());

输出:

Trying: /home/v/.luarocks/share/lua/5.2/?.lua
Trying: /home/v/.luarocks/share/lua/5.2/?/init.lua;/usr/share/lua/5.2/?.lua;/usr/share/l
Trying: /usr/share/lua/5.2/?.lua;/usr/share/lua/5.2/?/init.lua;/usr/local/share/lua/5.2/?.lua;/usr/local/share/lu
Trying: /usr/share/lua/5.2/?/init.lua;/usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/local/lib/lua/5.2/?.lua;/usr/loca
Trying: /usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/local/lib/lua/5.2/?.lua;/usr/local/lib/lua/5.2/?/init.lua;./?.lua;/home/v/.lua/libs/?.lua;/hom
Trying: /usr/local/share/lua/5.2/?/init.lua;/usr/local/lib/lua/5.2/?.lua;/usr/local/lib/lua/5.2/?/init.lua;./?.lua;/home/v/.lua/libs/?.lua;/home/v/.lua/libs/?.lua;./lib/?.lua;./lib/?/init.lua
Trying: /usr/local/lib/lua/5.2/?.lua;/usr/local/lib/lua/5.2/?/init.lua;./?.lua;/home/v/.lua/libs/?.lua;/home/v/.lua/libs/?.lua;./lib/?.lua;./lib/?/init.lua
Trying: /usr/local/lib/lua/5.2/?/init.lua;./?.lua;/home/v/.lua/libs/?.lua;/home/v/.lua/libs/?.lua;./lib/?.lua;./lib/?/init.lua
Trying: ./?.lua;/home/v/.lua/libs/?.lua;/home/v/.lua/libs/?.lua;./lib/?.lua;./lib/?/init.lua
Trying: /home/v/.lua/libs/?.lua;/home/v/.lua/libs/?.lua;./lib/?.lua;./lib/?/init.lua
Trying: /home/v/.lua/libs/?.lua;./lib/?.lua;./lib/?/init.lua
Trying: ./lib/?.lua;./lib/?/init.lua

你能解释一下我的代码有什么问题,什么是正确的方法吗?

问题是:

std::string prefix = searchpath.substr(begin, next);

std::string::substr采用偏移量 + 计数参数,而不是开始 + 结束参数。

你需要:

std::string prefix = searchpath.substr(begin, next-begin);

所以完整地:

#include <iostream>
#include <string>
int main()
{
std::string searchpath = "a;b;c";
size_t begin = 0;
size_t next = searchpath.find_first_of(";", 0);
do
{
if (next == std::string::npos)
next = searchpath.length();
std::string prefix = searchpath.substr(begin, next-begin);
std::cout << "Trying: " << prefix << "n";
begin = next + 1;
next = searchpath.find_first_of(";", begin);
} while (begin < (int)searchpath.length());
}

(注意,这就是你的问题应该的样子。 一个完整的程序。

我实际上会写成:

#include <iostream>
#include <string>
int main()
{
std::string searchpath = "a;b;c";
for (size_t begin = 0, next; begin < searchpath.length(); begin = next+1)
{
next = searchpath.find(';', begin);
if (next == std::string::npos)
next = searchpath.length();
std::string prefix = searchpath.substr(begin, next-begin);
std::cout << "Trying: " << prefix << "n";
}
}

它重复较少,定位循环的开始和旁边,使用find而不是find_first_of,并且没有不必要的强制转换。

只是除了@Martin邦纳的回答。

在我看来,它可以做得更容易、更易读,看看吧。

char someInput[] = "/home/user/?.lua;/home/test/?/init.lua;./lua";
std::string searchpath(someInput);
std::string temp;
std::size_t pos = std::string::npos;
pos = searchpath.find(";");
while (pos != std::string::npos)
{
temp = searchpath.substr(0, pos);
searchpath = searchpath.substr(pos + 1);
pos = searchpath.find(";");
std::cout << "Trying: " << temp << std::endl;
}
std::cout << searchpath << std::endl;

输出

Trying: /home/user/?.lua
Trying: /home/test/?/init.lua
Trying: ./lua

在这里,使用 std::getline(( 的简单版本:

#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::istringstream input{"/home/user/?.lua;/home/test/?/init.lua;./lua"};
for (std::string prefix ; std::getline(input, prefix, ';') ; ) {
std::cout << "Trying: " << prefix << "n";
}
}

演示

输出

正在尝试:/home/user/?.lua Trying:/home/test/?/init.lua
Trying: ./lua