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

Ошибка при повторном получении данных из потока cin - C++

Войти
Регистрация
Восстановить пароль
 
Gibboustooth
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 12:03     Ошибка при повторном получении данных из потока cin #1
Добрый день, уважаемые форумчане.

Делал учебную задачу и столкнулся с проблемой, которую затрудняюсь сам решить.

Задача формулируется следующим образом:
Напишите программу, считывающую ряд чисели записывающую их в ряд vector<int>. После того, как пользователь введет все числа, он может попытаться определить, сколько числе он ввел, чтобы найти их сумму.
Обработайте все входные данные. Например, убедитесь, что программа выдает сообщение об ошибке, если пользователь просит просуммировать больше чисел, чем хранится в векторе.
Я написал такое решение:

Решение
C++ (Qt)
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
61
62
#include "Lib.h"
#include <conio.h>
 
void err(string s) //Catch errors
{
    throw runtime_error(s);
}
vector<int> input()
//Get from cin into vector integer numbers
{
    vector<int> v;
    int temp;
    cout<<"Please, enter row of integers, separated with space. To exit press <|>\n";
 
    while(cin>>temp) 
        v.push_back(temp);
    return v;
}
int get_sum(vector<int> values, int num)
//Count sum of <num> first elements from vector
{
    if (num>values.size())
        err("Vector size exceeded!\n"); 
    else if(num<=0)
        err("Wrong number of elements!\n"); 
    else { 
        int sum=0;
        for(unsigned int i=0;i<num;++i)
            sum+=values[i];
        return sum;
    }
}
int main() 
{
    //Loop while user wants to continue
    do
    {
        //get vector in input values
        vector<int> v=input();
        cout<<"Please, enter number of values to sum (from the first):\n";
        //get number of values 
        int num_sum=0;
        /*ERROR here. Seems like <cin> still contains something, 
        previous function didn't get, so it doesn't let new input*/
        cin>>num_sum;
        try {
            int sum=get_sum(v,num_sum);
            cout<<"Sum of "<<num_sum<<" elements is: "<<sum;
        }
        catch (runtime_error& e) {
            cerr<<"error: "<<e.what()<<endl;
        }
        catch(...) {
            cerr<<"Oups, unknown exception!\n";
        }
        //Prompt to continue
        cout<<"Press Y - for new input\n";
    }
    while(toupper(getch()) == 'Y');
    system("pause");
    return 0;
}


Но строчка функции main() "cin>>num_sum;" отрабатывает не так, как мне бы хотелось - судя по всему , в потоке cin остаются необработанные символы, так что у пользователя не запрашивается новый ввод и в переменную num_sum передается ерунда.

Подскажите, пожалуйста, как можно от этого избавиться?

P.S. Если необходимо содержимое "Lib.h", могу его скинуть.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.08.2012, 12:03     Ошибка при повторном получении данных из потока cin
Посмотрите здесь:

C++ Возобновление потока cin.
Ошибка при работе с cin и cout C++
Защита от дурака при вводе текста с помощью: cin.get cin.clear cin.sync C++
C++ Ошибка при получении vector.size()
C++ Пробел при вводе данных c применением cin
Работа с cin при считывании с потока ввода C++
Ошибка при повторном запуске: terminate called after throwing an instance of 'std::ios_base::failure' C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
27.08.2012, 12:16     Ошибка при повторном получении данных из потока cin #2
При вводе 'Y' Вы нажимаете Enter?
Gibboustooth
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 12:22  [ТС]     Ошибка при повторном получении данных из потока cin #3
Нет. Но проблема не в этом - ошибка возникает раньше предложения ввести "Y".

Собственно, программа отрабатывает следующим образом:
Код
Please, enter row of integers, separated with space. To exit press <|>
1 2 3|
Please, enter number of values to sum (from the first):
error: Wrong number of elements!

Press Y - for new input
Т.е. он выдает мне предложение ввести сумму и сразу получает значение, не передавая обратно ввод.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
27.08.2012, 12:50     Ошибка при повторном получении данных из потока cin #4
Цитата Сообщение от Gibboustooth Посмотреть сообщение
while(cin>>temp)
* * * * v.push_back(temp);
Устанавливается флаг конца файла. Нужно сбрасывать флаг или сделать просто контрольное значение.

Добавлено через 10 минут
C++
1
2
3
4
5
6
    while(cin>>temp) 
        v.push_back(temp);
    
    cin.clear();
 
    return v;
Gibboustooth
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 13:37  [ТС]     Ошибка при повторном получении данных из потока cin #5
Переписал функцию input:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
vector<int> input()
//Get from cin into vector integer numbers
{
    vector<int> v;
    int temp;
    char c=' ';
    cout<<"Please, enter row of integers, separated with space. To exit press <|>\n";
 
    while(cin&&c!='|') 
    {
        cin>>c;
        if (c!='|') {
            cin.putback(c);
            cin>>temp;
            v.push_back(temp);
        }
    }
    if (cin.eof())
        err("Wrong input!");
    else
        return v;
}
Вроде работает

Спасибо за помощь.

cin.clear(); кстати говоря, не помогал. Не знаю почему.

Добавлено через 37 минут
P.S. Работает, но неправильно. Я, видимо, не вполне понимаю, как работает cin.
На строку "1а2 3" он не становится cin.eof. Зато проверка if (c!='|') работает нормально.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
27.08.2012, 13:43     Ошибка при повторном получении данных из потока cin #6
Правильно, потому что в данном случае устанавливается флаг badbit или failbit.
Gibboustooth
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 13:52  [ТС]     Ошибка при повторном получении данных из потока cin #7
If (cin.fail()) {}
работает нормально. Но я не понимаю, как его потом "оживить", чтобы он дальше принимал значения. cin.clear(); не работает
panicwassano
591 / 559 / 20
Регистрация: 07.11.2010
Сообщений: 2,004
27.08.2012, 14:23     Ошибка при повторном получении данных из потока cin #8
cin.sync() ?
Gibboustooth
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 14:56  [ТС]     Ошибка при повторном получении данных из потока cin #9
А, все. cin.clear() работает. Я тупой просто.

Всем спасибо за помощь.
-=ЮрА=-
Заблокирован
Автор FAQ
27.08.2012, 16:54     Ошибка при повторном получении данных из потока cin #10
Gibboustooth, вот и всё решение
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
#include <vector>
#include <iostream>
using namespace std;
 
//ÔóГ*êöèÿ âîçâðГ*Г№Г*ГҐГІ ÷èñëî ýëåìåГ*òîâ Гў âåêòîðå
int num(vector<int> vec)
{
    return vec.size();
}
 
int sum(vector<int> vec, int nElems)
{
    int Sum = 0;
    for(int i = 0; i < nElems; i++)
        Sum += vec.at(i);
    return Sum;
}
 
int main()
{
    int value;
    vector<int> vec;
    cout<<"Initialize of vector :\n";
    while(cin>>value)
        vec.push_back(value);
    //ГЌГ*äî î÷èñòèòü ïîòîê ââîäГ*
    cin.clear();
    cin.sync();
    int count;
    while(true)
    {
        cout<<"Enter number of elements to summ : ";cin>>count;
        if(count < num(vec))
            cout<<"Sum of "<<count<<" elements : "<<sum(vec, count)<<endl;
        else
            cout<<"Vector contain less elements that "<<count<<endl;
    }
    return 0;
}
Миниатюры
Ошибка при повторном получении данных из потока cin  
Gibboustooth
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 17:40  [ТС]     Ошибка при повторном получении данных из потока cin #11
Спасибо. Я просто изучаю вызовы функций и обработку ошибок (Try {}, Throw(), Catch () {} и т.д.) вот и пихаю их куда не попадя

А зачем функция num()? Можно же использовать vec.size() прямо в main()?
-=ЮрА=-
27.08.2012, 17:45
  #12

Не по теме:

Цитата Сообщение от Gibboustooth Посмотреть сообщение
А зачем функция num()? Можно же использовать vec.size() прямо в main()?
- да конечно можно если пишем что то простое, а если вектор это приват поле некого класса ?Просто я привык всё делать сразу методами...

Toshkarik
 Аватар для Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
27.08.2012, 17:46     Ошибка при повторном получении данных из потока cin #13
size и есть метод.
-=ЮрА=-
Заблокирован
Автор FAQ
27.08.2012, 17:49     Ошибка при повторном получении данных из потока cin #14

Не по теме:

Цитата Сообщение от Gibboustooth Посмотреть сообщение
Я просто изучаю вызовы функций и обработку ошибок (Try {}, Throw(), Catch () {} и т.д.)
- не надо перенасыщать код этим всем, оно путает читающего листинг. Надо вставлять там где это необходимо, ИМХО лучше баги не фиксить в готовом коде а устранять на этапе разработки.



Добавлено через 2 минуты
Toshkarik, я порой поражаюсь твоей прямолинейности
C++
1
2
3
4
5
6
7
8
class MyVec
{
private:
   vector<int> vec;
public:
      MyVec(){}
      int num(){return vec.size();}
};
я об этом писал
Toshkarik
27.08.2012, 17:59
  #15

Не по теме:

И я про то же. Нет в этом смысла никакого.
Если уж нужен размер вектора, то можно возвращать сам объект по константной ссылке, и через него уже ссылаться на size(). Да и это сомнительно. Правда к теме это никак не относится, просто я про то, что не вижу смысла в таком коде.

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.08.2012, 20:10     Ошибка при повторном получении данных из потока cin
Еще ссылки по теме:

C++ Кодировка при получении данных из сети
При вводе данных программа пропускает операции cin C++
C++ Детали относительно входного потока cin
C++ Обработка ошибок ввода из потока cin
Ошибка при перегрузке оператора cin >> C++

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

Или воспользуйтесь поиском по форуму:
-=ЮрА=-
27.08.2012, 20:10     Ошибка при повторном получении данных из потока cin
  #16

Не по теме:

Toshkarik, ну не видишь не видь,дело твое личное...

Yandex
Объявления
27.08.2012, 20:10     Ошибка при повторном получении данных из потока cin
Ответ Создать тему
Опции темы

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