重载运算符>>以从字符串创建数组

huangapple go评论99阅读模式
英文:

Overloading operator>> to create array from string

问题

我想从一个std::string创建一个std::array

为此,我想重载operator>>

我有以下的测试用例:

  1. std::istream& operator>>(std::istream& is, const std::array<double, 3>& a)
  2. {
  3. char p1, p2;
  4. is >> p1;
  5. // 如果失败,提醒用户
  6. for (unsigned int i = 1; i < a.size(); ++i)
  7. {
  8. // 忽略/检查是否为数字的一些操作
  9. }
  10. is >> p2;
  11. // 如果失败,提醒用户
  12. return is;
  13. }
  14. int main()
  15. {
  16. std::string a = "[1 2 3]";
  17. std::array<double, 3> arr;
  18. std::istringstream iss(a);
  19. iss >> arr;
  20. return 0;
  21. }

我希望操作符能够检查字符[]是否处于正确的位置,并使用括号内的元素构造数组。

如何检查提取是否成功?如何检查括号内的字符串是否为数字,如果是,如何从中构造数组?

谢谢!

英文:

I would like to create an std::array from a std::string.

For this, I would like to overload the operator&gt;&gt;.

I have the following test case:

  1. std::istream&amp; operator&gt;&gt;(std::istream&amp; is, const std::array&lt;double, 3&gt;&amp; a)
  2. {
  3. char p1, p2;
  4. is &gt;&gt; p1;
  5. // if fail warn the user
  6. for (unsigned int i = 1; i &lt; a.size(); ++i)
  7. {
  8. // something to ignore/ check if numeric
  9. }
  10. is &gt;&gt; p2;
  11. // if fail warn the user
  12. return is;
  13. }
  14. int main()
  15. {
  16. std::string a = &quot;[1 2 3]&quot;;
  17. std::array&lt;double, 3&gt; arr;
  18. std::istringstream iss (a);
  19. iss &gt;&gt; arr;
  20. return 0;
  21. }

I would like for the operator to check if the characters [and ] are in the correct place and to construct the array with the elements inside.

How can I do checks if the extraction was successfull? How can I check the string between the parenthesis is numeric and if so construct my array from it?

Kind regards

答案1

得分: 2

我会为你翻译这段代码,以下是翻译的结果:

我会添加一个辅助类,用于检查流中是否存在特定字符,并在存在时将其移除。如果不存在,则设置 failbit。

示例:

  1. #include <cctype>
  2. #include <istream>
  3. template <char Ch, bool SkipWhitespace = false>
  4. struct eater {
  5. friend std::istream& operator>>(std::istream& is, eater) {
  6. if /*constexpr*/ (SkipWhitespace) { // constexpr since C++17
  7. is >> std::ws;
  8. }
  9. if (is.peek() == Ch) // 如果预期的字符存在,则移除它
  10. is.ignore();
  11. else // 否则设置 failbit
  12. is.setstate(std::ios::failbit);
  13. return is;
  14. }
  15. };

然后可以像这样使用它:

  1. std::istream& operator>>(std::istream& is, std::array<double, 3>& a) {
  2. // 使用 `eater` 类模板,将 `[` 和 `]` 作为模板参数:
  3. return is >> eater<'['>{} >> a[0] >> a[1] >> a[2] >> eater<']'>{};
  4. }
  5. int main() {
  6. std::string a = "[1 2 3]";
  7. std::array<double, 3> arr;
  8. std::istringstream iss (a);
  9. // iss.exceptions(std::ios::failbit); // 如果你想在失败时抛出异常
  10. if(iss >> arr) {
  11. std::cout << "success\n";
  12. } else {
  13. std::cout << "fail\n";
  14. }
  15. }

演示 中使用 , 作为输入的分隔符。

英文:

I'd add a helper class that checks for a certain character in the stream and removes it if it's there. If it's not, sets the failbit.

Example:

  1. #include &lt;cctype&gt;
  2. #include &lt;istream&gt;
  3. template &lt;char Ch, bool SkipWhitespace = false&gt;
  4. struct eater {
  5. friend std::istream&amp; operator&gt;&gt;(std::istream&amp; is, eater) {
  6. if /*constexpr*/ (SkipWhitespace) { // constexpr since C++17
  7. is &gt;&gt; std::ws;
  8. }
  9. if (is.peek() == Ch) // if the expected char is there, remove it
  10. is.ignore();
  11. else // else set the failbit
  12. is.setstate(std::ios::failbit);
  13. return is;
  14. }
  15. };

And it could then be used like this:

  1. std::istream&amp; operator&gt;&gt;(std::istream&amp; is, std::array&lt;double, 3&gt;&amp; a) {
  2. // use the `eater` class template with `[` and `]` as template parameters:
  3. return is &gt;&gt; eater&lt;&#39;[&#39;&gt;{} &gt;&gt; a[0] &gt;&gt; a[1] &gt;&gt; a[2] &gt;&gt; eater&lt;&#39;]&#39;&gt;{};
  4. }
  5. int main() {
  6. std::string a = &quot;[1 2 3]&quot;;
  7. std::array&lt;double, 3&gt; arr;
  8. std::istringstream iss (a);
  9. // iss.exceptions(std::ios::failbit); // if you want exceptions on failure
  10. if(iss &gt;&gt; arr) {
  11. std::cout &lt;&lt; &quot;success\n&quot;;
  12. } else {
  13. std::cout &lt;&lt; &quot;fail\n&quot;;
  14. }
  15. }

Demo where , is used as separator in the input.

huangapple
  • 本文由 发表于 2023年1月8日 21:52:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75048273.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定