Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

K&R Exercise 1-9: output the input, replacing multiple blanks by a single blank

I've been working through some books on C trying to get my C legs (sea-legs! Get it?!). I've just finished exercise 1-9 from the K&R book, which for reference is to "write a program to copy its input to its output, replacing each string of one or more blanks by a single blank." I have a question about what's going on with my code, though--

#include <stdio.h>  //Copy input to output. Replace each string of multiple spaces with one single space  int main(int argc, char *argv[]){      int ch, lch;      // Variables to hold the current and last characters, respectively       /* This loop should 'put' the current char, then store the current char in lc,      * loop back, 'get' a new char and check if current and previous chars are both spaces.      * If both are spaces, do nothing. Otherwise, 'put' the current char      */      for(ch = getchar(); (ch = getchar()) != EOF; lch = ch){             if(ch == ' ' && lch == ' ')                     ;             else putchar(ch);     }      return 0; } 

This mostly works, except for the very first character input. For instance, if the first line input is

"This        is   a test" 

my code outputs

"his is a test".  

After dropping the very first character input, the program works consistently to meet the exercise's demands.

Can someone give me an idea of the mistake I made in my loop that's causing the issue? Any other advice is welcome as well.

like image 871
slaxx Avatar asked Jul 23 '15 21:07

slaxx


2 Answers

In the for-loop statement, you're having the bug.

for(ch = getchar(); (ch = getchar()) != EOF; lch = ch){...} 

Here, you're storing first character in ch, and then again testing if (ch!=EOF) by again reading character input.

Remove ch=getchar() from the initialisation statement; let it be in the second part.

for(;(ch = getchar()) != EOF; lch = ch){...} 

Also, you will have to initialise your lch before making it run as lch will not have any value stored in it before making comparison in the first iteration of the loop. So, let lch=0 be initialised first.

for(lch = 0; (ch = getchar()) != EOF; lch = ch){...} 

Consider enabling warnings in your compiler, it would probably detect and warn about this issue, so you could fix it.

The above would solve your problem.

(Thanks to Blue Moon and hyde for helping me modify the answer.)

like image 169
Am_I_Helpful Avatar answered Oct 11 '22 18:10

Am_I_Helpful


You call getchar twice in the loop initialization:

 for(ch = getchar(); (ch = getchar()) != EOF; lch = ch) 

Instead, you should call it once in the initialization (to get the first char) and then in the end of the iteration (to get the next characters):

int ch, lch = 0; // avoid using uninitialized variable  for(ch = getchar(); ch != EOF; lch = ch) {         if(ch == ' ' && lch == ' ')                 ;         else putchar(ch);          ch = getchar(); }  

UPD: Thanks Blue Moon and shekhar suman for pointing out the issue with lch

like image 38
alexo_o Avatar answered Oct 11 '22 17:10

alexo_o