I tried to replace characters with substraction. It works but it leaves a blank with this method:
#include <stdio.h>
int main(void) {
int c;
while((c = getchar()) != EOF) {
if (c == '\t')
putchar('t');
if(c == '\t')
c = c - '\t';
putchar(c);
}
}
Its the substraction that gives the unwanted output and I couldn't figure out why.
Example input:
Hello tab tab tab
Output:
Hello tabt tabt tab
Goal is Hello tabttabttab.
The "blank" is the result of printing NUL (0) character. Whenever you input '\t', you are printing NUL, which is not a printable character.
if(c == '\t')
c = c - '\t';
putchar(c); // same as putchar(0); if c == '\t'
Perhaps, you wanted to replace tabs with -:
if(c == '\t')
c = '-';
putchar(c);
Related
As a programming novice I have been trying to teach myself C to better understand computers using The C Programming Language (2nd Edition).
This site has been very helpful so far in troubleshooting problems but there is one problem I can't get my head around. It is my proposed solution to exercise 1-12 using my solution to 1-9 as a backdrop. I was wondering if anyone in this online community would kindly point out where I'm going wrong.
Exercise 1-9 asks you to "Write a program to copy its input to its output, replacing each string of one of more blanks by a single blank"
There are many ways to skin the proverbial cat here but the solution that reads most simply to me is this:
int c;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
putchar(' ');
while((c = getchar()) == ' ') // if there are subsequent blanks
; // do nothing
}
if(c != EOF)
putchar(c);
}
Now Exercise 1-12 is asking you to "Write a program that prints its input one word per line."
My first attempt was successful but an oversimplification of the problem.
int c;
while((c = getchar()) != EOF)
{ if(c == ' ')
putchar('\n');
else
putchar(c);
}
So I've tried to rectify this to accept a much wider range of inputs and here is the result
int c;
while((c = getchar()) != EOF)
{
if(c == ' ' || c == '\t' || c == '\n')
{
putchar('\n');
while((c = getchar()) == ' ' || (c = getchar()) == '\t' || (c = getchar()) == '\n')
;
}
if(c != EOF)
putchar(c);
}
Now I know this is wrong when I run it and I have looked up online other very simple ways to solve the problem.
My issue here is that I don't understand why it doesn't work. To me if the solution to 1-9 works I don't understand why it fails when I take the same principle to 1-12. Anyone who could point this out would be appreciated!
What you did was almost correct, but getchar() consumes one character of input on every invocation.
You could have written
while ((c = getchar()) == ' ' || c == '\t' || c == '\n')
because the || operator is processed left-to-right with so called sequence point in between;
though clearer is to move the initialization of c out of the loop condition.
Finally, using isspace this would consume any whitespace characters, with much less typing:
#include <ctype.h>
int c;
do {
c = getchar();
} while (isspace(c));
while((c = getchar()) == ' ' || (c = getchar()) == '\t' || (c = getchar()) == '\n')
^ ^ ^
You're calling getchar() three times. Those calls read three characters, and you compare the first against space, second against \t and third against \n. (The calls are separated by ||, so there should be no issues with undefined sequencing.)
Instead, use temp variable:
int c;
do {
c = getchar();
} while (c == ' ' || c == '\t' || c == '\n');
Using isspace() from ctype.h would probably be better too.
It might be worth mentioning a sane and readable way to write this code without "assignment inside conditions", "most operators on a single line wins a price" or other such bad and dangerous habits picked up from that old book:
#include <stdio.h>
#include <ctype.h>
int main (void)
{
while(1)
{
int c = getchar();
if (isspace(c))
{
putchar('\n'); // at first space found, print line feed
do
c = getchar();
while(isspace(c)); // discard any additional spaces
}
if(c == EOF) // here c will not be a space, but possibly EOF
{
break;
}
putchar(c);
}
return 0;
}
If your char is not a space then you will try to get another char from the user instead of analyzing the one that was entered.
correct your while to call it only once:
while ((c = getchar()) == ' ' || c == '\t' || c == '\n')
I am trying to write a program which replaces a string of one or more tabs by a single tab.
Here's what I wrote:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
while ((c = getchar()) != '\n')
{
if (c == 9)
{
while((c=getchar())== 9)
putchar(' ');
if (c != 9)
break;
}
putchar(c);
}
}
I compared it to newline because I don't get EOF and pressing ctrl-z does nothing, atleast on Windows.
Well the output prints spaces instead of tabs. Can someone point out what am I doing wrong?
There is no need to break, in fact, when you use break inside a for/while you exit from the loop (not what you want), if you want to allow only one tab use a sentinel and continue if the previous character is also a tab:
int c, tab = 0;
while (((c = getchar()) != '\n') && (c != EOF)) {
if (c == '\t') {
if (tab == 1) continue;
tab = 1;
} else {
tab = 0;
}
putchar(c);
}
Press CTRL+ Z + Intro to send EOF in Windows.
its because you write putchar(' ').
its an error. write putchar('\t') instead.
there is no such char as ' '. this is 4 spaces.
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == '\t')
printf("\\t");
else if (c == '\b')
printf("\\b");
else if (c == '\\')
printf("\\\\");
else
putchar(c);
}
return 0;
}
In this case for an input of
hi how are you\doing
I get an output
hi\thow\tare\tyou\\doing
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
if (c == '\t') {
c = '\b';
printf("\\t");
}
if (c == '\b') {
c = '\b';
printf("\\b");
}
if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
}
return 0;
}
When I run this program with an input
hi how are you\doing
(The large spaces being tabs)
I get this output
hi\t\how\t\are\t\you\doing
Code:
#include <stdio.h>
int main() {
int c;
c = '\b';
putchar(c);
return 0;
}
On running this,
I get nothing. No output. Back to the shell prompt.
To be more precise, in the first program I get the output I want, but in the second program I get the backslashes after every \t but not after the \ I would expect \\\ to be the output looking at how \t became \t\, is '\b' causing it? if it is, how does it work? but if so why doesn't the same happen in the third program?
Ran this on rasbian default gcc compiler and mingw msys-gcc package for windows.
The reason the second program is behaving that way is because you are entering more than one if block:
if (c == '\t') {
c = '\b';
printf("\\t");
}
if (c == '\b') {
c = '\b';
printf("\\b");
}
if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
When you encounter a tab, the first block is entered where it prints \t to the screen then changes c to a backspace.
The second block is then entered because c is a backspace (because you just changed it to be that). That block then prints \b to the screen, so now you have \t\b on the screen.
When you then call putchar to write the backspace, the b will get overwritten by the next character. So when the next character is written you then have \t\ on the screen.
So the problem here is that you're testing c multiple times and potentially changing it in between. The reason this happens only with the tab is because you check for the tab first, then the backspace, then the backslash.
If you use else if instead of if, you won't enter multiple blocks:
if (c == '\t') {
c = '\b';
printf("\\t");
}
else if (c == '\b') {
c = '\b';
printf("\\b");
}
else if (c == '\\') {
c = '\b';
printf("\\\\");
}
putchar(c);
With this change, given the original input, the output will be:
hi\how\are\you\doing
So this is my code so far, I am trying to replaces multiple spaces and tabs into single space. The input is multiple lines with multiple tabs and spaces (including mix tab and spaces sentence). I am stuck after writing this much:
#include <stdio.h>
#define NONBLANK 'a'
main(){
int c, lastc;
lastc = NONBLANK;
while (( c = getchar()) !=EOF) {
if (c != ' ' || lastc !=' '){
if (c != '\t' || lastc !='\t'){
putchar(c);
lastc = c;}
}
}
}
}
The problem is that getchar() echoes the input as it is typed, confusing you by echoing the spaces and tabs you wanted to condense. Try this using the non-echoing getch(). I haven't used EOF to end, but return, experiment with this as you will.
#include <stdio.h>
#include <conio.h>
int main(void)
{
int c, lastc = -1;
while ((c = getch()) != '\r') {
if (c != ' ' && c != '\t'){
if (lastc == ' ' || lastc == '\t')
putchar(' ');
putchar(c);
}
lastc = c;
}
return 0;
}
Please also note your incorrect declaration of main().
This code takes multiple fs and prints only 1. Can someone please explain to me why this code does not print two fs? putchar appears twice while not EOF. I have been staring at it for hours and I do not understand how it prints only 1 f.
The code is functioning correctly. I just do not understand how it works step by step.
/* A program that takes input of varied 'f's and out puts 1 f */
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF)
{
if (c == 'f')
{
putchar(c);
}
while (c == 'f')
{
c = getchar();
}
if (c != EOF) putchar(c);
}
}
Thanks
I'll step through with comments in the code; for f (or in reality f\n) as input:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) // You type f and hit return key (remember this)
{
if (c == 'f') // c contains 'f' is true
{
putchar(c); // print 'f'
}
while (c == 'f') // c == 'f' is true
{
c = getchar(); // '\n' is buffered on stdin from return key
// so getchar() returns '\n'. So c will be set to '\n'
// It goes back to the while loop and checks if c == 'f'
// but it's not, it's '\n'! So this will run once only.
}
if (c != EOF) putchar(c); // '\n' != EOF, so print '\n' newline, back to loop
}
}
Thus giving f\n as input will yield the output f\n
In the case of input fffff (in reality fffff\n), see below:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) // You type fffff and hit return key
{
if (c == 'f') // c contains 'f' is true, first 'f'
{
putchar(c); // print 'f'
}
while (c == 'f') // First loop, c == 'f'
// Second loop, c == 'f'
// Last loop, c == '\n', so false
{
c = getchar(); // First loop: 'ffff\n' is still buffered on stdin
// c = 'f', loop again
// Last loop: c = '\n'
}
if (c != EOF) putchar(c); // '\n' != EOF, so print '\n' newline, back to loop
}
}
You see that your inner while loop will eat all the f until you hit \n, thus the same affect as above.
if(c == 'f')
putchar(c);
This prints one f, the one you see.
while(c == 'f')
getchar(c);
This is where the f disappears. If you just used putchar(c) before, that means that the loop will execute at least once because c == f. So the f is gone (c != f)
Finally, you just use putchar(c) on the first character which is not f.