getchar / putchar возвращает поля с вопросительными знаками при печати введенных символов - PullRequest
0 голосов
/ 05 февраля 2019

Игра с примерами кода из K & R в Codeblocks на Windows 10 (датский язык).Следующий пример работает, как и ожидалось:

#include <stdio.h>

int main() {
    char c = 'a';
    putchar(c);
}

Тем не менее, следующий пример печатает ряд полей с вопросительными знаками, такими же числами, что и количество вводимых символов:

#include <stdio.h>

int main() {
    char c;

    while (c = getchar() != '\n') {
        putchar(c);
    }
}

Итакэто похоже на проблему кодирования.При запуске открывается командная строка с «C: \ Users \ username \ Desktop \ filename.exe» в заголовке, а мое имя пользователя содержит датский символ «å», который заменяется на «Õ».В командной строке используется набор символов CP 850.

(Кстати, я не проверяю, равен ли символ EOF, так как это приводит к нечетным результатам. Нажатие клавиши Enter выводит ожидаемое количество блоков плюсодин для \n, но он не завершает программу.)

Ответы [ 4 ]

0 голосов
/ 05 февраля 2019

В рамках вопроса уже есть несколько правильных ответов, но есть пара более широких проблем, которые вам нужно решить.

Во-первых, getchar() возвращает int, и важно, чтобы выопределите переменную, которая принимает возвращаемое значение как int, чтобы вы могли отличить ошибки и конец файла от действительных char s.

Во-вторых, если вы получили конец файла или произошла ошибка на stdin до того, как программа обнаружит \n, ваш код будет зацикливаться вечно.Это то, что страница руководства на моем ноутбуке говорит о getchar()

В случае успеха эти процедуры возвращают следующий запрошенный объект из потока.Символьные значения возвращаются как беззнаковый символ, преобразованный в int.Если поток находится в конце файла или возникает ошибка чтения, подпрограммы возвращают EOF.

Так что, как только getchar () возвращает EOF, он будет возвращать EOF все время.Вы должны решить эту проблему в своем цикле:

#include <stdio.h>

int main() 
{
    int c;    // c declared as int

    while ((c = getchar()) != EOF && c != '\n')) 
    { 
        putchar(c);
    }
    if (c == EOF) 
    {
        // handle errors and end of file as you see fit
    }
}
0 голосов
/ 05 февраля 2019

Редактировать: Вы получаете коробки из-за отсутствия круглых скобок вокруг задания, посмотрите этот вопрос для справки о том, почему вы должна иметь круглые скобки вокруг присваивания, используемого как значение истины ...

Кроме того, есть еще кое-что, что также не так с этой программой, рассмотрим этот пример: -

Например:

Что вы действительно хотели: -

ABCD
<новая строка>

То, что вы в действительности набрали: -

ABCD

И поскольку программа не нашла '\n' нигде в коде, это приводит к неопределенному поведению, так как она выходит за пределы, чтобы найти его ...

Существует два возможных решения, когда ваш ввод не содержит '\n': -

  • Использование EOF (предложено много , так как это лучшее из возможныхрешение для принятия каждого ввода ...)

    int main() {
        char c;
        while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
                                           an assignment in a condition... */
            putchar(c);
    }
    
  • Добавить новую строку для ввода: -

    int main() {
        char c;
        // Use fputc to modify input...
        fputc('\n', stdin);
        while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
                                           an assignment in a condition... */
            putchar(c);
    }
    

    Но будьте осторожны! Этот метод остановит на первой итерации новой строки, он получит , поэтому, если у вас есть что-то за пределами '\n', то это не будет напечатано ...

0 голосов
/ 05 февраля 2019

Вы видите проблему приоритета операторов здесь.Как вы можете видеть на этот график , = имеет более низкий приоритет, чем !=.

Это означает, что getchar() != '\n' оценивается первым.

Длякомпилятор ваш код выглядит следующим образом:

#include <stdio.h>

int main() {
    char c;

    while (c = (getchar() != '\n')) { 
        putchar(c);
    }
}

Так как 'c' получает неправильное значение (истинное / ложное вычисление выражения), вывод неправильный, и программа дает поведение, которое вы видитеоднако

#include <stdio.h>

int main() {
    char c;

    while ((c = getchar()) != '\n') { //<----notice brackets around c=getchar 
        putchar(c);
    }
}

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

0 голосов
/ 05 февраля 2019

Эта строка плохая.

while (c = getchar() != '\n') 

Должно быть:

while ((c = getchar()) != '\n') 
...