Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
1

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

27.08.2012, 12:03. Просмотров 1537. Ответов 15
Метки нет (Все метки)

Добрый день, уважаемые форумчане.

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

Задача формулируется следующим образом:
Напишите программу, считывающую ряд чисели записывающую их в ряд 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", могу его скинуть.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.08.2012, 12:03
Ответы с готовыми решениями:

Ошибка при повторном запуске потока
Занялся изучением работы потоков и написал следующий код (точнее взял с этого форума кусок работы с...

TidHTTP ошибка при получении данных
Здравствуйте. Rad Studio XE6. Написал парсер используя класс TidHTTP. Парсер постоянно работает....

Ошибка при получении данных из $_POST
Пытаюсь получить отправленные данные от ajax-запроса. if (isset($_POST)) { $abc = $_POST;...

Ошибка при получении данных из БД при использовании MVC framework 4.0
// HomeControlers.cs using System; using System.Collections.Generic; using System.Linq; using...

15
1170 / 883 / 94
Регистрация: 03.08.2011
Сообщений: 2,453
27.08.2012, 12:16 2
При вводе 'Y' Вы нажимаете Enter?
0
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 12:22  [ТС] 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
Т.е. он выдает мне предложение ввести сумму и сразу получает значение, не передавая обратно ввод.
0
1170 / 883 / 94
Регистрация: 03.08.2011
Сообщений: 2,453
27.08.2012, 12:50 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;
1
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 13:37  [ТС] 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!='|') работает нормально.
0
1170 / 883 / 94
Регистрация: 03.08.2011
Сообщений: 2,453
27.08.2012, 13:43 6
Правильно, потому что в данном случае устанавливается флаг badbit или failbit.
1
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 13:52  [ТС] 7
If (cin.fail()) {}
работает нормально. Но я не понимаю, как его потом "оживить", чтобы он дальше принимал значения. cin.clear(); не работает
0
595 / 563 / 104
Регистрация: 07.11.2010
Сообщений: 2,004
27.08.2012, 14:23 8
cin.sync() ?
0
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 14:56  [ТС] 9
А, все. cin.clear() работает. Я тупой просто.

Всем спасибо за помощь.
0
Заблокирован
Автор FAQ
27.08.2012, 16:54 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;
}
1
Миниатюры
Ошибка при повторном получении данных из потока cin  
733 / 201 / 11
Регистрация: 23.06.2011
Сообщений: 440
27.08.2012, 17:40  [ТС] 11
Спасибо. Я просто изучаю вызовы функций и обработку ошибок (Try {}, Throw(), Catch () {} и т.д.) вот и пихаю их куда не попадя

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

Не по теме:

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

0
1170 / 883 / 94
Регистрация: 03.08.2011
Сообщений: 2,453
27.08.2012, 17:46 13
size и есть метод.
0
Заблокирован
Автор FAQ
27.08.2012, 17:49 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();}
};
я об этом писал
0
Toshkarik
27.08.2012, 17:59
  #15

Не по теме:

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

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

Не по теме:

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

0
27.08.2012, 20:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.08.2012, 20:10
Привет! Вот еще темы с ответами:

Перезапуск таймера при повторном запуске потока
#include &lt;condition_variable&gt; #include &lt;iostream&gt; #include &lt;random&gt; #include &lt;thread&gt; #include...

При повторном открытии потока ofstream выводятся иероглифы
Всем привет! Прошу помощи. Есть код: #include &lt;Windows.h&gt; #include &lt;iostream&gt; #include...

Работа с cin при считывании с потока ввода
есть кусочек кода while (1) { string buf = name; cout &lt;&lt; &quot;Message : &quot;; string...

Защита от дурака при вводе текста с помощью: cin.get cin.clear cin.sync
Доброго времени суток. На С++ учусь с недавних пор. Имеется стандартная &quot;защита от дурака&quot; на ввод....


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

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