Why "\r " deletes my previous printed line but "\r" it doesn't - c

When I print some line, if I want to overwrite for example the first character, I use \r because is the carriage return character but it prints only one character after this one, my whole line is overwritten.
This is some code that I made for this question.
#include <stdio.h>
int main(){
printf("-------");
printf("\r ");
return 0;
}
using this code my output is: with one space.
Now I change a little bit the code. The only change is that in my second printf I delete the space after \r
#include <stdio.h>
int main(){
printf("-------");
printf("\r");
return 0;
}
using this second code my output is "-------" (without quotes)
my expected output: " ------"
Why this is not working?

\r is Carriage Return. It sends the "carriage" (cursor, in modern times) back to the beginning of the same line. It does not by itself erase anything--just moves the cursor. Apparently your terminal has the behavior that printing a character at the beginning of a line erases the rest of the line. That's not guaranteed, I think.
On many systems if you want to clear the current line you must print \r followed by as many spaces as the line had characters on it.

Related

Please help! I am trying to get input from a file with spaces I keep getting infinite loop. C programming

I am trying to read every word in a file and print it to the screen. I want The program to accept spaces but it gives me an infinite loop when I use this %[^\n]
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *DoThis;
DoThis = fopen("Encrypppc.txt", "r");
char word2[48];
while(!feof(DoThis)){
fscanf(DoThis,"%47[^\n]s",word2);
printf("%s\n", word2);
}
return 0;
}
Try to create a file and input spaces in the first sentence. It gives an infinite loop in the first sentence when there's space so it never reaches eof.
I found the answer I supposed to
add a space in the fscanf function.
this is what gives me the infinite loop
fscanf(DoThis,"%47[^\n]s",word2);
after I add a space before the sign % there's no infinite loop and the loop stops at EOF
fscanf(DoThis," %47[^\n]s",word2);
notice the change
You have an 's' that doesn't belong in the format string. Try this:
fscanf("%47[^\n]%*c", word2);
That will get you past the failure to read the end of file and on to the next problem. I added the %*c format to read and ignore the next character (either a \n newline or the end of file). That does (more precisely) what you accomplish with the leading space (which discards all spaces and tabs up to the next nonblank character.)
That "next problem" is the one mentioned in comment that feof() only goes true after an attempt to read past the end of file. You'll see your last line twice. The leading space in the format might work for you, but a better solution is to use the return value from fscanf() to tell you if the input read anything:
while (1)
{
int n = fscanf("%47[\n]%*c", word2);
if (n != 1) break;
...do something with word2
}
The ?scanf functions return the number of fields successfully converted and stored. There's only one such field in your format, so the return will be 1 whenever the input succeeded, or something else if it didn't. (Both 0 and EOF are possible returns, depending on the state of the file beforehand.)

Is getc() and getchar() well-defined function?

printf("%c %c", getc(stdin), getc(stdin));
rewind(stdin); printf("\n");
printf("%c %c", getchar(), getchar());
output
s
s
s
s
I wrote the source code like that and I pressed s, enter, s, enter sequentially on windows console application using vs2017. Console shows me what I put and print output when I press the key. The result's appearance is like s, enter, enter, space, s, s, enter, enter, space, s. Did I use the function in wrong way?
Q1. I pressed s, enter sequentially, but why output is reversed?
Q2. At output's third line and sixth line, why is there exist whitespace like  s not s?.
Explaining the output
The arguments to a function can be evaluated in any order that the compiler chooses.
The original code looked like this (missing printf("\n"); compared to the revised code):
printf("%c %c", getc(stdin), getc(stdin));
rewind(stdin);
printf("%c %c", getchar(), getchar());
Your 'output' in the question is extremely difficult to read and interpret. However, I'm reasonably sure that what you show consists of both your input and the program's output.
You say you type s enter twice. The output you get, copied from the question, is:
s
s
s
s
The first s and the newline that follows are what you typed. The blank line is there because the newline was read by the getc(stdin) that appears first in the argument list, then there's the blank from the format string, and the s which was read by the getc(stdin) that appears second in the argument list. Your compiler, it seems, evaluates the arguments right to left — but you should not rely on that.
Now we run into a problem; there's a newline after the second s that isn't accounted for by the code you showed when I wrote this answer. Since then, you've added the printf("\n"); which explains the output you saw.
Putting that aside, the third s is followed by a newline and is what you typed. And again, the blank line is from the newline and then space and s is the rest of the output, and there's probably a newline after that too.
JFTR, when I run your code (program getc73 compiled from getc73.c), I see:
$ getc73
s
ss
s$
$
The $ is my prompt; the first s is what I type; then the newline, blank and s are printed (with no newline at the end); then the second s on the third line is my next s and return, followed by the newline and blank s. Since there's no newline at the end, my prompt appears immediately after the fourth s. I hit return to print another prompt at the start of the line.
Why rewind(stdin) is a no-op
You can't successfully execute an fseek() call on a terminal device. They don't have any storage so you can't move around like that. The rewind() function is effectively:
void rewind(FILE *fp)
{
fseek(fp, 0, SEEK_SET);
}
So, the rewind(stdin) call fails to rewind, but it has no way to report that to you because it returns no value. It does no good; it doesn't do any harm either. If it had worked, you would not have needed to enter the information twice.
If the standard input had been a file instead of a terminal, then the rewind would succeed — disks are seekable.
Improved formatting
If you were on a POSIX system, I'd suggest you used a feature of POSIX printf() that allows you to print the same argument more than once:
#include <stdio.h>
int main(void)
{
printf("[%1$c] %1$d [%2$c] %2$d\n", getc(stdin), getc(stdin));
printf("[%1$c] %1$d [%2$c] %2$d\n", getchar(), getchar());
return 0;
}
When I run that on my terminal (it's a Mac running macOS Mojave 10.14.6 using GCC 9.2.0), I get:
s
[
] 10 [s] 115
s
[
] 10 [s] 115
The lines with just the s on them are what I typed; the other lines show that the newline is printed before the letter s.
This probably won't work for you in VS2017 — the manual for printf() formats on Windows strongly suggests it won't work. Your best bet, probably, is to use:
#include <stdio.h>
int main(void)
{
printf("%d %d\n", getc(stdin), getc(stdin));
printf("%d %d\n", getchar(), getchar());
return 0;
}
That generates:
s
10 115
s
10 115
Choosing a good format to show what you're seeing is an art form. Don't forget to include newlines at the end of (most) printf() format strings. Obviously, if you're building up a line of output piecemeal, you don't want newlines at the end of intermediate formats, but the majority of printf() statements should have a newline at the end of the format.

Treatment of \b in template strings to printf in C

Can someone please explain or point me to a reference that explains why in the code snippets below the line printed in the first includes the whole word hello, while in the second it consists only of the letters he? I thought the backspace escape characters would delete the last three letters regardless of the newline escape. I've read the GNU documentation on printf but couldn't find anything on point.
int main(void)
{
printf("hello\b\b\b\n");
return 0;
}
int main(void)
{
printf("hello\b\b\b");
return 0;
}
This isn't really a question about C or printf. In each case the code does exactly what it says: in the first example it outputs the 9 characters h e l l o \b \b \b \n and in the second it likewise outputs 8 characters. If you write standard output to a file that's exactly what the file will contain. But if you write to a terminal, your terminal may handle \b by backspacing, and so your question is really about your terminal. You have not said what terminal you are using.
One common way for the backspace character to behave is by moving the cursor one position left, but not actually erasing the character in that position. The next character output will be written over it.
In your first example, you move the cursor back to the first l, but then you never write anything over it or any other character. Then \n doesn't change any character on the screen, but just moves the cursor to the next line. So you still see hello on the preceding line.
In your second example, the cursor is left over the first l when your program terminates. So the next program to write output to the terminal will write over that character (unless the next program's first write is \n or something like that). That next program might be your shell, and so the characters from your shell prompt probably overwrite the llo, so you don't see them.
Two key things to keep in mind:
Output to the console isn't immediately rendered when you use printf(): the output is buffered. Two ways to immediately (synchronously) flush the output buffer to the console is to print a newline via printf("\n"), or manually flush the buffer via fflush(stdout).
If you use the \b escape sequence, you will move the cursor one "space" back/left, but printing a newline character won't necessarily clear the rest of the line. If you were to manually print new characters over the old ones (i.e. printf("Hello\b\b\b \n")) the output would be more like what you're expecting.
Additionally, if you want to do some advanced command-line menus, graphics, etc, you'll need to use something like libncurses.
Finally, the following example should help give a better idea on the typically behavior involving your question.
#include <stdio.h>
#include <unistd.h>
#define DELAY (2) /* seconds */
int main(void)
{
printf("Example DELAY:\n");
printf("------------------------------------------------------------------------\n");
printf("hello\b\b\b\n");
sleep(DELAY);
printf("\n\n");
printf("Example 2:\n");
printf("------------------------------------------------------------------------\n");
printf("hello\b\b\b");
sleep(DELAY);
printf("...");
sleep(DELAY);
fflush(stdout);
sleep(DELAY);
printf("\n\n");
printf("Example 3:\n");
printf("------------------------------------------------------------------------\n");
fflush(stdout);
printf("hello\b\b\b");
fflush(stdout);
sleep(DELAY);
printf("...");
sleep(DELAY);
fflush(stdout);
sleep(DELAY);
printf("\n\n");
return 0;
}

How scanf works if I add a new line '\n' at the end

#include <stdio.h>
int main(){
int a,b,c;
scanf("%d%d%d\n",&a,&b,&c);
printf("%d %d %d",a,b,c);
return 0;
}
Look I am taking 3 inputs and printing 3 outputs... But as I added a new line at the end of the scanf function I have to give 4 inputs to get 3 outputs(I get the first 3 I give as input)... How scanf works here?
And in this case:
#include <stdio.h>
int main(){
double n[2][5]; int i,j;
for (i=0;i<=1;i++){
for(j=0;j<=4;j++){
scanf("%lf\n",&n[i][j]);
printf("Class=%d Roll=%d Marks=%lf\n",i+6,j+1,n[i][j]);
}
}
return 0;
}
Look I have to give 11 inputs to get the 10 outputs... And each time I give a input I get the previous input as an output... How scanf is working here?
A white character in scanf format matches a sequence of white characters in the input until a non-white character.
Newline is a white character and this explains the behavior of your program. Meaning that if your scanf format terminates by a newline, it does not finish until it sees an additional non-blank character after the last parsed input.
scanf is only used to input values, now what you need is the your output to be on a new line, basically you want a newline to be printed on your screen, so you must use the \n in the printf as you want a new line to be printed.As for why it is asking for four inputs , Im not sure, the syntax says that you must you use % and a letter according to the type of data to be accepted, Ill read more on this and Get back.
Thank You.

Why and how does the following outputs involving the carriage return show up?

#include <stdio.h>
void main()
{
printf("ab");
printf("\bsi");
printf("\rha");
}
this code gives the output of "ha" on GCC 4.8 compiler
#include <stdio.h>
void main()
{
printf("ab");
printf("\bsi");
printf("\rha");
printf("\n");
}
this code gives the output of "hai" on GCC 4.8 compiler
now the question is why does the output change from "ha" to "hai" just on adding the statement printf("\n"); at the end which (according to me) should not affect the code due to the preceding lines.
When your program ends, the shell writes the prompt starting at whatever position the cursor was last on. So in the first case, after \rha, the cursor is sitting on the i. The shell will overwrite the i with whatever the first character of your prompt is.
In the second case, you output a \n at the end which moves the cursor to the next line, where the shell writes its prompt.
First of all you need to understand the white space characters:
\n :: It moves the cursor to the next line.
\b :: It moves the cursor one character back to the left of Console. Just simply backspaces one
character.
\r :: Carrage Returns.It moves cursor to extreme right of the same line.
So result of printf statments are::
1. Prints "ab" , cursor sitting at end of line.
2. Prints "asi" after moving the cursor back one space (\b), cursor sitting at the end of a line.
3. Prints "hai", cursor sitting after ha, just below i.
So, OUTPUT :: hai
In first case you are not able to see 'i' because of the cursor whereas in second due to newline character you are able to see it
If you compile the first code, in the place of i, there is the cursor so you can't see that i. In the second code, the cursor is in a new line and it doesn't cover any character.

Resources