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
For a start:
is always true. A character cannot be both space and tab at the same time, hence it must always be either a non-tab or non-space. I suspect you meant:
That’s why the state is never going back to
OUT_W, because after the first line end sequence, the secondifstatement is always true, so it will never get to that finalelsebit.The following code works okay:
although it still has that annoying initial newline, which you can fix by simply setting the initial state to
IN_W.There’s also a lot of magic numbers in your code and some rather unnecessary moving of values. Possibly a more polished version would be:
One thing I will mention is that it’s often preferable to separate the state machine itself from the actions carried out. To that end, I would make the primary choice based on the current state rather than the character/state pair, and separate the actions for each state from the state machine.
I think that makes things a lot more readable, and easier to modify: