Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чтобы не срабатывал переход на следующую строку. 
:(
    Опции темы
alsav22
Дата 15.5.2012, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.4.2012

Репутация: нет
Всего: нет



 Есть некий ввод символов, организованный через cin.get(char &), или через cin.get(char &, int), или через cin.getline(char &, int). Выведена на консоль, например, фраза: "Введите то-то: ". Дальше мигает курсор (приглашение на ввод). Если вводится не то, что нужно, то на следующей строке выводится то же:"Введите то-то: " и курсор на ввод. Всё получается кроме одного: если просто нажать <Enter>, то курсор на ввод переходит на начало следующей строки. Как сделать чтобы этого не происходило? То есть, при нажатии на <Enter>, или курсор оставался на том же месте, или на следующей строке выводилось то же : "Введите то-то: " и курсор на ввод.
PM MAIL   Вверх
disputant
Дата 15.5.2012, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Проверьте, что введено, и если ничего - повторите запрос.

Лучше это делать в цикле...
PM MAIL   Вверх
alsav22
Дата 15.5.2012, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.4.2012

Репутация: нет
Всего: нет



Цитата

Проверьте, что введено, и если ничего - повторите запрос.




В том-то и дело, что так не получается. Например, такая конструкция не работает как надо: 
     
Код

char s = '\n';
m :cout << "Введите один символ или нажмите <Enter>: ";
     cin.get(s);
     if (s == '\n')
     {
        cin.clear();
        cin.get();
        goto m;
     }
    else cout << s << endl;


Сравнение происходит при втором нажатии <Enter>. При первом нажатии происходит переход на начало следующей строки.
Дело,насколько я понимаю, в том, что эти функции, в не зависимости от того, что они делают с символом перевода строки, всегда его обрабатывают, т.е. выполняют. И вопрос в том, как сделать так, что бы они его или не обрабатывали, или, в результате обработки, выводилась таже надпись с курсором в конце.


Это сообщение отредактировал(а) alsav22 - 15.5.2012, 13:12
PM MAIL   Вверх
bsa
Дата 15.5.2012, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



alsav22, забудь об операторе goto. НЕ ИСПОЛЬЗУЙ ЕГО НИКОГДА!!!
когда станешь опытным программистом, узнаешь, когда его можно использовать, а когда нет.
Код
do {
     cout << "Введите один символ или нажмите <Enter>: ";
     int s = cin.get();
     if (s == '\n')
     {
        cin.clear();
        cin.get();
        continue;
     }
     if (s < 0)
        break; //error
     cout << char(s) << endl;
} while(false);


PM   Вверх
alsav22
Дата 15.5.2012, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.4.2012

Репутация: нет
Всего: нет



Знаю я о goto. В пределах видимости можно. А по теме, ничего не предложите? Ваш код тоже перевод строки делает.

Это сообщение отредактировал(а) alsav22 - 15.5.2012, 14:06
PM MAIL   Вверх
disputant
Дата 15.5.2012, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Вот что имел в виду я:

Код

#include <iostream>

using namespace std;


int main(int argc, const char * argv[])
{
    char sym[20];
    for(;;)
    {
        cout << "Input symbol or press <Enter>:" << flush;
        cin.getline(sym,20);
        if (strlen(sym)) break;
    }
}


Если вам позарез именно get, то добавьте считывание второго символа. 

Код

int main(int argc, const char * argv[])
{
    char sym;
    for(;;)
    {
        cout << "Input symbol or press <Enter>:" << flush;
        cin.get(sym);
        if (sym == 0x0A) continue;
        break;
    }
    cout << "Input: " << sym << endl;
    cin.get(sym);
}


Но мне не нравится сама идея, потому что что вы будете делать, если пользователь введет не один символ, а строку? Проще брать строку и убеждаться, что в ней 1 символ.

PM MAIL   Вверх
alsav22
Дата 15.5.2012, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.4.2012

Репутация: нет
Всего: нет



Благодарю! Я в первом посте насчёт  cin.getline(char &, int) писал. Конечно с ней лучше.
PM MAIL   Вверх
alsav22
Дата 15.5.2012, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.4.2012

Репутация: нет
Всего: нет



Получается, что это код у меня не работал только из-за лишнего cin.get(). Да и cin.clear(); там не нужен.

Код

char s = '\n';
m :cout << "Введите один символ или нажмите <Enter>: ";
     cin.get(s);
     if (s == '\n')
     {
        cin.clear();
        cin.get();
        goto m;
     }
    else cout << s << endl;


А чтобы работало (если в цикле сделать), когда вводится не один символ, можно, после тела if, воспользоваться такой конструкцией:
Код

cin.clear();
while(cin.get() != '\n')
   continue;


Это сообщение отредактировал(а) alsav22 - 15.5.2012, 15:29
PM MAIL   Вверх
Alca
Дата 15.5.2012, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



я так делал: 
https://bitbucket.org/skynowa/xlib/src/34ce...sole.cpp#cl-216

Код

bool
CxConsole::bPrompt(
    const std::tstring_t &csPrompt,
    const bool            cbIsVisible,
    std::tstring_t       *psAnswer
)
{
    /*DEBUG*/xASSERT_RET(false == csPrompt.empty(), false);
    /*DEBUG*/xASSERT_RET(NULL  != psAnswer,         false);

    for ( ; ; ) {
        bool bRes = bWrite(csPrompt + xT(": "));
        /*DEBUG*/xASSERT_RET(true == bRes, false);

        for ( ; ; ) {
            const tchar_t chLetter = static_cast<tchar_t>( std::tcin.get() );   

            // asterisks
            xCHECK_DO(true == cbIsVisible, bWrite(xT("*")));

            // ENTER
            xCHECK_DO(10 == chLetter, break);

            // BACKSPACE
            xCHECK_DO(0x8 == chLetter, (*psAnswer).clear(); continue);

            (*psAnswer).push_back(chLetter);
        }

        bRes = bWriteLine(CxConst::xSTR_EMPTY);
        /*DEBUG*/xASSERT_RET(true == bRes, false);

        xCHECK_DO(true == (*psAnswer).empty(), continue);

        break;
    }

    return true;
}



--------------------
PM WWW ICQ Skype Jabber   Вверх
bsa
Дата 16.5.2012, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(alsav22 @  15.5.2012,  15:03 Найти цитируемый пост)
Знаю я о goto. В пределах видимости можно. А по теме, ничего не предложите? Ваш код тоже перевод строки делает.

мой код относился к goto. И про этот оператор ты ничего не знаешь (то, как ты его использовал об этом и говорит). НЕ ИСПОЛЬЗУЙ ЕГО ВООБЩЕ!!! оператор нужен в одном из 100 случаев. Например, выход из циклов второй и более вложенности. Или, в языке С, для перехода на код отката изменений в случае ошибки (в С++ есть RAII и исключения, поэтому не актуально).
PM   Вверх
alsav22
Дата 16.5.2012, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 13.4.2012

Репутация: нет
Всего: нет



 Про goto я знаю, что его нужно применять как можно реже, и на это есть определённые причины("спагетти" и пр.). Но, в данном конкретном коде, можете назвать причины, по которым его ЗДЕСЬ нельзя использовать (кроме причины, что не надо привыкать к дурному)? Что может произойти неправильного в данном коде из-за этого? Поверьте, что я действительно хочу в этом разобраться, а не просто тупо стою на своём. 
PM MAIL   Вверх
bsa
Дата 16.5.2012, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



alsav22, в данном конкретном коде проблем из-за goto нет. Разве что, читать не так удобно, как в случае с циклом.
Но, код редко остается неизменным всю свою жизнь. Рано или поздно могут быть внесены изменения. Потом еще изменения, и в итоге ты получишь слабо понятный глючный код (не забывай, что в отличие от С в С++ есть классы, объекты которых имеют определенные условия создания и уничтожения, а с помощью goto ты можешь испортить всю "малину", перескочив не туда).
Короче. Не используй goto, как бы тебе этого ни хотелось. Уже миллион копий из-за него сломано. Если хочешь, можешь сам поискать дискуссии на эту тему в этом форуме.
А для иллюстрации своих слов приведу пример. Я имею опыт работы с С/С++ около 15 лет. Из них где-то 7 я этими языками активно пользуюсь (до этого несколько маленьких утилиток в год писал). В моем коде (за все вермя работы!) оператор goto встречается около 10-ти раз. Из них один в С++ коде (дешифратор, использует расширение gcc - переход по указателю на метку, указатели хранятся в таблице; данный код легко переписывается через switch/case без потери производительности), а остальные в С-коде недописанного linux-драйвера (очистка контекста в случае ошибки).
PM   Вверх
leniviy
Дата 19.5.2012, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



Если по делу: 
SetConsoleMode
отключить ENABLE_ECHO_INPUT и ENABLE_LINE_INPUT
читать посимвольно, выводить (если надо) всё, кроме '\n'. Недостатки: стрелочки и backspace не будут работать


Это сообщение отредактировал(а) leniviy - 19.5.2012, 20:14
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0854 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.