错误 C2679:二进制">>":未找到采用类型为"const char [4]"的右操作数的运算符(或没有可接受的转换) 22



首先,为我糟糕的英语道歉。英语不是我的母语,我的写作能力也很差。

我搜索了一些关于这个问题的话题。我有一些类似的话题,但我不能得到我的解决方案。[示例:error: binary '>>']没有找到右操作数类型为'const char[1]的操作符,程序在第一次输入后崩溃,VS2013 c++错误C2679: binary '>>'没有找到接受'Fraction'右操作数类型的操作符。(或没有可接受的转换)]

我刚刚发现问题是我不能在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 >> "jn"; //Error occur here
         return in;
     }
     friend ostream &operator<<(ostream & out, const Complex & Com){
         out << Com.real << " + " << Com.imaginary << "jn"; 
         return out;
     }
     void print() const;
     private:
     double real;
     double imaginary; 
};

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

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

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

没有重载>>操作符,它接受字符串字面值(字符串字面值是char的常量数组,例如const char [4]为3个字符的字符串字面值),因此您不能使用这样的模式匹配。

如果你想要进行模式匹配,你应该将一行读入字符串,然后你可以使用正则表达式来匹配特定的模式。

这个错误是因为" + "不能作为istream的目标

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

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

所以,std::cin >> " + "std::cin >> "jn"是无效的。

你可以工作,但是& help;

#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

(现场演示)

我选择要求用户在eat()中包装字符串字面值,这样您就不会意外地使用此功能。您可以通过只定义一个template <size_t N> std::istream& operator>>(std::istream&, const char (&str)[N])使它与现有代码一起工作,并让它做相同的工作,但我不建议这样做。

所有现有的答案都是好的;我将添加另一种(最简单的?)方法来做同样的事情。您认为"读"one_answers"写"应该具有大致相同的实现,仅改变数据流的"方向"。不幸的是,这不能在c++中工作。

但是,这将在C中工作,使用printfscanf:

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

如果你用scanf代替printf,你会得到这样的东西:

void read(FILE* in, Complex & Com){
    fscanf(in, "%lf + %lfjn", &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 + %lfjn", &com.real, &com.imaginary);
    return in;
}

最新更新