【问题标题】:Error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char [4]' (or there is no acceptable conversion) 22错误 C2679:二进制“>>”:未找到采用“const char [4]”类型右侧操作数的运算符(或没有可接受的转换)22
【发布时间】:2015-09-27 14:31:22
【问题描述】:

首先,对不起我的英语不好。英语不是我的主要语言,我的写作能力太差了......

我已经搜索了一些关于这个问题的主题。我有一些类似的主题,但我无法获得适合我的解决方案。 [例如:error : binary '>>' : no operator found which takes a right-hand operand of type 'const char [1] And program crashes after taking first input,VS2013 C++ error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'Fraction' (or there is no acceptable conversion)]

我只是发现问题是我不能在 istream 中使用类似“+”的东西,因为它不是变量,所以我不能使用它。但我想以如下形式输入我的类值: a + bj ,所以我可以使用 fstream 将其导出到 txt 文件。现在我不知道该怎么做。

我的代码:

#include "stdafx.h"
#include "iostream"
#include "fstream"
using namespace std;

class Complex
{
     public:
     Complex( double = 0.0, double = 0.0);
     Complex(const Complex &);
     Complex(const Complex *);
     Complex operator+( const Complex & ) const;
     Complex operator-( const Complex & ) const;
     Complex operator*( const Complex & ) const;
     Complex operator/( const Complex & ) const;
     Complex operator=( const Complex & );
     friend istream &operator>>(istream & in, const Complex & Com){
         in >> Com.real >> " + " >> Com.imaginary >> "j\n"; //Error occur here
         return in;
     }
     friend ostream &operator<<(ostream & out, const Complex & Com){
         out << Com.real << " + " << Com.imaginary << "j\n"; 
         return out;
     }
     void print() const;
     private:
     double real;
     double imaginary; 
};

【问题讨论】:

  • 你想如何通过这种方法从std::istream&amp;读入Complex:friend istream &amp;operator&gt;&gt;(istream &amp; in, const Complex &amp; Com)?此方法将 immutable Complex 引用作为第二个参数。
  • 您认为in &gt;&gt; " + " 和in &gt;&gt; j\n 应该做什么?这没有任何意义。

标签: c++


【解决方案1】:

为什么要重新发明轮子?标准库已经提供了&lt;complex&gt; 和流支持。

#include <iostream>
#include <complex>

int main()
{
    std::complex<double> c;
    std::cin >> c;
    std::cout << c;
}

如果您正在寻找更复杂的序列化,请尝试类似 Boost.Spirit。

【讨论】:

  • 哦,我只是用Class练习,没必要
【解决方案2】:

&gt;&gt; 运算符没有采用字符串文字的重载(字符串文字是 char 的常量数组,例如 const char [4] 用于 3 个字符的字符串文字),因此您不能使用类似的模式匹配那个。

如果你想做模式匹配你应该read a line into a string,然后你可以使用regular expressions到match一个特定的pattern。

【讨论】:

    【解决方案3】:

    错误是因为“+”不能是来自istream的东西的目的地

    如果数据是使用cout &lt;&lt; ... &lt;&lt; " + " &lt;&lt; ... 写出的,则输入需要将“+”读入std::string,并确保它是正确的。

    【讨论】:

      【解决方案4】:

      从std::istream 格式化提取不像C 的sscanf 那样工作,因为您不能指定文字片段来“匹配”或“跳过”。您只能将数据提取到变量中并在事后对其进行验证。

      所以,std::cin &gt;&gt; " + " 和 std::cin &gt;&gt; "j\n" 完全无效。

      你可以让它工作,不过……

      #include <iostream>
      #include <cstring>
      #include <stdexcept>
      
      struct eat
      {
          explicit eat(const char* in)
              : str(in)
              , len(std::strlen(in))
          {}
      
          template <size_t N>
          explicit eat(const char (&in)[N])
              : str(in)
              , len(N)
          {}
      
      private:
      
          const char* str;
          size_t len;
          friend std::istream& operator>>(std::istream&, eat);
      };
      
      std::istream& operator>>(std::istream& is, eat e)
      {
          char c;
          for (size_t i = 0; i < e.len; i++) {
              if (!is.get(c) || c != e.str[i]) {
                  is.setstate(std::ios::failbit);
                  break;
              }
          }
      
          return is;
      }
      
      int main()
      {
          int x = 0, y = 0;
          std::cin >> x >> eat(" + ") >> y >> eat("j");
          if (!std::cin)
              throw std::runtime_error("Input was invalid!");
      
          std::cout << "Real part: " << x << "; imaginary part: " << y << '\n';
      }
      
      // Input: 3 + 4j
      // Output: Real part: 3; imaginary part: 4
      

      (live demo)

      我选择要求用户将字符串文字包装在eat() 中,这样您就不会意外使用此功能。您可以通过仅定义 template &lt;size_t N&gt; std::istream&amp; operator&gt;&gt;(std::istream&amp;, const char (&amp;str)[N]) 使其与现有代码一起工作,并让它完成相同的工作,但我不推荐它。

      【讨论】:

        【解决方案5】:

        现有的所有答案都是好的;我会添加另一种(最简单的?)方法来做同样的事情。你想象“读”和“写”应该有大致相同的实现,只改变数据流的“方向”。不幸的是,这不能在 C++ 中工作。

        但是,这将在 C 中使用,使用 printf 和 scanf:

        // Hypothetical "print" function; you don't need to use it
        void print(FILE* out, const Complex & Com){
            fprintf(out, "%f + %fj\n", com.real, com.imaginary);
        }
        

        如果你用scanf 替换printf,你会得到这样的结果:

        void read(FILE* in, Complex & Com){
            fscanf(in, "%lf + %lfj\n", &com.real, &com.imaginary);
        }
        

        但是,这样做有一些问题:

        • 这对您了解 C++ 没有任何帮助
        • 检测错误并非易事
        • 它使用FILE*,而不是istream

        可以解决第三个缺陷——使用getline 读取一行输入并使用sscanf 解析它:

        friend istream &operator>>(istream & in, const Complex & Com){
            std::string str;
            std::getline(in, str);
            sscanf(str.c_str(), "%lf + %lfj\n", &com.real, &com.imaginary);
            return in;
        }
        

        【讨论】:

          猜你喜欢
          • 2018-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-22
          • 1970-01-01
          相关资源
          最近更新 更多