Reputation: 503
I'm trying to make a RLE (Run-Length Encoder) Programme just for characters. I read the way it works on notes on net. And I tried to fix my code! Regardless I think that the steps of code are right, the code doesnt work! It appears some strange 'Z' as it runs. I really can't find what;s wrong! Could you please give me a piece of advice?
#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;
}
e.g. I gave the input:
AAAAAAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEGGGGGGGGGGGGGGGGVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRHD RRRRRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMS TTTTTTTTTTHHHHHHHHHHHH
and I got the output:
Z0AZZ0AZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0FZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0EZZ0GZZ0GZZ0GZZ0GZZ0GZZ0GZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0VZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0SZZ0RZZ0RZZ0RZZ0RZZ0 ZZ0RZZ0RZZ0RZZ0RZZ0RZZ0RZZ0HZZ0HZZ0HZZ0HZZ0HZZ0HZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0AZZ0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :(
Upvotes: 0
Views: 871
Reputation: 754640
Converting previous comments into an answer...
There are problems with assignments in the 'if' conditions - as pointed out in the other answer.
You cannot assign a value to an unsigned char and then expect to detect EOF. Forget the name - remember that getc() and getchar() (and fgetc()) return an integer, not a char; they have to return an integer because they need to return every possible valid character value plus EOF!
Your test at if(currChar=='EOF')
is bizarre. You are using a multi-character constant, which is at best implementation-defined, and which is not going to equal EOF (unquoted) as returned by getchar(). Plus the type of currChar is wrong.
reverse() always returns 0; is that what you really wanted?
The line 'while(currChar=getchar() != EOF)
' needs extra parentheses so that it works as expected: 'while((currChar = getchar()) != EOF)
'. At the moment, it assigns 0 (NUL, '\0') or 1 (Control-A) to currChar.
The inner while loop does not read any characters, so it is going to send your program into a frenzy - it needs the assigning 'while((currChar = getchar()) != EOF)
' notation too. Then you need to work out what the expected output really is, because I don't think it makes much sense - in particular, the stray 'printf("%c",currChar);
' after the main test is dubious - maybe it is a debugging print that you left behind by accident.
You also need to consider how the code should handle things like newlines - and that's before we get to issues of ambiguity in the output (how do you tell the difference between the RLE encoded data and data containing numeric values. There is a lot to worry about in your algorithm! It is mostly not correct, I'm sorry to report.
Here is some semi-working code; it explicitly refuses to deal with digits (but that's all).
/* 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;
}
And this is the output when I run it on its own source code (note that I use spaces, not tabs). The 'Bogus character' messages are printed on stderr, not 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 ;
}
Upvotes: 2
Reputation: 16236
Look at this line:
if ( ( (currChar='A')&&(currChar='Z') ) || ( (currChar='a')&&(currChar='z') ) )
you are assigning 'A' to currChar
then you are assigning 'Z' to currChar
and so on...
You need to change =
to ==
to make it comparison instead of assignment.
Also, what do you mean by (currChar='A')&&(currChar='Z')
? currChar
cannot be 'A' and 'Z' at the same time, I believe what you meant to put here was a check for currChar
being included in certain interval. So it should probably be:
(currChar>='A')&&(currChar<='Z')
The same applies for the second part of your condition.
Upvotes: 3