Program that replaces multiple blanks and tabs into single blank and tab - c

I'm reading The C Programming Language.
I have used this program to replace multiple blanks to single blanks but I want to replace multiple blanks and tabs into single blank and tab in same time
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
putchar(c);
while ((c = getchar()) == ' ')
;
}
if (c != ' ')
putchar(c);
}
}

Your program is almost correct: there is a problem if the file ends with a space as the inner loop while ((c = getchar()) == ' '); will stop and the end of file leaving c with the value EOF, which will be output as the byte 0xFF (if EOF is defined as -1, the most common value).
You should check for this possibility:
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
putchar(c);
while ((c = getchar()) == ' ')
continue;
if (c != EOF)
break;
}
putchar(c);
}
return 0;
}
It is unclear what you mean by replace multiple blanks and tabs into single blank and tab.
To replace both spaces and TABs with a single space, you just need to test both byte values:
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\t') {
putchar(' ');
while ((c = getchar()) == ' ' || c == '\t')
continue;
if (c != EOF)
break;
}
putchar(c);
}
return 0;
}
Conversely, if you mean to replace multiple spaces with a single space and multiple TABs with a single TAB, a different approach can be used:
#include <stdio.h>
int main() {
int c, last = EOF;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\t') {
if (c == last)
continue;
}
putchar(c);
last = c;
}
return 0;
}
This approach can be used for the original problem and produces simpler code:
#include <stdio.h>
int main() {
int c, last = EOF;
while ((c = getchar()) != EOF) {
if (c != ' ' || c != last) {
putchar(c);
last = c;
}
}
return 0;
}

Related

replacing two spaces with an 'x' using only putchar and getchar

This program should replace two spaces with an x, using only getchar() and putchar(). My approach was to store the space in a buffer and then print it out. But the program replaces every space with an x. Can someone help me out?
#include <stdio.h>
#define MAX 2
char arr[MAX];
int ret = 0;
char second;
int main()
{
for(int i=0; ; )
{
if ( (ret = getchar())!= EOF)
{
putchar(ret);
}
if(ret==' '&&second==' ')
{
arr[i]=ret;
arr[i]='x';
putchar(arr[i]);
}
}
return 0;
}
When you read a character, first check if it's a space. If not, just print it. If it is read another character, then if the second is a space print an x otherwise print a space and the character you just read.
int c;
while ((c = getchar()) != EOF) {
if (c != ' ') {
putchar(c);
} else {
c = getchar();
if (c == EOF) {
putchar(' ');
} else if (c == ' ') {
putchar('x');
} else {
putchar(' ');
putchar(c);
}
}
}

Counting Tab, Blank and Newlines in C [duplicate]

This question already has answers here:
How do curly braces and scope wоrk in C?
(4 answers)
What does a 'for' loop without curly braces do?
(4 answers)
Closed 5 years ago.
The code won't work. The counting results of b(blank) and t(tab) are both 0. I think there maybe the issue with my condition set up. Can anyone help?
main()
{
int c, b, t, nl;
nl = 0;
b = 0;
t = 0;
while ((c = getchar()) != EOF)
if (c == '\n')
++nl;
if (c == ' ')
++b;
if (c == ' ')
++t;
printf("%d\t%d\t%d\n", nl, b, t);
}
The code as posted by you is equivalent to:
main()
{
int c, b, t, nl;
nl = 0;
b = 0;
t = 0;
while ((c = getchar()) != EOF) //your code is equivalent to this
{
if (c == '\n')
++nl;
} //the following if conditions fall outside the loop
if (c == ' ')
++b;
if (c == '\t')//tab is represented by \t not by ' '
++t;
printf("%d\t%d\t%d\n", nl, b, t);
}
You need to add braces around your while loop i.e.
int main(void)
{
int c, b, t, nl;
nl = 0;
b = 0;
t = 0;
while ((c = getchar()) != EOF){
if (c == '\n')
++nl;
if (c == ' ')
++b;
if (c == '\t')
++t;
}
printf("%d\t%d\t%d\n", nl, b, t);
return 0;
}
Another important thing: main() is not standard C
how does int main() and void main() work
Two spaces is not char, it is string.
Try this:
if(c == ' ')
b++;
if(c == '\t')
t++;
if(c == '\n')
nl++;

How do I replace more than one blank in c programming with one blank?

I am new to programming, and I have decided to start with c. I am using the book of K & R, and there is this exercise, which asks to write a program that copies input to output , replacing one or more blanks with a single blank. However when I wrote my program (and I am sure it's not correct but that's okay, since I am here to learn) I was wondering what I am doing wrong. Also a note: when I type my name with 3 blanks it's reduced to two, but when using two or one blank(s) nothing happens. Code posted below
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c; // getchar value
int blanks = 0; // counting the amount of blanks. If more than one then replace with blanks_2
char blanks_2 = ' '; //character value for replacement in case blanks is more than one
printf("Enter your name please\n");
while((c = getchar()) != EOF){
if(c == ' '){
++blanks;
if (blanks >= 1){
putchar(blankos); }
}
if(c >= 'a' && c <= 'z'){
putchar(c);
}
if (c >= 'A' && c <= 'Z'){
putchar(c);
}
}
return 0;
}
You do not need to count the exact number of blanks. Once you find a blank "raise a flag" that blank is found. When you revisit a non-blank character print a blank and turn the flag back to 0. Moreover, insert "continue" statements in your code to avoid unecessary checks:
int main(void)
{
int c; // getchar value
int blankfound = 0;
printf("Enter your name please\n");
while((c = getchar()) != EOF){
if(c == ' '){
blankfound = 1;
continue;
}
if(c >= 'a' && c <= 'z'){
if (blankfound == 1)
{
putchar(' ');
blankfound = 0;
}
putchar(c);
continue;
}
if (c >= 'A' && c <= 'Z'){
if (blankfound == 1)
{
putchar(' ');
blankfound = 0;
}
putchar(c);
continue;
}
}
return 0;
}
I guess you are trying to write a program that get something like this as input:
John David Doe
and display this as output:
John David Doe
by removing all extra spaces. This should work:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c; // getchar value
int blanks = 0; // counting the amount of blanks. If more than one then replace with blanks_2
printf("Enter your name please\n");
while((c = getchar()) != EOF)
{
if(c == ' ')
{
// count blanks
++blanks;
if (blanks==1)
putchar(c); // display only the 1st blank
}
if(isalpha(c))
{
putchar(c);
blanks=0; // reset blanks counter as c is an alpha character
}
}
return 0;
}
Many of these learner code assignments work on the idea of function based on a previous character.
Consider the following layout
int previous = something();
while ((c = getchar()) != EOF) {
do_stuff(previous, c);
previous = c;
}
For OP, that would be: If the character is not a space or the previous character was not a space, print it.
printf("Enter your name please\n");
int previous = 0;
int c;
while((c = getchar()) != EOF) {
if ((c != ' ') || (previous != ' ')) {
putchar(' ');
}
previous = c;
}
Simplifying the algorithm helps one see flaws like below. blanks is not reset when a letter appears. It prints when 1 or more spaces encountered.
if(c == ' '){
++blanks;
if (blanks >= 1){
putchar(blankos); }
}
if(c >= 'a' && c <= 'z'){
putchar(c);
}
if (c >= 'A' && c <= 'Z'){
putchar(c);
}
Reference to previous chapters (Used only 'while' and 'if'), my code look like this.
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
putchar(c);
while ((c = getchar()) == ' ')
;
}
putchar(c);
}
}

Not counting spaces as words in c

#include <stdlib.h>
#include <stdio.h>
int main()
{
unsigned long c;
unsigned long line;
unsigned long word;
char ch;
c = 0;
line = 0;
word = 0;
while((ch = getchar()) != EOF)
{
c ++;
if (ch == '\n')
{
line ++;
}
if (ch == ' ' || ch == '\n' || ch =='\'')
{
word ++;
}
}
printf( "%lu %lu %lu\n", c, word, line );
return 0;
}
My program works fine for the most part, but when I add extra spaces, it counts the spaces as extra words. So for example, How are you? is counted as 10 words, but I want it to count as 3 words instead. How could I modify my code to get it to work?
I found a way to count words and between them several spaces the program will count only the words and not the several spaces also as words
here is the code:
nbword is the number of words, c is the character typed and prvc is the previously typed character.
#include <stdio.h>
int main()
{
int nbword = 1;
char c, prvc = 0;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
nbword++;
}
if(c == prvc && prvc == ' ')
nbword-;
if(c == '\n')
{
printf("%d\n", nbword);
nbword = 1:
}
prvc = c;
}
return 0:
}
This is one possible solution:
#include <stdlib.h>
#include <stdio.h>
int main()
{
unsigned long c;
unsigned long line;
unsigned long word;
char ch;
char lastch = -1;
c = 0;
line = 0;
word = 0;
while((ch = getchar()) != EOF)
{
c ++;
if (ch == '\n')
{
line ++;
}
if (ch == ' ' || ch == '\n' || ch =='\'')
{
if (!(lastch == ' ' && ch == ' '))
{
word ++;
}
}
lastch = ch;
}
printf( "%lu %lu %lu\n", c, word, line );
return 0;
}
Hope this helped, good luck!

How do I use putchar to "squeeze" characters (Ansi-C)

i was wondering if i could get some help for my code. I put some partial code below
/*reads char by char til EOF*/
while((c = getchar()) != EOF)
{
if(c == '\t')
{
putchar(' ');
}
else if(c == ' ')
{
putchar('d');
}
else
{
putchar(c);
}
}
What I am trying to do right now is squeeze space characters entered by the user. So if the user puts in:
a[SPACE][SPACE][SPACE][SPACE][SPACE][SPACE][SPACE][SPACE]a
The output should be just
a[SPACE]a
Right now i have it set up that it replaces all spaces for d's for testing purposes. How would I change my code so that it just prints out 1 space instead of all the spaces the user puts in.
Thanks for any help in advance.
Just keep a whitespace flag:
int lastWasSpace = 0;
while((c = getchar()) != EOF) {
if(c == '\t' || c == ' ') { // you could also use isspace()
if(!lastWasSpace) {
lastWasSpace = 1;
putchar(c);
}
} else {
lastWasSpace = 0;
}
}
One solution:
/*reads char by char til EOF*/
int hasspace = 0;
while((c = getchar()) != EOF)
{
if (isspace(c))
hasspace = 1;
}
else
{
if (hasspace)
{
hasspace = 0;
putchar(' ');
}
putchar(c);
}
}
First things first, how have you declared c?:
while((c = getchar()) != EOF)
If c is a char, then it cannot hold all characters and an EOF. Be sure c is declared with a datatype larger than char (int is usual).
Next, you can handle compressing multiple spaces with a cheap trick:
int space_seen = 0;
while((c = getchar()) != EOF)
{
if(c == '\t')
{
putchar(' ');
}
else if(c == ' ')
{
if (!space_seen)
{
putchar('d');
space_seen = 1;
}
}
else
{
putchar(c);
space_seen = 0;
}
}
This trick is also good for keeping track of parsing strings, too.
jcomeau#intrepid:/tmp$ cat compress.c; echo 'this is a test' | ./compress
#include <stdio.h>
int main() {
int c, lastchar = 'x';
while ((c = getchar()) != EOF) {
if (c == '\t' || c == ' ') {
if (lastchar != ' ') {
putchar(' ');
lastchar = ' ';
}
} else {
putchar(c);
lastchar = c;
}
}
}
this is a test
Record when you printed a space, and don't print them anymore until you find another letter.
Using your code as a base:
unsigned char space = 0;
/* reads char by char until EOF */
while((c = getchar()) != EOF)
{
if(c == '\t')
{
putchar(' ');
}
else if(c == ' ')
{
/* state specific action */
if(space == 0) {
putchar('d');
space = 1; /* state transition */
}
}
else
{
/* state transition */
if(space == 1) {
space = 0;
}
putchar(c);
}
}
There you go. A very, very simple state machine. It's easy as that!

Resources