2016-12-23 25 views
0

Проблема, с которой я сталкиваюсь, заключается в том, что я хочу точно видеть, что находится во входном буфере, когда кто-то вводит что-то в консоль. Единственный способ узнать, как это увидеть, - это либо std :: cin :: getline(), либо std :: getline(), но я думаю, что оба они записывают либо в указатель char, либо в std :: string, основываясь на том, что подходит для конкретной строки символов в конце строки. Например, я думаю, что в Windows, если вы нажмете enter на консоли, он будет вводить '\ r' '\ n', но когда я пытаюсь прочитать его из указателя char или строкового объекта, он не отображает «\ р'. Например, если я ввожу слово привет в консоли, я подозреваю, что окна ставит:Как я могу точно увидеть, что находится в буфере ввода std :: cin?

«ч» «е» 'л «л» «о»' \ г «\ п»

в буфер, но в указателе char или строчном объекте я вижу только «привет». Я в основном хочу посмотреть, что находится во входном буфере. Могу ли я извлечь каждый символ из буфера один за другим в цикле, чтобы он не выбрасывал пробельные символы?

+1

Вообще, невозможно со стандартным C++. В системах, где это имеет значение, вы иногда можете уйти с закрытием и повторным открытием 'std :: cin' в двоичном режиме, а затем использовать' read() 'для получения символов. Но это не гарантируется стандартом. – Peter

+0

Для потоков _text_ (т. Е. Потоки файлов, не открытые с помощью 'std :: ios_base :: binary'), конечная последовательность для конкретной платформы преобразуется в' \ n' при чтении. При записи в эти потоки применяется противоположная операция. То есть, в Windows при чтении '\ r \ n' он преобразуется в' \ n'. Стандартные потоковые объекты обычно ведут себя как потоки файлов, открытые в текстовом режиме. Стандарт фактически не указывает точное поведение для стандартных объектов потока. –

ответ

0

Я думаю, что это должно работать:

std::string mystring; 
std::cin >> mystring; 

for(unsigned int i = 0; i < mystring.size(); i++) 
{ 
    switch(mystring[i]) 
    { 
     case ‘\n’: 
      cout << “\\n”; // print \n by escaping the slash 
      break; 
     case ‘\r’: 
      cout << “\\r”; // print \r by escaping the slash 
      break; 
     // OTHER CASES HERE 
     default: 
      cout << mystring[i]; // print the string normally 
      break; 
    } 
} 
+0

Кажется, что не работает, если я нахожусь в приветствии в консоли, чтобы переключить петлю только приветствия. Я думаю, что это потому, что в std :: string есть только привет, вот и все, он никогда не копировал никаких «\ r» или «\ n». – Zebrafish

+0

О, мой плохой я вижу. Но если это так, то буфер технически не имеет «\ n», я полагаю. Я предполагаю, что поток просто отключает строку в '\ n' и помещает терминатор '\ 0' в это место, так как _line_ на этом заканчивается. – Jas

+0

Глядя на это более тщательно, я просто понял, что неправильно истолковал ваш вопрос. Я предположил, что с помощью входного буфера вы имели в виду собственно строку. Я считаю, что ответ Мам-лагерстера - это то, что вы ищете. – Jas

2

std::cin является std::basic_istream и можно манипулировать как таковой.

Обычно вы читаете поток с помощью >> или getline, например. Оба эти чтения «знают, когда остановиться».

Но если вы хотите заглянуть в буфер с помощью \n s, тогда предполагается, что вы передадите поток с консоли символами новой строки и что функции, которые вы используете для чтения, не будут «съедать» строки новой строки ,

copy the buffer to a string. Но помните, что вам придется signal the EOF каким-то другим способом.

#include <iostream> 
#include <string> 
#include <sstream> 

int main() { 
    std::ostringstream oss{}; 
    oss << std::cin.rdbuf(); 
    std::string all_chars{oss.str()}; 
    std::cout << all_chars; 
    return 0; 
} 

На окнах, если я типа челлоВведитетчегеВведите следует Ctl + г (должно быть на новую линию для окон), то я вижу:

hello 
there 
^Z 
hello 
there 

Таким образом, в этом примере, все включая переводы строк хранились в std::string.


Но я вижу только \n для линейных окончаний.Я думал, что Windows, должен был использовать \r\n для линейных окончаний

Я добавил следующее, чтобы показать отдельные символы в явном виде:

int index{}; 
for(auto mychar : all_chars) 
    std::cout << std::setw(3) << index++ << ": character number " << std::setw(5) << static_cast<int>(mychar) 
     << " which is character\t"<< ((mychar == 10) ? "\\n" : std::string{}+mychar) << '\n'; 

Для того же входа он производит:

hello 
there 
^Z 
hello 
there 
    0: character number 104 which is character h 
    1: character number 101 which is character e 
    2: character number 108 which is character l 
    3: character number 108 which is character l 
    4: character number 111 which is character o 
    5: character number 10 which is character \n 
    6: character number 116 which is character t 
    7: character number 104 which is character h 
    8: character number 101 which is character e 
    9: character number 114 which is character r 
10: character number 101 which is character e 
11: character number 10 which is character \n 

Итак, это показывает, что из консоли передаются только \n s, а не \r s, чтобы быть fou без обозначения даты Я использовал Windows 10 для этого теста, но я полагаю, что это было поведением некоторое время.

+0

Хорошо, это классный трюк. Но я вижу только «\ n» для окончаний строк. Я думал, что Windows должна использовать '\ r' '\ n' для окончаний строк, например, при создании документа в блокноте. Я предположил, что консоль будет такой же. – Zebrafish

+0

Это странно. Огромное спасибо. Другое правило/исключение, которое мне придется добавить в голову. – Zebrafish