#c #getchar
#c #getchar
Вопрос:
Для приведенного ниже вопроса,
Упражнение 12336 — Считывайте обычный текст по символу за раз из стандартного ввода программы и печатайте его с каждой строкой, перевернутой слева направо. Читайте, пока не столкнетесь с окончанием данных `
Возможно, вы захотите протестировать программу, набрав `
prog5rev | prog5rev
чтобы увидеть, воссоздана ли точная копия исходного ввода. Для чтения символов до конца данных используйте цикл, такой как`
char ch; while( ch = getchar(), ch >= 0 ) /* ch < 0 indicates end-of-data */ or char ch; while( scanf( "%c", amp;ch ) == 1 ) /* one character read */
Вот мое решение:
#include <stdio.h>
void f(char *);
int main(void)
{
char ch = getchar();
f(amp;ch);
return 0;
}
void f(char *ch){
if(*ch < 0)
return;
else{
char character = getchar();
f(amp;character);
}
putchar(*ch);
}
Ввод:
abc | abc
Вывод:
cba | cba
Вопрос:
Проблема гласит: print it with each line reversed from left to right.
Правильно ли это решение?
Комментарии:
1. Я думаю, что в условии
prog5rev
указано имя программы, а не пример ввода. Они предлагают запустить программу дважды (с результатами одного, передаваемыми другому), и предоставить какой-то другой ввод, и ожидать, что результат будет таким же, как и ввод, потому что он был отменен дважды. Вы, кажется, неправильно истолковали это как означающее|
ввод ввода программы.
Ответ №1:
Это такое умное решение, что я действительно ненавижу его нарушать, но использование стека для него имеет некоторые ограничения. если быть точным, ограничения памяти. Если у вас больше определенного, относительно небольшого объема входных данных, он достигнет предела и произойдет сбой тем или иным способом, например: ошибка сегментации. Все 5 560 737 символов полного Шекспира из Гутенберга не проходят, они разбиваются на 654 337 символов.
Извините, вам нужно использовать кучу для большего ввода.
Комментарии:
1. Я безоговорочно склонен к рекурсии. Всегда пытаюсь найти странный подход для получения рекурсивного решения. Это большая проблема для меня
2. @overexchange с этим подходом нет абсолютно никаких проблем, если вы знаете о его пределах.
Ответ №2:
Да, это работает так, как ожидалось.
Вы читаете символ и вызываете f
. Если EOF не был прочитан, вызовите f
снова, а затем выведите прочитанный символ. Поскольку вы печатаете символ после рекурсивного вызова, символы печатаются в обратном порядке.
Однако одно изменение, которое вы должны внести, — использовать int
вместо char
для типа данных. getchar
Функция возвращает an int
, чтобы можно было правильно определить EOF. putchar
Функция принимает int
, поэтому вам не о чем беспокоиться.
Кроме того, нет необходимости передавать адрес переменной, которая была прочитана, поскольку вызывающая функция его не изменяет. Вы можете просто передать значение переменной и соответствующим образом изменить функцию.
Ответ №3:
Формулировка проблемы уже дает подсказку о решении:
char ch;
while( ch = getchar(), ch >= 0 ) /* ch < 0 indicates end-of-data */
or
char ch;
while( scanf( "%c", amp;ch ) == 1 ) /* one character read */
Вы должны использовать цикл для чтения данных, stdin
а затем внутри цикла проверять, есть ли новая строка, и только после этого печатать эту строку справа налево (возвращать строку).
Ниже приведен код, который простым способом выполняет задачу, возможно, потребуется некоторое улучшение, но он работает.
Пожалуйста, прочитайте комментарии и попытайтесь понять, что там происходит, если у вас есть какие-либо вопросы, пожалуйста, задавайте их.
#include <stdio.h>
#include <string.h> // for memset
void f(char *, int);
int main(void)
{
char ch;
char buffer[1024] = { 0 }; // 1024 = max supported line length
int i; // ieterator
i = 0;
while( scanf( "%c", amp;ch ) == 1 ) { // while there is input
if ( ch == 'n' ) { // if there is a new line
f(buffer, i); // print the line (inverted)
i = 0; // reset iterator
memset(buffer, 0, 1024); // reset buffer
} else {
buffer[i ] = ch; // append read char to the buffer
}
}
return 0;
}
void f(char *str, int n) {
// just print from right to left (easier than reversing and then printing the string)
while (n >= 0) {
putchar(str[n]);
n--;
}
putchar('n');
}
Обновление: в книге рекомендуется протестировать программу с помощью
prog5rev | prog5rev
Я рекомендую создать входной файл, а затем запустить:
$ prog5rev < input.txt | prog5rev
В предыдущем утверждении предполагается, что вы используете linux (или какой-либо unix).
Пример:
[ichramm@wilderjager][~]$ cat input.txt
hello
world
[ichramm@wilderjager][~]$ ./test < input.txt
olleh
dlrow
[ichramm@wilderjager][~]$ ./test < input.txt | ./test
hello
world
Комментарии:
1. Пожалуйста, не выполняйте все его домашнее задание… конечно, направляйте и отвечайте на острые вопросы, но раздача всей энчилады не помогает ему научиться думать, в чем смысл практики
2. @ScottStensland Ты серьезно? Правила ясны: ответ должен быть полным. Итак, вы понижаете голос, если ответ неполный, а также понижаете голос, если ответ слишком полный? Решайтесь!