将std :: string to to struct to struct

发布于 2025-01-26 19:29:33 字数 654 浏览 3 评论 0原文

假设我有以下我想按下定界符'>'的字符串:

std::string veg = "orange>kiwi>apple>potato";

我希望将字符串中的每个项目放在具有以下格式的结构中:

struct pack_item
{
    std::string it1;
    std::string it2;
    std::string it3;
    std::string it4;
};

我知道如何这样做

pack_item pitem;

std::stringstream veg_ss(veg);
std::string veg_item;

std::getline(veg_ss, veg_item, '>')
pitem.it1 = veg_item;
std::getline(veg_ss, veg_item, '>')
pitem.it2 = veg_item;
std::getline(veg_ss, veg_item, '>')
pitem.it3 = veg_item;
std::getline(veg_ss, veg_item, '>')
pitem.it4 = veg_item;

:有一种更好的单线方法吗?

Let's say I have the following string that I want to tokenize as per the delimiter '>':

std::string veg = "orange>kiwi>apple>potato";

I want every item in the string to be placed in a structure that has the following format:

struct pack_item
{
    std::string it1;
    std::string it2;
    std::string it3;
    std::string it4;
};

I know how to do it this way:

pack_item pitem;

std::stringstream veg_ss(veg);
std::string veg_item;

std::getline(veg_ss, veg_item, '>')
pitem.it1 = veg_item;
std::getline(veg_ss, veg_item, '>')
pitem.it2 = veg_item;
std::getline(veg_ss, veg_item, '>')
pitem.it3 = veg_item;
std::getline(veg_ss, veg_item, '>')
pitem.it4 = veg_item;

Is there a better and one-liner kind of way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

┼── 2025-02-02 19:29:33

这样的事情:

#include <string>
#include <vector>
#include <sstream>
#include <iostream>

std::string veg = "orange>kiwi>apple>potato";

typedef std::vector<std::string> it_vec;

int main(int argc, char* argv[]) {
    it_vec vec;
    
    std::stringstream veg_ss(veg);
    std::string veg_item;

    while (std::getline(veg_ss, veg_item, '>')) {
        vec.push_back(veg_item);
    }
    
    for (const std::string& vec_item : vec) {
        std::cout << vec_item << std::endl;
    }
}

Something like this:

#include <string>
#include <vector>
#include <sstream>
#include <iostream>

std::string veg = "orange>kiwi>apple>potato";

typedef std::vector<std::string> it_vec;

int main(int argc, char* argv[]) {
    it_vec vec;
    
    std::stringstream veg_ss(veg);
    std::string veg_item;

    while (std::getline(veg_ss, veg_item, '>')) {
        vec.push_back(veg_item);
    }
    
    for (const std::string& vec_item : vec) {
        std::cout << vec_item << std::endl;
    }
}
惜醉颜 2025-02-02 19:29:33

您不需要中间变量。

pack_item pitem;

std::stringstream veg_ss(veg);

std::getline(veg_ss, pitem.it1, '>');
std::getline(veg_ss, pitem.it2, '>');
std::getline(veg_ss, pitem.it3, '>');
std::getline(veg_ss, pitem.it4, '>');

您可能需要使该功能成为一个函数,例如运算符&gt;&gt; (使用类似的运营商&lt;&lt;

std::istream& operator >>(std::istream& is, pack_item & pitem) {
    std::getline(is, pitem.it1, '>');
    std::getline(is, pitem.it2, '>');
    std::getline(is, pitem.it3, '>');
    std::getline(is, pitem.it4, '>');
    return is;
}

std::ostream& operator <<(std::ostream& os, pack_item & pitem) {
    return os << pitem.it1 << '>'
              << pitem.it2 << '>'
              << pitem.it3 << '>'
              << pitem.it4 << '>';
}

int main() {
    std::stringstream veg_ss("orange>kiwi>apple>potato>");
    pack_item pitem;
    veg_ss >> pitem;
}

是否有更好的单线方法?

您可以制作一个类型&gt;&gt;在字符串中读取到定界符,并在一个语句中读取所有四个元素。那真的是“更好”吗?

template <bool is_const>
struct delimited_string;

template<>
struct delimited_string<true> {
    const std::string & string;
    char delim;
};

template<>
struct delimited_string<false> {
    std::string & string;
    char delim;
};

delimited_string(const std::string &, char) -> delimited_string<true>;
delimited_string(std::string &, char) -> delimited_string<false>;

std::istream& operator >>(std::istream& is, delimited_string<false> s) {
    return std::getline(is, s.string, s.delim);
}

template <bool is_const>
std::ostream& operator <<(std::ostream& os, delimited_string<is_const> s) {
    return os << s.string << s.delim;
}

std::istream& operator >>(std::istream& is, pack_item & pitem) {
    return is >> delimited_string { pitem.it1, '>' }
              >> delimited_string { pitem.it2, '>' }
              >> delimited_string { pitem.it3, '>' }
              >> delimited_string { pitem.it4, '>' };
}

std::ostream& operator <<(std::ostream& os, const pack_item & pitem) {
    return os << delimited_string { pitem.it1, '>' }
              << delimited_string { pitem.it2, '>' }
              << delimited_string { pitem.it3, '>' }
              << delimited_string { pitem.it4, '>' };
}

You don't need an intermediate variable.

pack_item pitem;

std::stringstream veg_ss(veg);

std::getline(veg_ss, pitem.it1, '>');
std::getline(veg_ss, pitem.it2, '>');
std::getline(veg_ss, pitem.it3, '>');
std::getline(veg_ss, pitem.it4, '>');

You might want to make that a function, e.g. operator >> (with a similar operator <<)

std::istream& operator >>(std::istream& is, pack_item & pitem) {
    std::getline(is, pitem.it1, '>');
    std::getline(is, pitem.it2, '>');
    std::getline(is, pitem.it3, '>');
    std::getline(is, pitem.it4, '>');
    return is;
}

std::ostream& operator <<(std::ostream& os, pack_item & pitem) {
    return os << pitem.it1 << '>'
              << pitem.it2 << '>'
              << pitem.it3 << '>'
              << pitem.it4 << '>';
}

int main() {
    std::stringstream veg_ss("orange>kiwi>apple>potato>");
    pack_item pitem;
    veg_ss >> pitem;
}

Is there a better and one-liner kind of way to do it?

You can make a type who's >> reads in a string up to a delimiter, and read all four elements in one statement. Is that really "better"?

template <bool is_const>
struct delimited_string;

template<>
struct delimited_string<true> {
    const std::string & string;
    char delim;
};

template<>
struct delimited_string<false> {
    std::string & string;
    char delim;
};

delimited_string(const std::string &, char) -> delimited_string<true>;
delimited_string(std::string &, char) -> delimited_string<false>;

std::istream& operator >>(std::istream& is, delimited_string<false> s) {
    return std::getline(is, s.string, s.delim);
}

template <bool is_const>
std::ostream& operator <<(std::ostream& os, delimited_string<is_const> s) {
    return os << s.string << s.delim;
}

std::istream& operator >>(std::istream& is, pack_item & pitem) {
    return is >> delimited_string { pitem.it1, '>' }
              >> delimited_string { pitem.it2, '>' }
              >> delimited_string { pitem.it3, '>' }
              >> delimited_string { pitem.it4, '>' };
}

std::ostream& operator <<(std::ostream& os, const pack_item & pitem) {
    return os << delimited_string { pitem.it1, '>' }
              << delimited_string { pitem.it2, '>' }
              << delimited_string { pitem.it3, '>' }
              << delimited_string { pitem.it4, '>' };
}
素年丶 2025-02-02 19:29:33

正如评论中建议的那样,您可以将其用于循环:

pack_item a;
std::array<std::reference_wrapper<std::string>, 4> arr{a.it1, a.it2, a.it3, a.it4};

constexpr std::string_view veg = "orange>kiwi>apple>potato";
std::istringstream ss(veg.data());

std::string str;

for(std::size_t idx = 0; std::getline(ss, str, '>'); ++idx){
    arr[idx].get() = std::move(str);
}

如果您的意思是“单线”,那么您可能会讨厌并使用:

std::getline(std::getline(std::getline(std::getline(ss, a.it1, '>'), a.it2, '>'), a.it3, '>'), a.it4, '>');

As suggested in the comments, you could use a for loop as such:

pack_item a;
std::array<std::reference_wrapper<std::string>, 4> arr{a.it1, a.it2, a.it3, a.it4};

constexpr std::string_view veg = "orange>kiwi>apple>potato";
std::istringstream ss(veg.data());

std::string str;

for(std::size_t idx = 0; std::getline(ss, str, '>'); ++idx){
    arr[idx].get() = std::move(str);
}

If you meant "one-liner" in its true sense, then you could be nasty and use:

std::getline(std::getline(std::getline(std::getline(ss, a.it1, '>'), a.it2, '>'), a.it3, '>'), a.it4, '>');
煮茶煮酒煮时光 2025-02-02 19:29:33

确实:

#include <iostream>
#include <sstream>
#include <string>

struct pack_item
{
    std::string it1;
    std::string it2;
    std::string it3;
    std::string it4;
};

pack_item pack( const std::string & s )
{
  pack_item p;
  getline(getline(getline(getline(std::istringstream(s), p.it1,'>'), p.it2,'>'), p.it3,'>'), p.it4);
  return p;
}

int main()
{
  auto pitem = pack( "orange>kiwi>apple>potato" );
  
  std::cout << pitem.it4 << "<" << pitem.it3 << "<" << pitem.it2 << "<" << pitem.it1 << "\n";
}

顺便说一句,多行代码没有错。对单线的寻求通常是对以正确的方式做事的分心。

Indeed:

#include <iostream>
#include <sstream>
#include <string>

struct pack_item
{
    std::string it1;
    std::string it2;
    std::string it3;
    std::string it4;
};

pack_item pack( const std::string & s )
{
  pack_item p;
  getline(getline(getline(getline(std::istringstream(s), p.it1,'>'), p.it2,'>'), p.it3,'>'), p.it4);
  return p;
}

int main()
{
  auto pitem = pack( "orange>kiwi>apple>potato" );
  
  std::cout << pitem.it4 << "<" << pitem.it3 << "<" << pitem.it2 << "<" << pitem.it1 << "\n";
}

BTW, there is nothing wrong with multiple lines of code. The quest for the one-liner is often a distraction to doing things the Right Way™.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文