Why is my wc implementation giving wrong word count? - c

Here is a small code snippet.
while((c = fgetc(fp)) != -1)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
else
{
if(c == ' ' && prevC != ' ') wCount++; // word count
}
prevC = c; // previous character equals current character. Think of it as memory.
}
Now when I run wc with the file containing this above snippet code(as is), I am getting 48 words, but when I use my program on same input data, I am getting 59 words.
How to calculate word count exactly like wc does?

You are treating anything that isn't a space as a valid word. This means that a newline followed by a space is a word, and since your input (which is your code snippet) is indented you get a bunch of extra words.
You should use isspace to check for whitespace instead of comparing the character to ' ':
while((c = fgetc(fp)) != EOF)
{
cCount++;
if (c == '\n')
lCount++;
if (isspace(c) && !isspace(prevC))
wCount++;
prevC = c;
}

There is an example of the function you want in the book: "Brian W Kernighan And Dennis M Ritchie: The Ansi C Programming Language". As the author says: This is a bare-bones version of the UNIX program wc. Altered to count only words is like this:
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* nw counts words in input */
main()
{
int c, nw, state;
state = OUT;
nw = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d\n", nw);
}

Instead of checking for spaces only you should check for escape sequences like \t \n space and so on.
This will give the correct results.
You can use isspace() from <ctype.h>
Change the line
if(c == ' ' && prevC != ' ') wCount++;
to
if(isspace(c) && !(isspace(prevC)) wCount++;
This would give the correct results.
Don't forget to include <ctype.h>

You can do:
int count()
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0;
char c;
FILE *fp = fopen ("text", "r");
if (fp == NULL)
{
printf ("Failed to open file\n");
return -1;
}
while((c = fgetc(fp)) != EOF)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
printf ("line : %u\n", lCount);
printf ("word : %u\n", wCount);
printf ("char : %u\n", cCount);
return 0;
}

Related

Counting the number of characters, words, lines in a text file

I have to check the number of words, characters, and lines in a file. I am getting the number of lines and words one more than it should actually be. What is wrong with my program?
#include <stdio.h>
int main()
{
FILE *number2;
number2 =fopen("Part2.txt", "r");
//open the file to read
if (number2 == NULL)
{
return 4;
}
char cha;
int character = 0;
int word = 0;
int lne = 0;
while ((cha = fgetc(number2)) != EOF)
// till end of file
{
//character++;
// if (cha == '\n' || cha == '\0')
//lne++;
while ((cha = fgetc(number2))!= EOF)
{
character++;
//new characters
if (cha == '\n' || cha == '\0')
lne++;
// new lines
if (cha == ' ' || cha == '\t' || cha == '\n' || cha == '\0')
word++;
//new words--- though the professor talks about only whitespace this is proper way
}
if (character > 0)
{
word++;
lne++;
}
// increasing the worlds and lines for last word and printing
printf("\n");
printf("Total number of characters = %d\n", character);
printf("Total number of words = %d\n", word-1);
printf("Total number of lines = %d\n", lne-1);
// decreasing by 1 in word and line because there is one extra line and this runs the code perfectly
fclose (number2);
//closing the file though professor didn't ask for smooth functioning of programms
return 0;
}
}

program to count commented characters and words in a C file

I have to count characters and word in comment of a C file, for both single line comments and blocked comment. Here's what I have:
#include <stdio.h>
#define IN = 1
#define OUT = 0
main() {
int c, nc;
nc = 0;
while ((c = getchar()) != EOF) {
if (c == '/') {
if (getchar() == '/')
while (getchar() != '\n')
++nc;
}
}
if (c == '/') {
if (getchar() == '*')
while (getchar() != '/')
++nc;
}
printf("Character Counts: %d\n", nc);
}
It works for every single line comment (//), but it skips the blocked comments (/*...*/). I feel like it never enter the if block for the blocked comment. Much appreciate!
There are multiple problems in your code:
You must specify int as the return type of the main function. The syntax in the question is obsolete.
The definitions of IN and OUT are incorrect. You should either use
#define IN 1
#define OUT 0
or
enum { IN = 1, OUT = 0 };
The first loop consumes all the bytes in standard input, you are at the end of file, so the tests for /*...*/ comments never produce anything.
loops such as while (getchar() != '\n') can run forever if the byte tested is not found before the end of file.
You cannot test // and /*...*/ comments separately as one can hide the other:
//* this is a line comment that does not start a C style one
/* this comment contains a // but stops here */ return 0;
Note also that you should parse C strings and character constants as they may contain // and or /* sequences that do not start a comment.
For a complete solution, you should also handle escaped newlines. Here are some pathological examples:
// this is a line comment that extends \
on multiple \
lines (and tricks the colorizer)
/\
* this is a C comment, but the colorizer missed it *\
/
This problem is non-trivial to solve in the general case, but you can start with simple cases.
Here is a modified version:
#include <stdio.h>
int main() {
int c, cc, nc = 0;
while ((c = getchar()) != EOF) {
if (c == '/') {
if ((cc = getchar()) == '/') {
while ((c = getchar()) != '\n')
nc++;
} else
if (cc == '*') {
while ((cc = getchar()) != EOF) {
if (cc == '*') {
if ((cc = getchar()) == '/')
break;
ungetc(cc, stdin);
}
nc++;
}
}
}
}
printf("Character Counts: %d\n", nc);
return 0;
}
I added code to count the words. It works on few occasions, but it behaves weird when I have space after the slash. For example, // comment... Most of the time, the word count is off by 1.
#include<stdio.h>
#define IN 1
#define OUT 0
int main() {
int c, cc, nc = 0;
int state;
int nw = 0;
state = OUT;
while ((c = getchar()) != EOF) {
if (c == '/') {
if ((cc = getchar()) == '/') {
while ((c = getchar()) != '\n'){
nc++;
if (c == ' ' || c == '\t')
state = OUT;
else if (state == OUT){
state = IN;
nw++;
}
}
}
else if (cc == '*') {
while ((cc = getchar()) != EOF) {
if (cc == ' ' || cc == '\t')
state = OUT;
else if (state == OUT){
state = IN;
nw++;
}
if (cc == '*') {
if ((cc = getchar()) == '/')
break;
ungetc(cc, stdin);
}
nc++;
}
}
}
}
printf("Character Counts: %d\n", nc);
printf("Word Counts: %d\n", nw);
return 0;
}
program to count commented characters and words in a C file
it skips the blocked comments (/.../)
I recommend, at a minimum, to parse code and look for 5 states: normal, in a // comment, in a /* comment, in a "" string literal, in a '' character constant.
// pseudo code
while ((ch = getchar()) != EOF) {
if ch == '/' and next == '/', process `//` comment until end-of-line
elseif ch '/' and next == '*', process `/*` comment until `*/`
elseif ch '"', process string until " (but not \")
elseif ch ''', process constant until ' (but not \')
else process normally
}
To look at the next character, call getchar() and then ungetc() if not as expected.

Wordcount in C that supports singlar letter input [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have some issues with 'wordcount' counting correctly as it missed singular letter such as 'I'.
Essentially if space between a character/symbol or standalone character/symbol will counts a word count.
#include <stdio.h>
int main()
{
int wordcount;
int ch;
char lastch = -1;
wordcount = 0;
while ((ch = getc(stdin)) != EOF) {
if (ch == ' ' || ch == '\n')
{
if (!(lastch == ' ' && ch == ' '))
{
wordcount++;
}
}
lastch = ch;
}
printf("The document contains %d words.", wordcount);
}
You are over-complicating your conditional tests. If I understand your purpose, the only thing you are concerned with is if lastch != ' ' and either (ch == ' ' || ch == '\n').
Additionally, getchar returns type int. Therefore, ch should be type int to properly detect EOF on all systems.
Simplifying with those changes, you could do something similar to:
#include <stdio.h>
int main (void) {
int wordcount = 0,
lastch = 0, /* just initialize to zero */
ch; /* ch should be an int */
while ((ch = getc (stdin)) != EOF) {
if (lastch && lastch != ' ' && (ch == ' ' || ch == '\n'))
wordcount++;
lastch = ch;
}
if (lastch != '\n') /* handle no '\n' on final line */
wordcount++;
printf ("The document contains %d %s.\n",
wordcount, wordcount != 1 ? "words" : "word");
return 0;
}
Example Use/Output
$ echo " " | ./bin/wordcnt
The document contains 0 words.
$ echo " t " | ./bin/wordcnt
The document contains 1 word.
$ echo " t t " | ./bin/wordcnt
The document contains 2 words.
Note: in order to protect against a corner-case of a file not containing a POSIX eof (e.g. '\n' at the end of the file), you would need to add an additional flag that at least one character was found and check lastch in combination after you exit the loop, e.g.
#include <stdio.h>
int main (void) {
int wordcount = 0,
lastch = 0, /* just initialize to zero */
ch, /* ch should be an int */
c_exist = 0; /* flag at least 1 char found */
while ((ch = getc (stdin)) != EOF) {
if (lastch && lastch != ' ' && (ch == ' ' || ch == '\n'))
wordcount++;
if (ch != ' ' && ch != '\n') /* make sure 1 char found */
c_exist = 1;
lastch = ch;
}
if (c_exist && lastch != '\n') /* handle no '\n' on final line */
wordcount++;
printf ("The document contains %d %s.\n",
wordcount, wordcount != 1 ? "words" : "word");
return 0;
}
Corner-case Example
$ echo -n " t" | ./bin/wordcnt
The document contains 1 word.

C: segmentation fault

I've created this function to read a word. I got segmentation fault and I can't find the problem. Here's what I've done.
void LeeCaracter(FILE * fp, char * s)
{
char c;
int i = 0;
c = fgetc(fp);
while(c==' ' || c=='\t' || c=='\n')
c = fgetc(fp);
while(c!=' ' && c!='\n')
{
s[i] = c;
i++;
c = fgetc(fp);
}
s[i] = '\0';
}
s is a pointer parameter, as I have to use it later. Is it correct to write it just with one *? Thanks for your help!
*And what about if I wanted to know the character that follows the word(' ' or '\n')? I added this after the while loop:
"printf("%c",c);"
but it doesn't print anything. Any ideas?
Consider:
while(c==' ' || c=='\t' || c=='\n')
c = fgetc(fp);
So, at this point, two things that c is not are ' ' and '\n'. Then:
while(c!=' ' && c!='\n')
{
s[i] = c;
i++;
}
Since the value of c does not change in the loop, the while condition is always true. Meaning that pretty quickly, s[i] will go out of bounds. You need to check against the length of s, probably by getting that passed in as a parameter (not to mention, rethink your algorithm a bit -- probably you want to fgetc more inside the loop).
You have to make sure that the 's' has enough space for containing a word with maximum characters in the input file. Then you need to make sure that you check for 'End Of File'. Here is a working version. I hope it works for you as well.
#include <stdio.h>
void LeeCaracter(FILE * fp, char * s)
{
char c;
int i = 0;
c = fgetc(fp);
if (feof(fp)) return;
while (c == ' ' || c == '\t' || c == '\n')
c = fgetc(fp);
while (!feof(fp) && (c != ' ' && c != '\n')) {
s[i++] = c;
c = fgetc(fp);
}
s[i] = '\0';
printf("%s\n", s);
}
int main(void)
{
char s[128]; /* assuming no word is larger than this size */
FILE *fp = fopen("/usr/share/dict/words", "r");
while (!feof(fp)) {
LeeCaracter(fp, s);
}
return 0;
}

K&R Exercise 1-9 (C)

"Write a program to copy its input to
its output, replacing each string of
one or more blanks by a single blank."
I'm assuming by this he means input something like...
We(blank)(blank)(blank)go(blank)to(blank)(blank)(blank)the(blank)mall!
... and output it like:
We(blank)go(blank)to(blank)the(blank)mall!
This is probably easier than I'm making it out to be, but still, I can't seem to figure it out. I don't really want the code... more so pseudo code.
Also, how should I be looking at this? I'm pretty sure whatever program I write is going to need at least one variable, a while loop, a couple if statements, and will use both the getchar() and putchar() functions... but besides that I'm at a loss. I don't really have a programmers train of thought yet, so if you could give me some advice as to how I should be looking at "problems" in general that'd be awesome.
(And please don't bring up else, I haven't got that far in the book so right now that's out of my scope.)
Look at your program as a machine that moves between different states as it iterates over the input.
It reads the input one character at a time. If it sees anything other than a blank, it just prints the character it sees. If it sees a blank, it shifts to a different state. In that state, it prints one blank, and then doesn't print blanks if it sees them. Then, it continues reading the input, but ignores all blanks it sees--until it hits a character that isn't a blank, at which point it shifts back to the first state.
(This concept is called a finite state machine, by the way, and a lot of theoretical computer science work has gone into what they can and can't do. Wikipedia can tell you more, though in perhaps more complicated detail than you're looking for. ;))
Pseudo code
while c = getchar:
if c is blank:
c = getchar until c is not blank
print blank
print c
C
You can substitute use of isblank here if you desire. It is unspecified what characters contrive blank, or what blank value is to be printed in place of others.
After many points made by Matthew in the comments below, this version, and the one containing isblank are the same.
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ');
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
Since relational operators in C produce integer values 1 or 0 (as explained earlier in the book), the logical expression "current character non-blank or previous character non-blank" can be simulated with integer arithmetic resulting in a shorter (if somewhat cryptic) code:
int c, p = EOF;
while ((c = getchar()) != EOF) {
if ((c != ' ') + (p != ' ') > 0) putchar(c);
p = c;
}
Variable p is initialized with EOF so that it has a valid non-blank value during the very first comparison.
This is what I got:
while ch = getchar()
if ch != ' '
putchar(ch)
if ch == ' '
if last_seen_ch != ch
putchar(ch)
last_seen_ch = ch
Same explanation with Matt Joiner's, but this code does not use break.
int c;
while ((c = getchar()) != EOF)
{
if (c == ' ') /* find a blank */
{
putchar(' '); /* print the first blank */
while ((c = getchar()) == ' ') /* look for succeeding blanks then… */
; /* do nothing */
}
if (c != EOF) /* We might get an EOF from the inner while-loop above */
putchar(c);
}
I worked really hard at finding a solution that used only the material that has already been covered in the first part of the first chapter of the book. Here is my result:
#include <stdio.h>
/* Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank. */
main()
{
int c;
while ((c = getchar()) != EOF){
if (c == ' '){
putchar(c);
while ((c = getchar()) == ' ')
;
}
if(c != ' ')
putchar(c);
}
}
Here is how I think of the algorithm of this exercise, in pseudo-code:
define ch and bl (where bl is initially defined to be 0)
while ch is = to getchar() which is not = to end of file
do the following:
if ch is = to blank and bl is = 0
--> output ch and assign the value 1 to bl
else --> if ch is = to blank and bl is = 1
--> do nothing
else --> output ch and assign the value 0 to bl
Example implementation in C:
#include <stdio.h>
#include <stdlib.h>
main() {
long ch,bl=0;
while ((ch=getchar()) != EOF)
{
if (ch == ' ' && bl == 0)
{
putchar(ch);
bl=1;
} else if (ch == ' ' && bl == 1) {
// no-op
} else {
putchar(ch);
bl=0;
}
}
return 0;
}
I wrote this and seems to be working.
# include <stdio.h>
int main ()
{
int c,lastc;
lastc=0;
while ((c=getchar()) != EOF)
if (((c==' ')+ (lastc==' '))<2)
putchar(c), lastc=c;
}
#include <stdio.h>
int main()
{
int c;
while( (c = getchar( )) != EOF )
{
if (c == ' ')
{
while ((c = getchar()) == ' ');
putchar(' ');
putchar(c);
}
else
putchar(c);
}
return 0;
}
#include <stdio.h>
main()
{
int c, numBlank=0 ;
while((c= getchar())!=EOF)
{
if(c ==' ')
{
numBlank ++;
if(numBlank <2)
{
printf("character is:%c\n",c);
}
}
else
{
printf("character is:%c\n",c);
numBlank =0;
}
}
}
First declare two variables character and last_character as integers.when you have not reach the end of the file( while(character=getchar() != EOF ) do this;
1. If character != ' ' then
print character
last_character = character
2. If character == ' '
if last_character ==' '
last character = character
else print character
Using the constraints of not using else or and operators. This code only prints a blank when the blank variable is equal to 1 and the only way to reset the counter is by typing something other than a blank. Hope this helps:
include
/* Write a program that replaces strings of blanks with a single blank */
void main(){
int c, bl;
bl = 0;
while((c = getchar()) != EOF){
if(c == ' '){
++bl;
if(bl == 1){
putchar(' ');
}
}
if(c != ' '){
putchar(c);
bl = 0;
}
}
}
Many others have already used the last character logic in their code, but perhaps the following version is easier to read:
int c, prevchar;
while ((c = getchar()) != EOF) {
if (!(c == ' ' && prevchar == ' ')) {
putchar(c);
prevchar = c;
}
}
#include <stdio.h>
main() {
int input, last = EOF;
while ((input = getchar()) != EOF) {
if (input == ' ' && last == ' ') continue;
last = input;
putchar(input);
}
}
I am at the same point in the book. and my solution goes with making a count++ if blank is found and making the count back to zero if anything other than blank is found.
For if statement I put another another check to check value of count (if zero) and then print.
Though at this point of learning I shouldn't be concern about efficiency of two methods but which one is efficient a.) Accepted solution here with while inside while or b.) the one I suggested above.
My code goes like below:
#include <stdio.h>
main()
{
int count=0,c;
for( ; (c=getchar())!=EOF; )
{
if(c==' ')
{
if(count==0)
{
putchar(c);
count++;
}
}
if(c!=' ')
{
putchar(c);
count=0;
}
}
}
#include <stdio.h>
main()
{
int CurrentChar, LastChar;
LastChar = '1';
while ((CurrentChar = getchar()) != EOF)
{
if (CurrentChar != ' ')
{
putchar(CurrentChar);
LastChar = '1';
}
else
{
if (LastChar != ' ')
{
putchar(CurrentChar);
LastChar = ' ';
}
}
}
}
a way to make it easier for the new people are stuck on this book
(by not knowing any thing then what brought up until page 22 in K&R).
credits to #Michael , #Mat and #Matthew to help me to understand
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) /* state of "an input is not EOF" (1) */
{
if (c == ' ') /* "blank has found" -> change the rule now */
{
while ((c = getchar ()) == ' '); /* as long you see blanks just print for it a blank until rule is broken (2) */
putchar(' ');
}
putchar(c); /* either state (2) was broken or in state (1) no blanks has been found */
}
}
1.Count the number of blanks.
2.Replace the counted number of blanks by a single one.
3.Print the characters one by one.
<code>
main()
{
int c, count;
count = 0;
while ((c = getchar()) != EOF)
{
if (c == ' ')
{
count++;
if (count > 1)
{
putchar ('\b');
putchar (' ');
}
else putchar (' ');
}
else
{
putchar (c);
count = 0;
}
}
return;
}
</code>
#include <stdio.h>
int main(void)
{
long c;
long nb = 0;
while((c = getchar()) != EOF) {
if(c == ' ' || c == '\t') {
++nb;
} else {
if(nb > 0) {
putchar(' ');
nb = 0;
}
putchar(c);
}
}
return 0;
}
To do this using only while loops and if statements, the trick is to add a variable which remembers the previous character.
Loop, reading one character at a time, until EOF:
If the current character IS NOT a space:
Output current character
If the current character IS a space:
If the previous character WAS NOT a space:
Output a space
Set previous character to current character
In C code:
#include <stdio.h>
main()
{
int c, p;
p = EOF;
while ((c = getchar()) != EOF) {
if (c != ' ')
putchar(c);
if (c == ' ')
if (p != ' ')
putchar(' ');
p = c;
}
}
I am also starting out with the K&R textbook, and I came up with a solution that uses only the material which had been covered up until that point.
How it works:
First, set some counter 'blanks' to zero. This is used for counting blanks.
If a blank is found, increase the counter 'blanks' by one.
If a blank is not found, then first do a sub-test: is the counter 'blanks' equal or bigger than 1? If yes, then first, print a blank and after that, set the counter 'blanks' back to zero.
After this subtest is done, go back and putchar whatever character was not found to be a blank.
The idea is, before putcharing a non-blank character, first do a test to see, if some blank(s) were counted before. If there were blanks before, print a single blank first and then reset the counter of blanks. That way, the counter is zero again for the next round of blank(s). If the first character on the line is not a blank, the counter couldn't have increased, hence no blank is printed.
One warning, I haven't gone very far into the book, so I'm not familiar with the syntax yet, so it's possible that the {} braces might be written in different places, but my example is working fine.
#include <stdio.h>
/* Copy input to output, replacing each string of one or more blanks by a single blank. */
main()
{
int c, blanks;
blanks = 0;
while ((c = getchar()) != EOF) {
if (c != ' ') {
if (blanks >= 1)
printf(" ");
blanks = 0;
putchar(c); }
if (c == ' ')
++blanks;
}
}
Like many other people, I am studying this book as well and found this question very interesting.
I have come up with a piece of code that only uses what has been explained before the exercice (as I am not consulting any other resource but just playing with the code).
There is a while loop to parse the text and one if to compare the current character to the previous one.
Are there any edge cases where this code would not work ?
#include <stdio.h>
main() {
// c current character
// pc previous character
int c, pc;
while ((c = getchar()) != EOF) {
// A truthy evaluation implies 1
// (learned from chapter 1, exercice 6)
// Avoid writing a space when
// - the previous character is a space (+1)
// AND
// - the current character is a space (+1)
// All the other combinations return an int < 2
if ((pc == ' ') + (pc == c) < 2) {
putchar(c);
}
// update previous character
pc = c;
}
}
for(nb = 0; (c = getchar()) != EOF;)
{
if(c == ' ')
nb++;
if( nb == 0 || nb == 1 )
putchar(c);
if(c != ' ' && nb >1)
putchar(c);
if(c != ' ')
nb = 0;
}
Here is my answer, I am currently in the same spot you were years ago.
I used only the syntax taught until this point in the books and it reduces the multiple spaces into one space only as required.
#include<stdio.h>
int main(){
int c
int blanks = 0; // spaces counter
while ((c = getchar()) != EOF) {
if (c == ' ') { // if the character is a blank
while((c = getchar()) == ' ') { //check the next char and count blanks
blanks++;
// if(c == EOF){
// break;
// }
}
if (blanks >= 0) { // comparing to zero to accommodate the single space case,
// otherwise ut removed the single space between chars
putchar(' '); // print single space in all cases
}
}
putchar(c); //print the next char and repeat
}
return 0;
}
I removed the break part as it was not introduced yet in the book,hope this help new comers like me :)
This is a solution using only the techniques described so far in K&R's C. In addition to using a variable to achieve a finite state change for distinguishing the first blank space from successive blank spaces, I've also added a variable to count blank spaces along with a print statement to verify the total number. This helped me to wrap my head around getchar() and putchar() a little better - as well as the scope of the while loop within main().
// 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.
#include <stdio.h>
int main(void)
{
int blank_state;
int c;
int blank_count;
printf("Replace one or more blanks with a single blank.\n");
printf("Use ctrl+d to insert an EOF after typing ENTER.\n\n");
blank_state = 0;
blank_count = 0;
while ( (c = getchar()) != EOF )
{
if (c == ' ')
{
++blank_count;
if (blank_state == 0)
{
blank_state = 1;
putchar(c);
}
}
if (c != ' ')
{
blank_state = 0;
putchar(c);
}
}
printf("Total number of blanks: %d\n", blank_count);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int c, flag=0;
while((c=getchar()) != EOF){
if(c == ' '){
if(flag == 0){
flag=1;
putchar(c);
}
}else{
flag=0;
putchar(c);
}
}
return 0;
}
I hope this will help.
/*a program that copies its input to its output, replacing each string of one or more blanks by a single blank*/
#include <stdio.h>
#include<stdlib.h>
int main(void)
{
double c;
char blank = ' ';
while((c = getchar()) != EOF)
{
if(c == ' ')
{
putchar(c);
while(( c = getchar() )== ' ')
{
if(c != ' ')
break;
}
}
if(c == '\t')
{
putchar(blank);
while((c = getchar()) == '\t')
{
if(c != '\t')
break;
}
}
putchar(c);
}
return 0;
}
// K & R Exercise 1.9
// hoping to do this with as few lines as possible
int c = 0, lastchar = 0;
c = getchar();
while (c != EOF) {
if (lastchar != ' ' || c != ' ') putchar(c);
lastchar=c;
c=getchar();
}
Considering what's asked in the question, I have also made sure that the program runs smooth in case of various tabs, spaces as well as when they're clubbed together to form various combinations!
Here's my code,
int c, flag = 1;
printf("Enter the character!\n");
while ((c = getchar()) != EOF) {
if (c == ' '||c == '\t') {
c=getchar();
while(c == ' '|| c == '\t')
{
c = getchar();
}
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
Feel free to run all test cases using various combinations of spaces and tabs.
Solution1: as per topics covered in the k&R book:
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != EOF)
{
if (c == ' ')
{while ( getchar() == ' ' )
; // ... we take no action
}
putchar(c);
}
return 0;
}
Solution2 : using program states:
int main()
{
int c, nblanks = 0 ;
while ((c = getchar()) != EOF)
{
if (c != ' ')
{ putchar(c);
nblanks = 0;}
else if (c==' ' && nblanks == 0) // change of state
{putchar(c);
nblanks++;}
}
return 0;
}
Solution3 : based on last seen char
int main()
{
int c, lastc = 0;
while ((c = getchar()) != EOF)
{
if ( c != ' ')
{putchar(c);}
if (c == ' ')
{
if (c==lastc)
;
else putchar(c);
}
lastc = c;
}
return 0;
}

Resources