Ошибка C2679: двоичный файл «& gt; & gt;» : не найден оператор, который принимает правый операнд типа ‘const char [4]’ (или нет приемлемого преобразования) 22

Во-первых, извините за мой плохой английский. Английский не мой основной язык, и мои навыки письма настолько ужасны …

Я искал тему об этой проблеме. У меня похожая тема, но я не могу найти решение для своей. [Пример: ошибка: двоичная>>’: не найден оператор, который принимает правый операнд типа’ const char [1] и программа падает после первого ввода , VS2013 C ++ ошибка C2679: двоичный файл ‘>>’: не найден оператор, который принимает правый операнд типа’ Fraction ‘(или нет приемлемого преобразования) ]

Я просто понимаю, что проблема в том, что я не могу использовать что-то вроде: «+» в istream, потому что это не переменная, поэтому я не могу ее использовать. Но я хочу ввести значение моего класса в виде: a + bj, чтобы я мог экспортировать его в текстовый файл с помощью fstream. Теперь я не знаю, как это сделать.

Мой код:

#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;
};

0

Решение

Зачем изобретать велосипед? Стандартная библиотека уже предоставляет <complex> и потоковая поддержка.

#include <iostream>
#include <complex>

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

Если вы ищете более сложную сериализацию, попробуйте что-то вроде Boost.Spirit.

0

Другие решения

Там нет перегрузки >> оператор, который принимает строковые литералы (строковые литералы являются константными массивами charнапример, const char [4] для строкового литерала из 3 символов), следовательно, вы не можете использовать сопоставление с шаблоном таким образом

Если вы хотите сделать сопоставление с шаблоном, вы должны читать строку в строку, тогда вы можете использовать регулярные выражения в матч особый шаблон.

0

Ошибка в том, что «+» не может быть пунктом назначения для istream

Если данные были записаны с использованием cout << ... << " + " << ...вход должен будет прочитать «+» в std::stringи убедитесь, что это было правильно.

0

Отформатированное извлечение из std::istream не работает как С sscanfв том, что вы не можете указать буквальные фрагменты текста, чтобы «соответствовать» или «пропустить». Вы можете только извлечь данные в переменные и подтвердите это после факта.

Так, std::cin >> " + " а также std::cin >> "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

(живое демо)

Я решил потребовать от пользователей переносить строковые литералы в eat(), так что вы не можете использовать эту функцию случайно. Вы можете заставить его работать с вашим существующим кодом, определяя только template <size_t N> std::istream& operator>>(std::istream&, const char (&str)[N])И пусть он делает ту же работу, но я бы не рекомендовал это.

0

Все существующие ответы хороши; Я добавлю другой (самый простой?) способ сделать то же самое. Вы представляете, что «чтение» и «запись» должны иметь примерно одинаковую реализацию, изменяя только «направление» потока данных. К сожалению, это не может работать в 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);
}

Если вы замените printf с scanf, вы получите что-то вроде этого:

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;
}
0
По вопросам рекламы [email protected]