Кодирование RLE… Что не так?
Вопрос
Я пытаюсь создать программу RLE (кодировщик длины пробега) только для символов.Я читал, как это работает в заметках в сети.И я попытался исправить свой код!Несмотря на то, что я считаю, что шаги кода правильные, код не работает!Во время работы появляется какая-то странная буква «Z».Я действительно не могу найти, что не так!Не могли бы вы дать мне совет?
#include <stdio.h>
int main()
{
int count;
unsigned char currChar,prevChar=EOF;
while(currChar=getchar() != EOF)
{
if ( ( (currChar='A')&&(currChar='Z') ) || ( (currChar='a')&&(currChar='z') ) )
{
printf("%c",currChar);
if(prevChar==currChar)
{
count=0;
currChar=getchar();
while(currChar!=EOF)
{
if (currChar==prevChar)
count++;
else
{
if(count<=9)
printf("%d%c",count,prevChar);
else
{
printf("%d%c",reverse(count),prevChar);
}
prevChar=currChar;
break;
}
}
}
else
prevChar=currChar;
if(currChar==EOF)
{ printf("%d",count);
break;
}
}
else
{
printf("Error Message:Only characters are accepted! Please try again! False input!");
break;
}
}
return 0;
}
int reverse(int x)
{
int p,y,r=0;
x=(x<0)?-x:x;
while (x>0)
{
y=x%10;
p=x/10;
r=10*r+y;
x=p;
}
printf("%d",r);
return 1;
}
напримерЯ дал вводные данные:
AAAAAAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEGGGGGGGGGGGGGGGGVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRHD RRRRRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMS TTTTTTTTTTHHHHHHHHHHHH
и я получил результат:
Z0AZZ0AZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0GZZ0GZZ0GZZ0GZZ0GZZ0GZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0RZZ0RZZ0RZZ0RZZ0 ZZ0RZZ0RZZ0RZZ0RZZ0RZZ0RZZ0HZZ0HZZ0HZZ0HZZ0HZZ0HZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :(
Решение
Преобразование предыдущих комментариев в ответ...
Существуют проблемы с назначениями в условиях «если», как указано в другом ответе.
Вы не можете присвоить значение беззнаковому символу, а затем ожидать обнаружения EOF.Забудьте имя — помните, что getc() и getchar() (и fgetc()) возвращают целое число, а не символ;они должны возвращать целое число, потому что им нужно вернуть все возможные допустимые значения символов плюс EOF!
Ваш тест в
if(currChar=='EOF')
это странно.Вы используете многосимвольную константу, которая в лучшем случае определяется реализацией и не будет равна EOF (без кавычек), возвращаемому getchar().Плюс тип currChar неправильный.verse() всегда возвращает 0;это то, чего ты действительно хотел?
Линия '
while(currChar=getchar() != EOF)
' нужны дополнительные круглые скобки, чтобы все работало как положено:'while((currChar = getchar()) != EOF)
'.На данный момент он присваивает currChar 0 (NUL, '\0') или 1 (Control-A).Внутренний цикл while не читает никаких символов, поэтому он приведет вашу программу в безумие — ему необходимо присваивание '
while((currChar = getchar()) != EOF)
' тоже обозначение.Затем вам нужно выяснить, каков на самом деле ожидаемый результат, потому что я не думаю, что это имеет большой смысл - в частности, случайный 'printf("%c",currChar);
' после основного теста сомнительно - возможно, это отладочный отпечаток, который вы случайно оставили.Вам также необходимо подумать о том, как код должен обрабатывать такие вещи, как символы новой строки, — и это до того, как мы перейдем к проблемам неоднозначности вывода (как определить разницу между данными в кодировке RLE и данными, содержащими числовые значения).В вашем алгоритме есть о чем беспокоиться!По большей части это не правильно, мне жаль сообщать об этом.
Вот некоторый полурабочий код;он явно отказывается иметь дело с цифрами (но это все).
/* RLE - Run Length Encoding */
/* SO 2485285 */
/*
** Input: stream of data except for digits 0-9
** Output: stream of data with adjacent sets of 3 or more of the same
** character represented by 3Z (for ZZZ), etc.
*/
#include <stdio.h>
#include <ctype.h>
static void print_rle(int count, int repchar)
{
if (count > 2)
printf("%d%c", count, repchar);
else if (count == 2)
printf("%c%c", repchar, repchar);
else if (repchar != EOF)
printf("%c", repchar);
}
int main()
{
int count = 1;
int currChar;
int prevChar = EOF;
while ((currChar = getchar()) != EOF)
{
if (isdigit(currChar))
fprintf(stderr, "Bogus character %c read - ignored\n", currChar);
else if (currChar == prevChar)
count++;
else
{
print_rle(count, prevChar);
count = 1;
prevChar = currChar;
}
}
print_rle(count, prevChar);
return 0;
}
И это результат, когда я запускаю его с собственным исходным кодом (обратите внимание, что я использую пробелы, а не табуляции).Сообщения «Поддельный символ» выводятся на стандартный вывод, а не на стандартный вывод.
/* RLE - Run Length Encoding */
Bogus character 2 read - ignored
Bogus character 4 read - ignored
Bogus character 8 read - ignored
Bogus character 5 read - ignored
Bogus character 2 read - ignored
Bogus character 8 read - ignored
Bogus character 5 read - ignored
/* SO */
/*
Bogus character 0 read - ignored
Bogus character 9 read - ignored
** Input: stream of data except for digits -
Bogus character 3 read - ignored
** Output: stream of data with adjacent sets of or more of the same
Bogus character 3 read - ignored
**9 character represented by Z (for 3Z), etc.
*/
#include <stdio.h>
#include <ctype.h>
static void print_rle(int count, int repchar)
{
Bogus character 2 read - ignored
4 if (count > )
8 printf("%d%c", count, repchar);
Bogus character 2 read - ignored
4 else if (count == )
8 printf("%c%c", repchar, repchar);
4 else if (repchar != EOF)
8 printf("%c", repchar);
}
int main()
{
Bogus character 1 read - ignored
4 int count = ;
4 int currChar;
4 int prevChar = EOF;
4 while ((currChar = getchar()) != EOF)
4 {
8 if (isdigit(currChar))
12 fprintf(stderr, "Bogus character %c read - ignored\n", currChar);
8 else if (currChar == prevChar)
12 count++;
8 else
8 {
12 print_rle(count, prevChar);
Bogus character 1 read - ignored
12 count = ;
12 prevChar = currChar;
8 }
4 }
4 print_rle(count, prevChar);
Bogus character 0 read - ignored
4 return ;
}
Другие советы
Посмотрите на эту строку:
if ( ( (currChar='A')&&(currChar='Z') ) || ( (currChar='a')&&(currChar='z') ) )
вы присваиваете букву «А» currChar
тогда вы назначаете «Z» currChar
и так далее...
Вам нужно изменить =
к ==
сделать это сравнением вместо присвоения.
Кроме того, что вы имеете в виду под (currChar='A')&&(currChar='Z')
? currChar
не может быть «А» и «Z» одновременно, я полагаю, вы хотели поставить здесь чек на currChar
будучи включенными в определенный интервал.Так что, вероятно, должно быть:
(currChar>='A')&&(currChar<='Z')
То же самое относится и ко второй части вашего состояния.