2012-01-29 4 views
3

Мне нужно прочитать ввод от стандартного ввода до тех пор, пока не будет нажата пробел или табуляция.Как читать ввод со стандартного ввода до тех пор, пока не будет нажата пробел или вкладка?

В конце концов, мне нужно провести ввод в объекте std::string.

+0

Поскольку вход обычно буферизирован в строке, я не думаю, что это легко сделать. – Xeo

+1

Если вход является интерактивным, терминал обычно не отправляет контент до тех пор, пока не будет введена полная строка (ввод отправляется после ввода пользователем клавиши «возврат»). Если вы ожидаете ввести имя и попросите свою программу реагировать на каждый пробел или символ табуляции, вы будете немного удивлены. –

+1

У C++ нет понятия «нажатие клавиши». Вам понадобится библиотека обработки терминала для конкретной платформы. Попробуйте 'ncurses'. –

ответ

3

Поскольку вкладка считается пробелами, вы просите извлечь первый токен из потока. Это очень легко в C++, так как маркер экстракция поведение по умолчанию >> оператора:

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string token; 

    if (!(std::cin >> token)) { /* error */ return 1; } 

    // now you have the first token in "token". 
} 

(Ошибка может произойти только в тайных обстоятельствах, например, когда дескриптор входного файла уже закрыт при запуске программы .)

1

Вы можете std::cin прекратить чтение в любом указанном характере использования

char temp[100]; 
std::cin.getline(temp, 100, '\t'); 

Я не знаю, если вы можете легко получить его на работу с двумя персонажами, хотя.

+0

вы не сможете, но если вам действительно нужны такие функции, вы можете написать свою собственную версию 'std :: getline() ', который принимает предикат в качестве третьего параметра, снова имеет тест, а не символ новой строки. –

2

Вы можете использовать getch() или getchar(), чтобы читать каждый символ отдельно, а затем обрабатывать вход вручную, чтобы при нажатии пробела или вкладки вы заканчивали ввод.

+2

'getch' является специфичным для платформы; он не выходит на большинство платформ. 'getchar' является эквивалентом' std :: cin.get() ', и, как указывали некоторые из комментариев к исходному сообщению, большинство систем ничего не вернет, пока не будет нажата клавиша ввода. –

2

Это должно сделать работу:

#include <stdio.h> 

int main() 
{ 
    char c; 
    do { 
    c=getchar(); 
    /** Your code here **/ 
    } while ((c != ' ') && (c != '\t')); 
    return 0; 
} 
+0

Мне нужно получить std :: string в конце концов. могу ли я сделать это с вашим примером? – AAaa

+0

Создайте пустую строку 'std :: string' перед циклом и добавьте каждый символ (вы можете использовать перегруженный оператор' + = ') – nijansen

+0

Просто добавьте символы в строку, например. 'str.push_back (c)' –

4
#include <iostream> 
#include <string> 

int main() 
{ 
    std::string result; 
    std::cin >> std::noskipws; //don't skip whitespaces 
    char c; 
    while (std::cin >> c) 
    { 
     if(c == '\t' || c == ' ') 
      break; 
     result.push_back(c); 
    } 

} 
+0

Я пытаюсь запустить его, и он продолжает вводить данные после спайка и TAB. в конце концов, наброски символов до того, как пространство будет сохранено в результате (и это хорошо), но по какой-то причине, только когда я нажимаю кнопку ввода, окно ввода закрывается. – AAaa

+2

@AAaa: Чтобы входной сигнал работал, вы должны в конечном итоге нажать ENTER. В этом случае ваша строка будет содержать только символы до первой TAB или пробела. Нет стандартного метода C++ для фактического обнаружения нажатия клавиши –

+4

@AAaa: программа не получает ввод до тех пор, пока пользователь не нажимает кнопку ввода, потому что программа терминала не отправляет ее, пока не будет нажата клавиша ввода. Эта «функция» позволяет терминалу осуществлять редактирование (например, нажимать назад и изменять ввод) перед отправкой его в программу). –

0

использовать зсапЕ для этого:

Простой код:

#include<iostream> 
#include<stdio.h> 
int main() 
{ 
     char t[1000]={'\0'}; 
     scanf("%[^\t ]",t); 
     printf("%s",t); 
     std::string mains(t); 
     return 1; 

} 
1

Простой ответ заключается в том, что вы не можете. Фактически, способ, которым вы сформулировали вопрос, показывает, что вы не понимаете: вход istream: нет такой вещи, как “, нажатой ” в istream, потому что нет гарантии, что вход поступает с клавиатуры.

Возможно, вам понадобится curses или ncurses, который действительно понимает ввод на клавиатуре; консольный выход и остальное.

+0

Давай, Джеймс! Мы все знаем, что вы можете отключить буферизацию строк (по крайней мере, на POSIX-системах) и перейти оттуда даже с помощью 'std :: cin'. Конечно, мы не знали бы, привязана ли она к клавиатуре, но нам может быть безразлично: просто вызовите системные вызовы и не будьте осторожны с их результатом. –

+0

@ DietmarKühl Существуют, конечно, системные решения, а также 'curses'. Проблема в том, что они просто ... зависят от системы. И, насколько я знаю, под Windows единственный способ обойти буферизацию строк - это использовать другой набор системных вызовов. (Но тогда, я не знаю Windows, что хорошо, так что легко может быть что-то, что мне не хватает.) –

1

Похоже, что решение этого, действительно, намного проще с использованием scanf("%[^\t ]", buffer). Если вы хотите сделать это с помощью C++ IOStreams, я считаю, что наиболее подходящим вариантом является установка std::locale с измененной фасеткой std::ctype<char>, которая использует модифицированную интерпретацию того, что считается пространством, а затем читает std::string (см., Например, this answer Я дал для аналогичной задачи). Независимо от того, используете ли вы подход C или C++, вам, вероятно, необходимо отключить буферизацию линии на стандартном входе, если вы хотите узнать о пространстве или вкладке, когда она была введена, а не когда вся строка будет передана вашей программе ,

Смежные вопросы