0

I've started studying "The ANSI C Programming Language" by Dennis Ritchie and Brian W.Kernighan. So far I've just learned getchar(),putchar(),while, for, if. There is an exercise that I have to do only using what I've learned by now. The above are the only things I know. Here's the exercise as it appears in the book:

Exercise 1-9. Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.

I know C#, Pascal, Objective-C and some Java but I cannot understand how this problem can be solved without using arrays. I know arrays but as the author has not covered arrays yet I assume I must not use them. Arrays are taught in the next chapters.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206

4 Answers4

2

Implementing Nikolai's solution, as it might be easier to understand in code,

#include <stdio.h>
#include <stdbool.h> /* C99, but a good idea to use nonetheless */

int main() {
    bool was_space; /* state variable */
    char c; /* one-character buffer */

    while ( ( c = getchar() ) != EOF ) {
        if ( ! was_space || c != ' ' ) putchar( c );
        was_space = c == ' ';
    }
    return 0;
}

http://ideone.com/LLmBh

If you really want to avoid bool, you can just use int instead.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
1

Print the first whitespace (blank) character you see, skip the rest. That means having a boolean variable that is set to false as soon you see a non-whitespace character, and set to true when you hit and print first whitespace. Do not print if that variable is true. Kind of a two-state "state machine".

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • What have you tried so far? If you know Objective-C, you should probably have an idea that `int`s could be treated as booleans in C. I also don't really get where you want to use arrays. You get a `char` of input, compare it to "blank", and depending on your state print (output) your input, then repeat. – Nikolai Fetissov May 18 '12 at 12:22
  • I know what boolean is but so far there's no word about booleans. So I cannot use them either. – Mikayil Abdullayev May 18 '12 at 12:25
  • I thought I would treat the the whole input as an array of chars and iterate through them. This is where I would use arrays. – Mikayil Abdullayev May 18 '12 at 12:27
  • Then just keep previous char to check if you had "blank" on the last iteration. – Nikolai Fetissov May 18 '12 at 12:27
1

Example based on my comment:

#include <stdio.h>

int main()
{
    int previous_char = 0;
    int latest_char;

    while ((latest_char = getchar()) != EOF)
    {
        if (' ' != previous_char || ' ' != latest_char)
        {
            putchar(latest_char);
        }
        previous_char = latest_char;
    }
    return 0;
}

Note that getchar() returns, and putchar() accepts, an int, not char.

hmjd
  • 120,187
  • 20
  • 207
  • 252
0

After some time I realised that I'd misunderstood the question and this misunderstanding was because I did not fully understand the mechanism of getchar() and putchar() functions. At first I thought I had to take the whole string and then itearte through it. But then I understood that "while ((input_char = getchar()) != EOF)" does some kind of iteration (maybe a simulation of iteration, don't know for sure). After that the rest is just a normal logic. When you look at the code you'll probably notice that I did not use if-else pattern. That's simply because "If" is the only thing that I've got so far and I should not use anything else that I know from other programming languages(although I'm sure if-else is found in any language). We have not seen &&,||,boolean either. And also I used ++counter instead of counter++. That's also because we have not yet come to post increment. I know it's the simplest logic that everyone knows but I wanted to share anyway.

#include <stdio.h>
int main()
{
   int input_char;
   int counter = 0;
   while ((input_char = getchar()) != EOF)      
   {
     if (input_char == ' ')
     {
        ++counter;
        if (counter == 1)
          putchar(input_char);
     }

     if (input_char != ' ')
     {
        putchar(input_char);
        counter = 0;
     }
   }
  return 0;
}          
Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206