Check if a character is a space - c

I'm creating an absurdly simple program in C to mess around with getchar(). The program will print out what you input until you press enter and it will guarantee that your lines are no more than 80 chars each. To do this, I keep a running count of how many characters have been entered. Once the char count hits 70, the next space encountered will cause a line break. If no space is encountered between 70-80, a line break will occur regardless. I realize this is a super naive implementation and could be optimized left and right, but remember, I'm just messing around:
while ((c = getchar()) != '\n') {
if (lineLengthCount < 70) {
putchar(c);
lineLengthCount++;
}
else if (lineLengthCount < 80 && (c == ' ')) {
printf("%c\n", c);
lineLengthCount = 0;
}
else {
printf("%c\n", c);
lineLengthCount = 0;
}
}
The problem is the c == ' ' conditional doesn't seem to be actually checking for a space. I get output like this:
fitter happier more productive comfortable not drinking too much regula
r exercise at the gym three days a week getting on better with your ass
ociate employee contemporaries at ease eating well no microwaved dinner
where I was hoping that the lines would be truncated when a space was encountered. Instead, no matter what character is entered after line 70, a new line is created. am I missing something? Does ' ' really mean any character?

while ((c = getchar()) != '\n') {
if (lineLengthCount < 70) {
putchar(c);
lineLengthCount++;
}
else if (lineLengthCount < 80 && (c == ' ')) {
printf("%c\n", c);
lineLengthCount = 0;
}
else if (lineLengthCount >= 80){
printf("%c\n", c);
lineLengthCount = 0;
}
else{
putchar(c);
lineLengthCount++;
}
}
I think this should work. That should prevent the else from executing when there are less than 80 characters but the character isn't a space.
EDIT: I realized now that instead if lineLengthCount is less than 80 but the character isn't a space it wouldn't get printed at all, so I added another else at the end to fix it.
Wouldn't this be shorter and more concise?
while ((c = getchar()) != '\n') {
putchar(c);
if((c == ' ' && lineLengthCount >= 70) || lineLengthCount >= 80){
printf("\n");
lineLengthCount = 0;
}
else
++lineLengthCount;
}

There's a problem with your conditions: if lineLengthCount is > 70 but the next character is not a space, the last else will be hit, breaking line and resetting the counter.

If you're at all unsure of what's going on, I would recommend breaking up the "if" conditional into three explicit checks:
while ((c = getchar()) != '\n') {
lineLengthCount++;
if (lineLengthCount < 70) {
putchar(c);
}
if (lineLengthCount < 80 && (c == ' ')) {
printf("%c\n", c);
lineLengthCount = 0;
}
if (lineLengthCount == 80) {
printf("%c\n", c);
lineLengthCount = 0;
}
}
If you want to see what's happening, write some debugging output in each "if" to notice when it is called.
Once it works, and you understand why, you can edit it down and combine the "ifs" ...

Using ' ' is completely valid. You could also try using the C standard library function isspace() to check if the character is a space. This function returns a boolean expression, As in:
char ch = '0';
if (isspace(ch))
//the char is a space...
By 'is space' this function actually means is any 'whitespace' character, so that includes '\n' or any other character that prints as empty space.
You could also the decimal value 32 which means the same as a space:
if (ch==32)
However for readability I would rather use the first version!

Related

The answer outputs blanks

Program task -
Enter a string, display it word for word on the screen.
The problem is that if you type a lot of spaces between words, they will show up when you check. How can this be fixed?
#include <stdio.h>
int main()
{
int inw = 0, i = 0, count = 0;
char s[10000];
printf("Print string (max 10000 sb):\n");
gets(s);
while (s[i] != '\0') {
if (s[i] != ' ' && s[i] != '\t') {
putchar(s[i]);
}
else if (s[i] == ' ') {
printf("\n");
}
i++;
}
return 0;
}
Ugly, but this gets the job done. Just need a flag to keep track of whether or not you just printed a new line. Also cleaned up unused variables and changed to using fgets
#include <stdio.h>
#include <stdbool.h>
int main()
{
int i = 0;
char s[10000];
bool justPrintedNewline = false;
printf("Print string (max 10000 sb):\n");
fgets(s, sizeof s, stdin);
while (s[i] != '\0') {
if (s[i] != ' ' && s[i] != '\t') {
putchar(s[i]);
justPrintedNewline = false;
}
else if (s[i] == ' ' && justPrintedNewline == false) {
printf("\n");
justPrintedNewline = true;
}
i++;
}
return 0;
}
Demo
You did a great job in the algorithm just fix a little thing.
You can create a flag and after space you increase the flag to 1.
Then you will know you will print just one space.
After printing " " check for a char that isn't " " for update the flag to 0.
When the flag is 1 DONT print anything just wait for another valid char.
Take care,
Ori
Only print a line-feeed when starting a word and after all is done.
Change code to:
If a space
-- print a '\n' when the prior character is a non-white-space.
Else
-- if (prior character is white-space) print a '\n'
-- print it
char prior = 'a';
while (s[i]) {
char ch = s[i];
if (ch != ' ' && ch != '\t') {
if (prior == ' ' || prior == '\t') {
putchar('\n');
}
putchar(ch);
}
prior = ch;
i++;
}
putchar('\n');
There is a bit of a trick to it: use a second, inside loop to skip past spaces and another to print words. The outer loop should only terminate if you have reached the end of the string.
while (s[i] != '\0')
{
// skip all spaces
while ((s[i] != '\0') && isspace( s[i] )) ++i;
// print the word
while ((s[i] != '\0') && !isspace( s[i] ))
{
putchar( s[i] );
}
// print the newline after a word
putchar( '\n' );
}
By the way, gets() is a really, really dangerous function. It should never have been included in the language. You are OK to use it for a homework, but in reality you should use fgets().
char s[1000];
fgets( s, sizeof(s), stdin );
The fgets() function is a bit more fiddly to use than gets(), but the above snippet will work for you.
Your other option for solving this homework is to use scanf() to read a word at a time from user input, and print it each time through the loop. I’ll leave that to you to look up. Don’t forget to specify your max string length in your format specifier. For example, a 100 char array would be a maximum 99-character string, so you would use "%99s" as your format specifier.

is there any way to stop a (c = getchar()) != EOF) if my work inside the while loop is done?

I am reading the C programming language book Dennis M. Ritchie and
trying to solve this question:
Write a program to print a histogram of
the lengths of words in
its input. It is easy to draw the histogram with the bars horizontal; a vertical
orientation is more challenging.
I think my solution works, but the problem is that if I don't press EOF, the terminal won't show the
result. I know that the condition specifies that exactly, but I am
wondering whether there is any way to make the program terminate after
reading a single line? (Sorry if my explanation of the problem is a bit shallow. Feel free to ask more.)
#include <stdio.h>
int main ()
{
int digits[10];
int nc=0;
int c, i, j;
for (i = 0; i <= 10; i++)
digits[i] = 0;
//take input;
while ((c = getchar ()) != EOF) {
++nc;
if (c == ' ' || c=='\n') {
++digits[nc-1];
//is it also counting the space in nc? i think it is,so we should do nc-1
nc = 0;
}
}
for (i = 1; i <= 5; i++) {
printf("%d :", i);
for (j = 1; j <= digits[i]; j++) {
printf ("*");
}
printf ("\n");
}
// I think this is a problem with getchar()
//the program doesn't exit automatically
//need to find a way to do it
}
You could try to make something like
while ((c = getchar ()) != EOF && c != '\n') {
and then adding a line after the while loop to account for the last word:
if (c == '\n') {
++digits[nc-1];
nc = 0;
There is also another problem inside your program. ++digits[nc-1]; is correct, however, for the wrong reason. You should make it because an array starts at zero, i.e. if you have an array of length 10, it will go from 0 to 9, so you should count the length of the words and then add one to the position of the array length - 1 (as there are no words of length zero). The problem is that you are still counting the blank spaces or the newline characters inside the length of a word, so if you have two blank spaces after a word of length 4, the program will add to the array a word of length 5 + a word of length 1. To avoid this, you should do something like this:
while ((c = getchar ()) != EOF) {
if ((c == ' ' || c == '\n' || c == '\t') && nc > 0) {
++digits[nc-1]; // arrays start at zero
nc = 0;
}
else {
++nc;
}
}

Whitespace not printing properly [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 6 years ago.
Improve this question
I have this program:
int main(void)
{
while ((c = getchar()) != EOF) {
putchar(c);
if (c == '{')
spaces += 4;
else if (c == '}')
spaces -= 4;
else if (c == '\n') {
print_spaces(spaces);
while ((c = getchar()) == ' ')
continue;
putchar(c);
}
}
}
void print_spaces(int spaces)
{
while (spaces-- > 0)
putchar(' ');
}
When run with this input:
#include<stdio.h>
int main(void)
{
printf("hello, world!\n");
}
It simply prints the exact input, instead of the desired output - desired output being:
#include<stdio.h>
int main(void)
{
printf("hello, world!\n");
}
Where have I gone wrong?
This is because the character { is being read through your while ((c = getc(f)) == ' '); line in the newline character block. That is why the condition c == '{' is never reached and spaces counter never incremented.
As far as I see, there are two things here:
The indentation depends on two character sequence \n{ to indent and \n} to de-indent. You need some way to convey what the previous or next character is (newline variable below).
} and { have slightly difference paradigm i.e. print and increment vs decrement and print (kinda like i++ vs ++i
The code below tries to capture these two points by
changing the sequence of space counter adjustment and print
using a variable to convey what the previous character was
That being said, it is very rudimentary, doesn't handle corner cases or coding style and most likely there is more elegant way to do it.
`
10 int newline = 0;
11 while ((c = getc(f)) != EOF) {
12 if (c == '}') {
13 spaces -= 4;
14 }
15 if (newline == 1) {
16 print_spaces(spaces);
17 newline = 0;
18 }
19 putchar(c);
20 if (c == '{') {
21 spaces += 4;
22 } else if (c == '\n') {
23 newline = 1;
24 while ((c = getc(f)) == ' ');
25 ungetc(c, f);
26 }
27 }
`
There is an extra ; at the end of the while condition, it is probably intentional, but very misleading: it looks like a bug. You should add a continue statement or an empty block {} to emphasize the empty statement as intentional:
while ((c = getc(f)) == ' ')
continue;
There are some problems in your approach:
you should unget the last byte if it is not EOF so it can be tested in the main loop. This the cause of your problem: { is just copied after the \n and spaces is not incremented.
You should also skip tab characters and handle newlines specially, otherwise a blank line will prevent proper indentation of the next line.
Lines that are not ; terminated should cause the continuations to be indented, potentially by a specific amount different than 4.
Here an improved code fragment that only addresses the first 2 issues:
while ((c = getc(f)) != EOF) {
putchar(c);
if (c == '{') {
spaces += 4;
} else
if (c == '}') {
if (spaces >= 4) {
spaces -= 4;
}
} else
if (c == '\n') {
/* consume all white space except newlines */
while (isspace(c = getc(f))) {
if (c == '\n')
putchar(c);
}
if (c != EOF) {
ungetc(c, f);
/* print the indentation if further code is present */
print_spaces(spaces);
}
}
}
Your code it's a bit confusing.
int printspaces = 1; // initial spaces are ignored.
while ((c = getc(f)) != EOF) {
if(printspaces == 1)
{
print_spaces(spaces);
printspaces = 0;
if(c == ' ')
while((c = getc(f)) == ' ');
}
putchar(c);
switch(c)
{
case '{':
spaces += 4;
break;
case '}':
if(spaces >= 4)
spaces -= 4;
break;
case '\n':
printspaces = 1;
break;
default:
break;
}
}

limit spaces to only one in text - c

I'm reading through K&R and the question is to: write a program to copy its input to its output, replacing each string of one or more blanks by a single blank. In my mind I think I know what I need to do, set up a boolean to know when I am in a space or not. I've attempted it and did not succeed. I've found this code and it works, I am struggling to figure out what stops the space from being written. I think I may have it but I need clarification.
#include <stdio.h>
int main(void)
{
int c;
int inspace;
inspace = 0;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(inspace == 0)
{
inspace = 1;
putchar(c);
}
}
/* We haven't met 'else' yet, so we have to be a little clumsy */
if(c != ' ')
{
inspace = 0;
putchar(c);
}
}
return 0;
}
I have created a text file to work on, the text reads:
so this is where you have been
After the 's' on 'this' the state changes to 1 because we are in a space. The space gets written and it reads the next space. So now we enter:
while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(inspace == 0)
{
inspace = 1;
putchar(c);
}
But inspace is not 0, it is 1. So what happens? Does the code skip to return 0;, not writing anything and just continues the while loop? return 0; is outside of the loop but this is the only way I can see that a value is not returned.
At this point:
if(c == ' ')
{
if(inspace == 0) // <-- here
If inspace is equal to 1, it will not execute the if body, it will jump to:
if(c != ' ') {
And as long as c == ' ' above will be false, so it will skip the if body and jump to:
while((c = getchar()) != EOF) {
And this will continue until the end of the file or until (c != ' ') evaluates to true. When c is non-space:
if(c != ' ')
{
inspace = 0;
putchar(c);
inspace is zeroed, and character is printed.
Yeah in the case you mentioned, it does not write anything and continues in the while loop and fetches the next character. If the next character is again space then it will do the same thing i.e go to next iteration without printing. Whenever it will find first non-space it will set inspace to 0 and start printing.
While loop will terminate whenever getchar will fetch EOF. Then program will return 0.
If a condition in an if-statement is not true, the following expression is not executed. This means that everything inside the corresponding brackets is skipped and the execution resumes 'after' the closing bracket.
As the following if-statement is also false, nothing is done inside this iteration of the for-loop.
When inspace is 1 and c is ' ' the expression:
inspace == 0
evaluates to 0 and the code
inspace = 1;
putchar(c);
does not get executed.
The program will then go to the next iteration of the while loop if it can, but it won't return 0 until the while loop has ended.
You can simplify the while loop to this code:
while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(inspace == 0)
{
inspace = 1;
putchar(c);
}
} else
{
inspace = 0;
putchar(c);
}
}

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