Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
#1

Чтение символов из cin в буфер в цикле - C++

22.06.2013, 22:43. Просмотров 1181. Ответов 13
Метки нет (Все метки)

Привет!
Нужно считать строки из консоли, но что-то идёт не так.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    while (true) {
 
        Strings.push_back(yury::BasicString());
        std::cout << std::endl << "Vvedite stroku: ";
        std::cin >> Strings.back();
 
        std::cout << "Prodolgim napolnyat spisok strok (y - da, n - net)? ";
        lNext = std::cin.get();
 
        if (lNext != 'y') {
            break;
        }
 
    }
C++
1
2
3
4
5
6
7
8
9
    const int sizeBuf = 256;
    yury::T lBuf[sizeBuf];
 
    do {
        stream.getline(lBuf, sizeBuf);
        string += lBuf;
    } while (stream.gcount() == sizeBuf);
 
    return stream;
Добавлено через 3 минуты
При первом проходе всё нормально, но при втором проходе программа почему-то не ждёт ввода символов в строке №6 (второй кусок), а сразу записывает в string '\0'. Не подскажите как сделать, чтобы всегда в строке №6 программа ждала ввода символов из консоли?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.06.2013, 22:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Чтение символов из cin в буфер в цикле (C++):

Как проверить на пустоту буфер потока cin ? - C++
Мне нужно ввести строку такого типа: &quot;поиск 1 2 3&quot; cin&gt;&gt;sts.code; j = 0; while( ???вот тут что то !буфер.empty()) { ...

Игнорирует cin в цикле. - C++
Здравствуйте, уважаемые. Прошу помочь. Не могу понять почему в приведенном ниже коде при втором и последующем прохождении цмкла...

Объяснить поведение объекта std::cin в цикле while - C++
#include&lt;iostream&gt; #include&lt;string&gt; #include&lt;cstdlib&gt; #include&lt;windows.h&gt; using namespace std; int main(){ char i; char...

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

Объясните пожалуйста как работают cin.good(), cin.sync(), cin.clear() - C++
Такая проблема: сдаю в вуза лабораторные по программированию, писал все сам, до этого c++ не изучал, поэтому возникали некоторые проблемы....

cin чтение из файла C++ - C++
Здравствуйте,который день ищу не могу понять как читать из файла с помошью cin Допустим есть 2 файла input.txt и output.txt.В файле...

13
m1Rr0r
247 / 230 / 15
Регистрация: 05.02.2010
Сообщений: 3,262
Завершенные тесты: 2
22.06.2013, 22:43 #2
C++
1
2
cin.clear();
cin.sync();
1
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
22.06.2013, 22:48  [ТС] #3
Цитата Сообщение от m1Rr0r Посмотреть сообщение
cin.clear();
Такого метода нету. Только sync();
0
m1Rr0r
247 / 230 / 15
Регистрация: 05.02.2010
Сообщений: 3,262
Завершенные тесты: 2
22.06.2013, 23:02 #4
Юрий Ч, После первого ввода в потоке остается "ентер", вот его то и нужно изгнать оттуда.
0
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
23.06.2013, 09:32  [ТС] #5
Сделал так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    const int sizeBuf = 3;
    yury::T lBuf[sizeBuf];
 
    stream.clear();
    stream.sync();
 
    do {
        stream.getline(lBuf, sizeBuf);
        string += lBuf;
    } while (stream.gcount() == (sizeBuf - 1));
 
 
    stream.clear();
    stream.sync();
 
    return stream;
Теперь читает только два символа из потока, остальные нет. Как грамотно считать, подскажите.

Добавлено через 22 минуты
@m1Rr0r, в литературе написано, что getline извлекает символ новой строки и не помещает его в буфер. Наверное, символов не один, а два, а имено "\r\n".

Добавлено через 9 часов 34 минуты
Пока черновой вариант обнаружения конца строки и выхода из цикла чтения такой:

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
    const int sizeBuf = 3;
    yury::T lBuf[sizeBuf];
 
    int lI = 0;
    char lCh;
 
    stream.clear();
    stream.sync();
 
    while (true) {
 
        stream.get(lCh);
 
        if (lCh != '\n') {
            lBuf[lI] = lCh;
        }
        else {
            lBuf[lI + 1] = '\0';
            string += lBuf;
            break;
        }
 
        ++lI;
 
        if (lI == (sizeBuf - 1)) {
            lBuf[lI] = '\0';
            string += lBuf;
            lI = 0;
        }
 
    }
 
    return stream;
Но что-то говорит мне, что вариант не совсем гибок и зависит от ОС.
0
alsav22
5429 / 4824 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.06.2013, 10:26 #6
Цитата Сообщение от Юрий Ч Посмотреть сообщение
@m1Rr0r, в литературе написано, что getline извлекает символ новой строки и не помещает его в буфер. Наверное, символов не один, а два, а имено "\r\n".
getline() извлекает, зато cin >> не извлекает, от этого потом проблемы с getline(). Там где есть cin >> , сделайте так:
C++
1
(cin >> n).get();
Добавлено через 1 минуту
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Как грамотно считать, подскажите.
Код весь покажите.
0
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
23.06.2013, 11:09  [ТС] #7
@alsav22, весь код (почти):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    while (true) {
 
        // Создаём строку, помещаем её в список строк и
        // наполняем из стандартного входного потока.
 
        Strings.push_back(yury::BasicString());
        std::cout << std::endl << "Vvedite stroku: ";
        std::cin >> Strings.back();
 
        // Спрашиваем у пользователя продолжать строить список или
        // достаточно.
 
        std::cout << "Prodolgim napolnyat spisok strok (y - da, n - net)? ";
        std::cin.get(lNext);
 
        if (lNext != 'y') {
            break;
        }
 
    }
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
std::basic_istream<yury::T, std::char_traits<yury::T> >& yury::operator >> (std::basic_istream<yury::T, std::char_traits<yury::T> > &stream, yury::BasicString &string)
{
 
    const int sizeBuf = 256;
    yury::T lBuf[sizeBuf];
 
    int lI = 0;
    char lCh;
 
    stream.clear();
    stream.sync();
 
    while (true) {
 
        stream.get(lCh);
 
        if (lCh != '\n') {
            lBuf[lI] = lCh;
        }
        else {
            lBuf[lI] = '\0';
            string += lBuf;
            break;
        }
 
        ++lI;
 
        if (lI == (sizeBuf - 1)) {
            lBuf[lI] = '\0';
            string += lBuf;
            lI = 0;
        }
 
    }
 
    return stream;
 
}
0
alsav22
5429 / 4824 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.06.2013, 11:22 #8
Уберите из него то, что добавили, после первого поста (stream.clear(); stream.sync(); и пр.) и покажите. И потом: разве это весь код?

Добавлено через 8 минут
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Теперь читает только два символа из потока, остальные нет. Как грамотно считать, подскажите.
А сколько нужно?
0
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
23.06.2013, 11:26  [ТС] #9
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
int _tmain(int argc, _TCHAR* argv[])
{
 
    std::cout << "Seychas budem napolnyat spisok strokami." << std::endl;
    yury::T lNext;
 
    // Создаём список строк.
 
    std::list<yury::BasicString> Strings;
 
    // Наполняем список строк.
 
    while (true) {
 
        // Создаём строку, помещаем её в список строк и
        // наполняем из стандартного входного потока.
 
        Strings.push_back(yury::BasicString());
        std::cout << std::endl << "Vvedite stroku: ";
        std::cin >> Strings.back();
 
        // Спрашиваем у пользователя продолжать строить список или
        // достаточно.
 
        std::cout << "Prodolgim napolnyat spisok strok (y - da, n - net)? ";
        std::cin.get(lNext);
 
        if (lNext != 'y') {
            break;
        }
 
    }
 
    // Сортируем строки в списке строк в лексикографическом порядке.
 
    Strings.sort();
 
    // Отображаем строки в порядке обратном лексикографическому, используя реверсивный итератор.
 
    std::cout << "Stroki v obratnom leksikograficheskom poryadke:" << std::endl << std::endl;
    std::list<yury::BasicString>::reverse_iterator lRit = Strings.rbegin();
    while (lRit != Strings.rend()) {
        std::cout << *(lRit++) << std::endl;
    }
 
    // Ждём команды пользователя на выход из программы.
 
    std::cout << std::endl << "Dlya vychoda nagmite klavishi 'e' i 'Enter' ";
    std::cin >> lNext;
 
    return 0;
 
}
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
std::basic_istream<yury::T, std::char_traits<yury::T> >& yury::operator >> (std::basic_istream<yury::T, std::char_traits<yury::T> > &stream, yury::BasicString &string)
{
 
    const int sizeBuf = 256;
    yury::T lBuf[sizeBuf];
 
    int lI = 0;
    char lCh;
 
    stream.clear();
    stream.sync();
 
    while (true) {
 
        stream.get(lCh);
 
        if (lCh != '\n') {
            lBuf[lI] = lCh;
        }
        else {
            lBuf[lI] = '\0';
            string += lBuf;
            break;
        }
 
        ++lI;
 
        if (lI == (sizeBuf - 1)) {
            lBuf[lI] = '\0';
            string += lBuf;
            lI = 0;
        }
 
    }
 
    return stream;
 
}
Пока не понял что убрать, что добавить. Привёл весь код.
0
alsav22
5429 / 4824 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.06.2013, 11:45 #10
Цитата Сообщение от Юрий Ч Посмотреть сообщение
Привёл весь код.
Если это весь код, то тогда, что такое yury?
0
Юрий Ч
5 / 5 / 0
Регистрация: 16.05.2012
Сообщений: 149
23.06.2013, 11:47  [ТС] #11
@alsav22, yury - пространство имён, T - синоним char.
0
alsav22
5429 / 4824 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.06.2013, 11:56 #12
У вас вот здесь, что должно делаться? Чтение в string с консоли?
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
std::basic_istream<yury::T, std::char_traits<yury::T> >& yury::operator >> (std::basic_istream<yury::T, std::char_traits<yury::T> > &stream, yury::BasicString &string)
{
 
    const int sizeBuf = 256;
    yury::T lBuf[sizeBuf];
 
    int lI = 0;
    char lCh;
 
    stream.clear();
    stream.sync();
 
    while (true) {
 
        stream.get(lCh);
 
        if (lCh != '\n') 
        {
            lBuf[lI] = lCh;
        }
        else 
        {
            lBuf[lI] = '\0';
            string += lBuf;
            break;
        }
 
        ++lI;
 
        if (lI == (sizeBuf - 1)) 
        {
            lBuf[lI] = '\0';
            string += lBuf;
            lI = 0;
        }
 
    }
 
    return stream;
}
Добавлено через 2 минуты
Вот так попробуйте:
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
61
62
std::basic_istream<yury::T, std::char_traits<yury::T> >& yury::operator >> (std::basic_istream<yury::T, std::char_traits<yury::T> > &stream, yury::BasicString &string)
{
 
    getline(stream, string);
 
    return stream;
}
 
int main()
{
 
    std::cout << "Seychas budem napolnyat spisok strokami." << std::endl;
    yury::T lNext;
 
    // Создаём список строк.
 
    std::list<yury::BasicString> Strings;
 
    // Наполняем список строк.
 
    while (true) {
 
        // Создаём строку, помещаем её в список строк и
        // наполняем из стандартного входного потока.
 
        Strings.push_back(yury::BasicString());
        std::cout << std::endl << "Vvedite stroku: ";
        std::cin >> Strings.back();
 
        // Спрашиваем у пользователя продолжать строить список или
        // достаточно.
 
        std::cout << "Prodolgim napolnyat spisok strok (y - da, n - net)? ";
        (std::cin.get(lNext)).get();
        
 
        if (lNext != 'y') {
            break;
        }
 
    }
 
    // Сортируем строки в списке строк в лексикографическом порядке.
 
    Strings.sort();
 
    // Отображаем строки в порядке обратном лексикографическому, используя реверсивный итератор.
 
    std::cout << "Stroki v obratnom leksikograficheskom poryadke:" << std::endl << std::endl;
    std::list<yury::BasicString>::reverse_iterator lRit = Strings.rbegin();
    while (lRit != Strings.rend()) {
        std::cout << *(lRit++) << std::endl;
    }
 
    // Ждём команды пользователя на выход из программы.
 
    std::cout << std::endl << "Dlya vychoda nagmite klavishi 'e' i 'Enter' ";
    std::cin >> lNext;
 
    return 0;
 
}
0
alsav22
5429 / 4824 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.06.2013, 12:38 #13
Убрал пространство имён для проверки работы. Вот так работает:
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
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <cstdlib>
 
typedef char T;
typedef std::string BasicString;
 
std::basic_istream<T, std::char_traits<T> >& operator >> (std::basic_istream<T, std::char_traits<T> > &stream, BasicString &string)
{
 
    std::getline(stream, string);
 
    return stream;
}
 
int main()
{
 
    std::cout << "Seychas budem napolnyat spisok strokami." << std::endl;
   T lNext;
 
    // Создаём список строк.
 
    std::list<BasicString> Strings;
 
    // Наполняем список строк.
 
    while (true) {
 
        // Создаём строку, помещаем её в список строк и
        // наполняем из стандартного входного потока.
 
        Strings.push_back(BasicString());
        std::cout << std::endl << "Vvedite stroku: ";
        std::cin >> Strings.back();
 
        // Спрашиваем у пользователя продолжать строить список или
        // достаточно.
 
        std::cout << "Prodolgim napolnyat spisok strok (y - da, n - net)? ";
        (std::cin.get(lNext)).get();
        
 
        if (lNext != 'y') {
            break;
        }
 
    }
 
    // Сортируем строки в списке строк в лексикографическом порядке.
 
    Strings.sort();
 
    // Отображаем строки в порядке обратном лексикографическому, используя реверсивный итератор.
 
    std::cout << "Stroki v obratnom leksikograficheskom poryadke:" << std::endl << std::endl;
    std::list<BasicString>::reverse_iterator lRit = Strings.rbegin();
    while (lRit != Strings.rend()) {
        std::cout << *(lRit++) << std::endl;
    }
 
    // Ждём команды пользователя на выход из программы.
 
    std::cout << std::endl << "Dlya vychoda nagmite klavishi 'e' i 'Enter' ";
    std::cin >> lNext;
 
    return 0;
 
}
0
Миниатюры
Чтение символов из cin в буфер в цикле  
alsav22
5429 / 4824 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.06.2013, 13:49 #14
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
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <string>
#include <list>
#include <cstdlib>
 
namespace yury
{
    typedef char T;
    typedef std::string BasicString;
}
 
std::basic_istream<yury::T, std::char_traits<yury::T> >& operator >> (std::basic_istream<yury::T, std::char_traits<yury::T> > &stream, yury::BasicString &string)
{
    std::getline(stream, string);
 
    return stream;
}
 
 
int main()
{
    std::cout << "Seychas budem napolnyat spisok strokami." << std::endl;
    yury::T lNext;
 
    // Создаём список строк.
 
    std::list<yury::BasicString> Strings;
 
    // Наполняем список строк.
 
    while (true) {
 
        // Создаём строку, помещаем её в список строк и
        // наполняем из стандартного входного потока.
 
        Strings.push_back(yury::BasicString());
        std::cout << std::endl << "Vvedite stroku: ";
        std::cin >> Strings.back();
 
        // Спрашиваем у пользователя продолжать строить список или
        // достаточно.
 
        std::cout << "Prodolgim napolnyat spisok strok (y - da, n - net)? ";
        (std::cin.get(lNext)).get();
        
 
        if (lNext != 'y') {
            break;
        }
 
    }
 
    // Сортируем строки в списке строк в лексикографическом порядке.
 
    Strings.sort();
 
    // Отображаем строки в порядке обратном лексикографическому, используя реверсивный итератор.
 
    std::cout << "Stroki v obratnom leksikograficheskom poryadke:" << std::endl << std::endl;
    std::list<yury::BasicString>::reverse_iterator lRit = Strings.rbegin();
    while (lRit != Strings.rend()) {
        std::cout << *(lRit++) << std::endl;
    }
 
    // Ждём команды пользователя на выход из программы.
 
    std::cout << std::endl << "Dlya vychoda nagmite klavishi 'e' i 'Enter' ";
    std::cin >> lNext;
 
    return 0;
 }
1
23.06.2013, 13:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.06.2013, 13:49
Привет! Вот еще темы с ответами:

Cin, чтение с конца полученного потока - C++
Происходит ввод с клавиатуры последовательности чисел разделенных пробелами, нужно извлечь из этого потока последнее значение. Как?

Чтение последовательности чисел из cin в массив - C++
Добрый вечер. Есть код: vector&lt;unsigned int&gt; block; while (!bGood) { counter=0; cout&lt;&lt;&quot;\r\nEnter ciphertext: &quot;; ...

Выяснить почему после ввода первого элемента массива цикл не работает (std::cin в цикле for) - C++
Добрый день! Взялся за простой пример из книги Лафоре. #include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace std; const...

Ограничение на ввод символов scanf() и cin - C++
Здравствуйте. Возможно ли ограничить ввод символов после вызова scanf() или cin? Нужно чтоб после вызова этих функций пользователь...


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

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

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