Hi,
Rainer wrote:
<<
Conventional approach using a state variable:
--------
#include <stdio.h>
int main(void)
{
int c, blanks;
blanks = 0;
while ((c = getchar()) != EOF) {
if (blanks) {
if (c == ' ') continue;
blanks = 0;
} else
blanks = c == ' ';
putchar(c);
}
return 0;
}
>>
If a blank is already found, and c is yet another blank, jump to next
iteration. If not, set blanks to zero and place c in the output
stream.
If blank is set to zero, test whether c is a blank and assign the new
value to blank. Execute the next statement putchar(c).
I see the action of blank like a toggle switch. If the switch is on,
certain conditions apply, if not, other distinct conditions apply.
Rainer wrote:
<<
#include <stdio.h>
static void put_a_char(int);
static void (*process_char)(int) = put_a_char;
static void skip_blanks(int c)
{
if (c == ' ') return;
process_char = put_a_char;
putchar(c);
}
static void put_a_char(int c)
{
putchar(c);
if (c == ' ') process_char = skip_blanks;
}
int main(void)
{
int c;
while ((c = getchar()) != EOF) process_char(c);
return 0;
}
>>
I will try although I may fail.
The main function:
a while loop repeatedly runs getchar assigning it to c and testing
whether it is an EOF. If not, process_char is called with c as
parameter passed by value.
Initially process_char is assigned put_a_char which calls putchar(c),
checks whether c is a space in which case it assigns process_char the
address of skip_blanks.
The next iteration must call skip_blanks, which returns immediately if
a blank is found. If not, c is not a blank, and the function pointer
is assigned the previous value. After this step putchar(c) is called.
Thanks, Edward.
On 20/06/2016, Rainer Weikusat <rweikusat@???> wrote:
> Edward Bartolo <edbarx@???> writes:
>
> [...]
>
>> On page Page 34 Exercise 1-9
>> "Write a program to copy its input to its output, replacing each
>> string of blanks one ore more blanks by a single blank."
>>
>> I wrote the following, tested it, and seems to work, but I think it is
>> too complicated. Any suggestions?
>>
>> --------------------------
>> #include <stdio.h>
>>
>> int main()
>> {
>> int c, d = 0;
>> while ((c = getchar()) != EOF) {
>> if (c != ' ') {
>> d = 0;
>> putchar(c);
>> }
>> if (c == ' ' && d == 0) {
>> putchar(c);
>> d = 1;
>> }
>> }
>>
>> return 0;
>> }
>> ----------------------------
>
> Conventional approach using a state variable:
>
> --------
> #include <stdio.h>
>
> int main(void)
> {
> int c, blanks;
>
> blanks = 0;
> while ((c = getchar()) != EOF) {
> if (blanks) {
> if (c == ' ') continue;
> blanks = 0;
> } else
> blanks = c == ' ';
>
> putchar(c);
> }
>
> return 0;
> }
> --------
>
> Less conventional approach using a function pointer as state variable.
>
> NB: This is really overkill here but very helpful in case of (much) more
> complicated state machines.
>
> --------
> #include <stdio.h>
>
> static void put_a_char(int);
>
> static void (*process_char)(int) = put_a_char;
>
> static void skip_blanks(int c)
> {
> if (c == ' ') return;
>
> process_char = put_a_char;
> putchar(c);
> }
>
> static void put_a_char(int c)
> {
> putchar(c);
> if (c == ' ') process_char = skip_blanks;
> }
>
>
> int main(void)
> {
> int c;
>
> while ((c = getchar()) != EOF) process_char(c);
>
> return 0;
> }
> --------
> _______________________________________________
> Dng mailing list
> Dng@???
> https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
>