#c #while-loop #getchar
#c #цикл while #getchar
Вопрос:
Как использовать getchar в качестве условия для цикла while и завершить его, когда (c= getchar()) = EOF или ‘ n’ или ».
Я пытался:
int c=0;
while((c=getchar()) != EOF || 'n' || ''){
putchar();
}
Что не сработало, если я ввел: ПОГОДА ( enter). Это не завершило цикл.
Как я могу заставить это работать?
Просвети меня
Комментарии:
1. Я бы посоветовал прочитать копию Языка программирования C ( en.wikipedia.org/wiki/The_C_Programming_Language ), часто известный как Kamp;R. Похоже, у вас глубокое непонимание логических операторов и / или порядка операций.
Ответ №1:
Вы могли бы использовать что-то вроде этого:
int c = 0;
while((c=getchar()) != EOF) {
if ((c == 0) || (c == 'n'))
break;
putchar(c);
}
Ответ №2:
while ((c = getchar()) != EOF amp;amp; c != 'n' amp;amp; c != '')
{
// loop body
}
Это работает, потому что amp;amp;
оператор a) всегда сначала вычисляет выражение LHS и b) вводит точку последовательности, поэтому любые побочные эффекты в выражении LHS (такие как присвоение результата getchar
to c
) будут применены до вычисления выражения RHS.
Ответ №3:
Я думаю, это должно сработать:
int c;
while( (c=getchar()) != EOF amp;amp; c!='n' amp;amp; c!='') {
putchar();
}
но, возможно, было бы лучше просто сделать:
int c=getchar();
while( c != EOF amp;amp; c!='n' amp;amp; c!=''){
putchar();
c=getchar();
}
Комментарии:
1. Второй вариант определенно лучше. Избегайте назначений в условиях, поскольку = и == легко вводятся с ошибками, может быть неясно, какова цель обслуживания.
Ответ №4:
К сожалению, вам нужно будет разложить его на несколько операторов. Вы пытаетесь выполнить логическое или из нескольких вещей, и, учитывая, что «true» — это «что-либо ненулевое», а символы — это просто числа, большинство из которых ненулевые, вы в основном говорите «пока c не является EOF, или TRUE или TRUE».
Я не совсем уверен в спецификации C, но может сработать переписывание инструкции следующим образом:
while((c=getchar()) != EOF amp;amp; c!='n' amp;amp; c!='')
Это может быть неопределенным, хотя основано на порядке вычисления, и это выглядит беспорядочно.
Лучшее решение — переместить «c = getchar()» куда-нибудь еще и вместо этого проверить значения C в заголовке while. Это означает, что вам придется переместить «c = getchar()» как за пределы цикла, так и в нижнюю часть тела цикла while.
Комментарии:
1. Это не определено из-за порядка работы; из-за короткого замыкания подвыражения гарантированно выполняются по порядку.
Ответ №5:
Учитывайте свой код, например
while (intint((int []){ EOF, 'n', 0 }, c=getchar(), 3) ...
Где intint
это функция, которую вы пишете как memchr
, но принимающая массив целых чисел. 🙂
Этот ответ — наполовину шутка, поскольку другие ответы уже достаточно хорошо решают проблему, но дело в том, что часто определение правильной функции с правильным интерфейсом может сделать ваш код намного проще.
Ответ №6:
Это не работает, потому что EOF || 'n' || ''
это логическое выражение, которое всегда будет вычисляться как true
поэтому условие сводится к if( c != true )
, что только true
если c равно nul, которое getchar() обычно не возвращает.
Присваивания в условиях всегда опрометчивы, и некоторые компиляторы выдадут предупреждение, если само присвоение не будет заключено в круглые скобки. Это делается для того, чтобы предостеречь от случайного использования, =
когда в условии предполагалось более обычное ==
.
В C у вас должны быть отдельные логические выражения, даже если каждое из них проверяет одну и ту же переменную:
int c = getchar() ;
if( c != EOF amp;amp; c != 'n' amp;amp; c != '' )
...
Ответ №7:
Довольно объемное, но очень индивидуальное решение может быть:
#include <stdarg.h>
#define END_INPUT -12332 // not likely to be returned from getchar()...
int is_any(int c, ...)
{
va_list ap;
va_start(ap, c);
int ret = 0;
while (ret == 0) {
int a = va_arg(ap, int);
if (a == END_INPUT) break; // End of inputs - not any of the given ones
if (c == a) ret = 1; // will result in a break as well...
}
va_end(ap);
return ret;
}
int main()
{
int c;
while( isany(c=getchar(), EOF, 'n', '', END_INPUT) {
...
}
}
Ответ №8:
Если вы готовы отказаться от int c
и использовать char
вместо этого, то можно закодировать его короче, используя стандартные библиотечные функции, сохраняя при этом расширяемый список исключений:
char terminate_on[] = { EOF, 'n', '' }; /* needs to end with '' */
char c[2] = { '', '' };
while ((*c = getchar()) amp;amp; !strpbrk(c, terminate_on))
putchar(*c);
Хотя всего для двух символов «разрыва» это, вероятно, менее эффективно, чем явная последовательность тестов.
Посмотрите strpbrk()
, что делает эта функция.