I have a source code in C.
#include <stdio.h>
#define IN_W 1
#define OUT_W 0
#define SPACE 32
#define TAB 9
int main() {
int c, state, temp;
state = OUT_W;
while ((c = getchar()) != EOF) {
if ((c != SPACE || c != TAB) && (state == OUT_W)) {
state = IN_W;
temp = c;
c = 13;
putchar(c);
c = 10;
putchar(c);
putchar(temp);
} else if (c != SPACE || c != TAB)
putchar(c);
else
state = OUT_W;
}
return 0;
}
What I want to achieve is I will type in some characters/words and catch those inputs by getchar. When ever getchar receive any characters besides space or tab, it will print a new line and then print those characters until it found a space or tab (abandon them). For example, when I type
123 eat 4bananas in themorning
the program will print
123
eat
4bananas
in
themorning
I tried to integrate it with CR or LF, but it still print "123 eat 4bananas in themorning".
My questions are: 1. What did I miss? 2. In the last 'else', which one is more efficient for the running program:
else
state = OUT_W;
or
else if ((c == SPACE || c == TAB) && state == IN_W)
state = OUT_W;
else
continue; // or can I use single ';' since we do nothing in here?
That's all. Thank you for your help.
Note: I tried playing with '\n' and '\t' too.
Regards, Mario
This expression is not what you want: (c != SPACE || c != TAB)
This is always true. If c is SPACE then it is not TAB, so the second part would be true. If c is TAB then it is not SPACE so the first part would be true.
In both cases, what you want is (c != SPACE && c != TAB) This is only true when c is not SPACE and also not TAB. The operator && is Boolean "and".
Also, I suggest that instead of magic numbers like 13 you should use C character constants like '\r'.
As for your second question, your program is not too bad as written. I definitely don't think you would improve it by putting in a continue and I don't even quite see how it would work. (As you noted, if the else continue; is at the very end of the loop, you can leave out the continue; actually, you could then just chop off the whole else, because else; does nothing.)
You have written a little state machine. You have three interesting cases:
There is a fourth possibility:
If you want the most efficient code, I think it would be best to rearrange it so that you only need to check for SPACE and TAB in one place:
while ((c = getchar()) != EOF) {
if (c == SPACE || c == TAB) {
state = OUT_W;
}
else {
/* c is not SPACE or TAB so we will print it */
if (state == OUT_W) {
/* transition from OUT_W to IN_W */
state = IN_W;
putchar('\r');
putchar('\n');
putchar(c);
}
else
putchar(c);
}
}
And with this restructured version of the code, it becomes clear that any time you are in IN_W you print the character, but only on the transition you print the CR/LF. So you could shorten this to not have an else, always call putchar(c);, but do that after the check for the transition. I will leave that as an exercise for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With