Rle codificando ... qual é o errado?
Pergunta
Estou tentando fazer um programa RLE (Run-Length Coder) apenas para caracteres. Eu li como ele funciona nas notas na rede. E eu tentei consertar meu código! Independentemente disso, acho que as etapas do código estão certas, o código não funciona! Parece algum 'z' estranho como corre. Eu realmente não consigo encontrar o que; está errado! Você poderia me dar um conselho?
#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;
}
por exemplo, eu dei a entrada:
AAAAAAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEGGGGGGGGGGGGGGGGVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRHD RRRRRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMS TTTTTTTTTTHHHHHHHHHHHH
E eu obtive a saída:
Z0AZZ0AZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0GZZ0GZZ0GZZ0GZZ0GZZ0GZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0RZZ0RZZ0RZZ0RZZ0 ZZ0RZZ0RZZ0RZZ0RZZ0RZZ0RZZ0HZZ0HZZ0HZZ0HZZ0HZZ0HZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :(
Solução
Convertendo comentários anteriores em uma resposta ...
Existem problemas com as atribuições nas condições 'if' - como apontado na outra resposta.
Você não pode atribuir um valor a um char não assinado e, em seguida, espera detectar o EOF. Esqueça o nome - lembre -se de que getc () e getchar () (e fgetc ()) retornam um número inteiro, não um char; Eles precisam devolver um número inteiro porque precisam devolver todos os valores de caracteres válidos mais possíveis mais EOF!
Seu teste em
if(currChar=='EOF')
é bizarro. Você está usando uma constante de vários caracteres, que é, na melhor das hipóteses, definida pela implementação e que não será igual a EOF (não cotado) conforme retornado por getchar (). Além disso, o tipo de currchar está errado.reverse () sempre retorna 0; É isso que você realmente queria?
A linha '
while(currChar=getchar() != EOF)
'Precisa de parênteses extras para que funcione como esperado:'while((currChar = getchar()) != EOF)
'. No momento, ele atribui 0 (nul, ' 0') ou 1 (Control-A) a Currchar.O interior enquanto o Loop não lê nenhum personagem, por isso vai enviar seu programa para um frenesi - ele precisa da atribuição '
while((currChar = getchar()) != EOF)
'Notação também. Então você precisa descobrir qual é a saída esperada, porque não acho que faça muito sentido - em particular, o perdido 'printf("%c",currChar);
'Após o teste principal, é duvidoso - talvez seja uma impressão de depuração que você deixou para trás por acidente.Você também precisa considerar como o código deve lidar com coisas como as novas linhas - e isso é antes de chegarmos a problemas de ambiguidade na saída (como você diz a diferença entre os dados codificados e dados que contêm valores numéricos. Há muito com que se preocupar Sobre no seu algoritmo! Na maioria das vezes, não é correto, lamento relatar.
Aqui está algum código semi-trabalhador; Ele se recusa explicitamente a lidar com dígitos (mas isso é tudo).
/* 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;
}
E esta é a saída quando a executo em seu próprio código -fonte (observe que eu uso espaços, não guias). As mensagens de 'personagem falso' são impressas no Stderr, não no stdout.
/* 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 ;
}
Outras dicas
Olhe para esta linha:
if ( ( (currChar='A')&&(currChar='Z') ) || ( (currChar='a')&&(currChar='z') ) )
você está atribuindo 'a' para currChar
Então você está atribuindo 'z' para currChar
e assim por diante...
Você precisa mudar =
para ==
para fazer isso comparação em vez de atribuição.
Além disso, o que você quer dizer com (currChar='A')&&(currChar='Z')
? currChar
não pode ser 'a' e 'z' ao mesmo tempo, acredito que o que você pretendia colocar aqui foi um cheque para currChar
sendo incluído em determinado intervalo. Então provavelmente deveria ser:
(currChar>='A')&&(currChar<='Z')
O mesmo se aplica à segunda parte da sua condição.