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 <[email protected]> wrote:
> Edward Bartolo <[email protected]> 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
> [email protected]
> https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
>
_______________________________________________
Dng mailing list
[email protected]
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng

Reply via email to