Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
#1

Перегрузка >> - C++

25.06.2013, 01:26. Просмотров 558. Ответов 16
Метки нет (Все метки)

Доброго времени суток. Есть учебный пример перегрузки операций >> и <<.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "stdafx.h"
#include <iostream>
using namespace std;
 
class PhoneNumber
{
public:
    friend ostream &operator << (ostream &, const PhoneNumber &);
    friend istream &operator >> (istream &, PhoneNumber &);
    void printPhone();
 
private:
    char areaCode[4];
    char exchange[4];
    char line[5];
};
 
void PhoneNumber::printPhone()
{
    cout << areaCode << endl;
    cout << exchange << endl;
    cout << line << endl;
}
 
ostream &operator << (ostream &output, const PhoneNumber &num)
{
    output << "(" << num.areaCode << ") "
           << num.exchange << "-" << num.line;
    return output;
}
 
istream &operator >> (istream &input, PhoneNumber &num)
{
    input.ignore();
    input.getline(num.areaCode, 4);
    input.ignore(2);
    input.getline(num.exchange, 4);
    input.ignore();
    input.getline(num.line, 5);
 
    return input;
 
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
    PhoneNumber phone;
 
    cout << "Введите номер телефона в "
         << "виде (123) 456-7890: " << endl;
 
    cin >> phone;
    cout << "Был введен номер телефона: " << endl
         << phone << endl;
 
    phone.printPhone();
    system("pause");
    return 0;
}
Проблема в следующем. Если я ввожу номер телефона одной строкой, то срабатывает только
C++
1
2
input.ignore();
    input.getline(num.areaCode, 4);
, а
C++
1
2
3
4
input.ignore(2);
    input.getline(num.exchange, 4);
    input.ignore();
    input.getline(num.line, 5);
просто пропускает.
Нормально работает, если я ввожу так:
(123
) 456
-7890

Объясните плз, в чем загвоздка?

Добавлено через 17 минут
Получилось исправить вот таким вот образом
C++
1
2
3
4
5
6
7
8
9
10
11
12
istream &operator >> (istream &input, PhoneNumber &num)
{
    input.ignore();
    input.getline(num.areaCode, 4, ')');
    input.ignore();
    input.getline(num.exchange, 4, '-');
    //input.ignore();
    input.getline(num.line, 5);
 
    return input;
 
}
Но все же мне не понятно, почему не сработал 1-й вариант. Может кто объяснить пошагово, что там происходило при вводе одной строкой:
(123) 456-7890
?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.06.2013, 01:26     Перегрузка >>
Посмотрите здесь:

Перегрузка * - C++
Есть такой класс: class CMatrix{ valarray&lt;valarray&lt;double&gt; &gt; matrix; public: CMatrix operator* (const CMatrix &amp;M); }; ...

перегрузка [] - C++
Как перегрузить operator так, чтобы когда я модифицировал массив то вызывалась простая версия, а когда просто выводил то const версия? ...

Перегрузка + - C++
#include &lt;iostream&gt; using namespace std; class loc { int n , m; public: loc() {} loc( int lg , lt) { n = lg; m =...

перегрузка [] - C++
Здравствуйте! код из учебного пособия. (возможно немного не рабочий) текст перед кодом- &quot;Пусть класс определен как строка символов....

Перегрузка в c++ - C++
Зачем нужно использовать перегрузку в c++? Этот вопрос будет у меня на экзамене, поэтому хочу услышать ваши версии

Перегрузка ++ и -- - C++
У меня было задание: Напишите программу работы со временем, в которой используются перегруженные операции ++ и --, которые работают в...

Перегрузка - C++
Дали задачу, на перегрузку строк вот один из операторов который надо перегрузить. stringg&amp; operator+=( stringg a) { char...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ksandro
31 / 31 / 1
Регистрация: 15.04.2011
Сообщений: 81
25.06.2013, 01:35     Перегрузка >> #2
потому что метод istream::getline() выставляет failbit если не нашел перехода не новую строку через 4 символа. Дальше соответственно ничего не читается
http://www.cplusplus.com/reference/i...tream/getline/
xtorne21st
интересующийся
303 / 274 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
25.06.2013, 01:36     Перегрузка >> #3
@Мимино, Вдумайтесь, пожалуйста, в название метода getline: "получить строку". У вас в операторе >> getline вызывается 3 раза соответственно должно быть 3 строки. Так как getline по умолчанию ищет символ '\n' для завершения и вашем случаи он находит его только один раз, так как вводиться всего лишь одна строка.
ksandro
31 / 31 / 1
Регистрация: 15.04.2011
Сообщений: 81
25.06.2013, 01:37     Перегрузка >> #4
The failbit flag is set if the function extracts no characters, or if the delimiting character is not found once (n-1) characters have already been written to s. Note that if the character that follows those (n-1) characters in the input sequence is precisely the delimiting character, it is also extracted and the failbit flag is not set (the extracted sequence was exactly n characters long).

http://www.cplusplus.com/reference/i...tream/getline/
xtorne21st
интересующийся
303 / 274 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
25.06.2013, 01:40     Перегрузка >> #5
Более по научному выразился выше ksandro
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
25.06.2013, 01:43  [ТС]     Перегрузка >> #6
Цитата Сообщение от ksandro Посмотреть сообщение
потому что метод istream::getline() выставляет failbit если не нашел перехода не новую строку через 4 символа. Дальше соответственно ничего не читается
http://www.cplusplus.com/reference/i...tream/getline/
Да, но разве failbit распространяется на последующие вызовы istream::getline()?
xtorne21st
интересующийся
303 / 274 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
25.06.2013, 01:46     Перегрузка >> #7
Можно, конечно, каждый раз восстанавливать поток в рабочее состояние:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
istream &operator >> (istream &input, PhoneNumber &num)
{
    input.ignore();
    input.getline(num.areaCode, 4);
    std::cout << num.areaCode << std::endl;
    input.clear();
    input.ignore();
    input.ignore();
    input.getline(num.exchange, 4);
    std::cout << num.exchange << std::endl;
    input.clear();
    input.ignore();
    input.getline(num.line, 5);
    std::cout << num.line << std::endl;
 
    return input;
}
Но правильней, наверное, просто парсировать строку.

Добавлено через 1 минуту
@Мимино, конечно, поток находиться в ошибочном состоянии и чтоб его вернуть нужно вручную менять флаг либо вызвать метод clear()
ksandro
31 / 31 / 1
Регистрация: 15.04.2011
Сообщений: 81
25.06.2013, 01:49     Перегрузка >> #8
Цитата Сообщение от Мимино Посмотреть сообщение
Да, но разве failbit распространяется на последующие вызовы istream::getline()?
да, failbit распространяется объект istream, и он будет выставлен пока объект живой, или пока его вручную не поменяют.

тут можно почитать: http://www.cplusplus.com/reference/i..._base/iostate/
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
25.06.2013, 01:56  [ТС]     Перегрузка >> #9
Цитата Сообщение от xtorne21st Посмотреть сообщение
@Мимино, конечно, поток находиться в ошибочном состоянии и чтоб его вернуть нужно вручную менять флаг либо вызвать метод clear()
Не понятно только одно :
failbit The last input operation failed because of an error related to the internal logic of the operation itself.
Цитата Сообщение от xtorne21st Посмотреть сообщение
Но правильней, наверное, просто парсировать строку.
Да, до этого я вроде как додумался.

_________
Все, увидел. Дошло, разобрался Спасибо всем.
ksandro
31 / 31 / 1
Регистрация: 15.04.2011
Сообщений: 81
25.06.2013, 02:04     Перегрузка >> #10
ну, вообщем-то там написано, что последняя операция ввода вызвала ошибку. После этой ошибки, больше операций ввода не будет, несмотря на то что getline ты вызываешь. То есть это имеется ввиду не последний вызов функции а последнее реальное чтение из потока.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.06.2013, 02:09     Перегрузка >> #11
Цитата Сообщение от Мимино Посмотреть сообщение
Нормально работает, если я ввожу так:
(123
) 456
-7890
Непонятно только, как это у вас нормально работало, если первая getline() позволяет ввести не более 3-х символов, а вы вводили 4.
ksandro
31 / 31 / 1
Регистрация: 15.04.2011
Сообщений: 81
25.06.2013, 02:23     Перегрузка >> #12
Цитата Сообщение от alsav22 Посмотреть сообщение
Непонятно только, как это у вас нормально работало, если первая getline() позволяет ввести не более 3-х символов, а вы вводили 4.
он сначала вызывал ignore которая читала и отбрасывала первый символ "("
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.06.2013, 02:29     Перегрузка >> #13
Понял.
Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
25.06.2013, 10:28     Перегрузка >> #14
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
istream &operator >> (istream &input, PhoneNumber &num)
{
    input.ignore( numeric_limits<streamsize>::max(), '(' );
    input.get(num.areaCode, 4, ')');
 
    input.ignore( numeric_limits<streamsize>::max(), ' ' );
    input.get(num.exchange, 4, '-');
 
    input.ignore( numeric_limits<streamsize>::max(), '-' );
    input.get(num.line, 5);
 
    return input;
}
Миниатюры
Перегрузка >>   Перегрузка >>  
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
25.06.2013, 10:49  [ТС]     Перегрузка >> #15
@Olivеr,
спасибо конечно, но это к чему?
Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
25.06.2013, 11:00     Перегрузка >> #16
@Мимино, так у вас проблемы с вводом были.

Добавлено через 46 секунд
UPD: не заметил в первом посте решение
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.06.2013, 11:08     Перегрузка >>
Еще ссылки по теме:

Перегрузка - C++
Класс - множество set. Дополнительно перегрузить следующие операции: -- удалить элемент из множества (типа set-item); * - пересечение...

Перегрузка [][] - C++
Возможно ли для данного класса обеспечить перегрузку жвойных скобок с тем, чтобы в программе можно было использовать выражения типа: ...

Перегрузка - C++
Написать программу на языке C++, реализующию перегруженную функцию z_cnt, получа- ющую в качестве аргумента или массив целых чисел, или...

перегрузка [] - C++
доброго времени суток.. суть задачи такова: есть класс матриц, матрица хранится в виде одномерного массива.. я перегрузил &lt;&lt; и += ...

Перегрузка new - C++
Дайте примеры на перегрузку. #define n ... // Некая целая константа class a { ... }; // Некий класс a *p=new a; // Здесь должен быть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Мимино
180 / 151 / 5
Регистрация: 22.05.2013
Сообщений: 435
Записей в блоге: 1
25.06.2013, 11:08  [ТС]     Перегрузка >> #17
Цитата Сообщение от Olivеr Посмотреть сообщение
@Мимино, так у вас проблемы с вводом были.
Не с вводом, а с пониманием Но все-равно спасибо.
Yandex
Объявления
25.06.2013, 11:08     Перегрузка >>
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru