I write a program to print integer values using for loop and after printing, the program should wait one second, after that those integers are overwrite with double space character in other words the purpose of the program is to erase those integer after wait for one second.
This the program:
#include <stdio.h>
#include <time.h>
int main (void) {
int i;
for(i=1;i<=5;i++){
printf("%d ",i);
}
for(;clock () < CLOCKS_PER_SEC;){} /*wait for one second*/
printf("\r"); /*move to the beginning of the line*/
for(i=1;i<=5;i++){
printf(" "); /*overwriting the integers*/
}
printf("\n");
return 0;
}
The problem is in the wait loop loop brackets `for(;clock () < CLOCKS_PER_SEC;){}' when i
remove those brackets the program work properly. but if the for loop with brackets. the program doesn't work,I mean the program still runs but it overwrite the integer instead of showing those integers first.
please someone explain what happen?
When you remove the brackets, the printf("\r") statement becomes the body of the for loop, logically equivalent to this:
for(;clock () < CLOCKS_PER_SEC;) {printf("\r");}
So the integers get overwritten right away instead of after the end of the delay period.
Of course, the real question is why you are using a busy-loop for a delay rather than just calling sleep(1), which is much more efficient (i.e. it won't pin your CPU at 100% during the delay period)
You aren't flushing stdout (the stream that printf writes to) yourself so it doesn't happen until the '\r' is written, and then you immediately clear it.
If you remove the {}, then your loop is equivalent to
for(;clock () < CLOCKS_PER_SEC;)
printf("\r");
which writes a bunch of \r, the first of which flushes the output and the rest of which are redundant. After the loop completes, you clear the line, working as you want it to.
You should call fflush(stdout) after printing the numbers. Or you could move the printf("\r") so it comes before the wait loop (the difference being where the cursor ends up).
Your loop is problematic, as there's no guarantee that clock() starts at 0, and it won't on many systems, and you shouldn't spin like that ... it slows down other programs running on your system. You could just use sleep(1), although it's not very accurate.
I suspect somehow the output buffer is being flushed differently between the two cases. You could check this by manually flushing the buffer using fflush(stdout) before the problematic loop.
Also note that the {} aren't mandatory in C, for single-line statements within the loop.
Here is the code you might want:
#include <stdio.h>
int main(int argc, char * argv[]) {
int seconds = 10;
while(seconds>0) {
printf("%10d", --seconds);
fflush(stdout);
sleep(1);
printf("\r");
}
printf("%10s\n", "time up!");
return 0;
}
(Since you ask about what fflush() acturally is, here is a little explanation base on my understanding)
It's all about io cache, 1 reason cache exists is: read/write memory could be over 1000 times quicker than hard disk.
So program should try do reduce the frequence of read/write hard disk, and use memory instead, but need a proper tradeoff for the user experience and io delay.
e.g
When read a file by lines, it could read 2kb or so at once instead a single line, then could read from the memory cache,
When write to console, the program might choose to write to the memory cache until meet a \n or \t char, and some other case.
fflush(FILE * file), is a function from stdio.h, it flush the cache of specified FILE. In your case, the file is stdout(standard output), which print to your console. When you use printf() to print a single number, it might write to cache of stdout, so you didn't see it in console, but calling fflush(stdout) flush out the cache to your console.
On the first 'for' loop you are printing values using printf. Here 'printf' uses 'stdout' which is a buffered output- meaning output will not be printed unless '\n' is provided or buffer full. so you can either uses flush(stdout) after the first loop or uses fprintf(stderr, "") to print to standard error which is not a buffered output.
Related
I have this program that create a new line after every 10 characters. However, once it hits the second iteration and there after it only outputs 9 characters. The program works if I set the second i to -1 but I do not understand why it will not work with i set to 0. The logic is the exact same as the first run as the first i is only run once, so when I want a new line I reset i. Can someone explain what I am missing? I drew out the steps on paper but it still doesn't make sense. Thank you.
#include <stdio.h>
#include <ncurses.h>
#define MAXLINE 10
// count number of chars, once it reaches certain amount
int main (void)
{
//cbreak();
// to open curses terminal
initscr();
int i, c;
// first iteration set to 1
for (i = 0; (c = getch()) != EOF; i++)
{
if (i == (MAXLINE-1))
{
printf("\r\n");
i = 0; // Counter is reset. To break out of the loop use CTRL + D.
}
}
// to close curses terminal
endwin();
}
The first time through the loop i is zero. When you set i to zero inside the loop, when control reaches the end of the for, the statement executed is i++ (making i 1), then (c = getch()) != EOF
The first iteration starts with i set to zero. When the test in the loop resets i to zero, the usual execution of i++ in the for loop still occurs, so the next iteration has i set to one, not zero.
You seem to intermixed both of my examples of my previous answer to your previous question.
Unfortunately, It seems that I didn´t pointed out the reset explicitly although I hinted the difference. I apologize.
The reset needs to be 1 less than the initial start value of the counter because the counter gets incremented at the end of the loop in which the reset takes place, although the incrementation should be only valid for every fully next iteration. We need to make it one integral value less to compensate this effect.
In your actual code, You need to replace i = 0; with i = -1 as seen in one of the examples in my previous answer.
Furthermore, the commenting of cbreak() isn´t a good idea as the console can be either in cbreak() or nocbreak() mode when the program is started up (it is not fixed). Use the explicit cbreak() to determine that the input will immediately read by characters, without the wait for a newline character to flush the buffer.
The Linux man page says:
"Initially the terminal may or may not be in cbreak mode, as the mode is inherited; therefore, a program should call cbreak or nocbreak explicitly."
I cannot understand when does the putchar line is being executed and how it's helping to reverse the input lines ? If EOF occurs the return statement gets executed , but what happens after that line ?
#include<stdio.h>
int fun_reverse();
void main(){
fun_reverse();
}
int fun_reverse(){
int ch ;
ch = getchar();
if(ch==EOF)
return;
fun_reverse();
putchar(ch);
}
every time you're calling fun_reverse in your fun_reverse function, it doesn't print the inputted char immediately, just asks for input for another one, piling on the requests (and creating as much local variables storing each char) until EOF is reached.
When EOF is encountered, fun_reverse returns without calling fun_reverse again, ending the chain, making all callers return and eventually print the results.
The fact that the calls have been piled on due to recursion has the effect of reversing the output, because unpiling them is done the other way round.
This technique is often used to convert a number to string without any extra buffer. Converting a number to string gives the "wrong" end of the number first, so you have to buffer the numbers until the number digits are fully processed. A similar algorithm as the one above allows to store the digits and print them in the readable order.
Though your question is already been answered I would suggest you to read about 'head recursion' and 'tail recursion'.
Have a look at accepted answer of this question.
After Mark Lakata pointed out that the garbage isn't properly defined in my question I came up with this. I'll keep this updated to avoid confusions.
I am trying to get a function that I can call before a prompt for user input like printf("Enter your choice:); followed a scanf and be sure that only the things entered after the prompt would be scanned in by scanf as valid input.
As far as I can understand the function that is needed is something that flushes standard input completely. That is what I want. So for the purpose of this function the "garbage" is everything in user input i.e. the whole user input before that user prompt.
While using scanf() in C there is always the problem of extra input lying in the input buffer. So I was looking for a function that I call after every scanf call to remedy this problem. I used this, this, this and this to get these answers
//First approach
scanf("%*[^\n]\n");
//2ndapproach
scanf("%*[^\n]%*c");
//3rd approach
int c;
while((c = getchar()) != EOF)
if (c == '\n')
break;
All three are working as far as I could find by hit-and-trial and going by the references. But before using any of these in all of my codes I wanted to know whether any of these have any bugs?
EDIT:
Thanks to Mark Lakata for one bug in 3rd. I corrected it in the question.
EDIT2:
After Jerry Coffin answered I tested the 1st 2 approaches using this program in code:blocks IDE 12.11 using GNU GCC Compiler(Version not stated in the compiler settings).
#include<stdio.h>
int main()
{
int x = 3; //Some arbitrary value
//1st one
scanf("%*[^\n]\n");
scanf("%d", &x);
printf("%d\n", x);
x = 3;
//2nd one
scanf("%*[^\n]%*c");
scanf("%d", &x);
printf("%d", x);
}
I used the following 2 inputs
First Test Input (2 Newlines but no spaces in the middle of garbage input)
abhabdjasxd
23
bbhvdahdbkajdnalkalkd
46
For the first I got the following output by the printf statements
23
46
i.e. both codes worked properly.
Second Test input: (2 Newlines with spaces in the middle of garbage input)
hahasjbas asasadlk
23
manbdjas sadjadja a
46
For the second I got the following output by the printf statements
23
3
Hence I found that the second one won't be taking care of extra garbage input whitespaces. Hence, it isn't foolproof against garbage input.
I decided to try out a 3rd test case (garbage includes newline before and after the non-whitespace character)
``
hahasjbas asasadlk
23
manbdjas sadjadja a
46
The answer was
3
3
i.e. both failed in this test case.
The first two are subtly different: they both read and ignore all the characters up to a new-line. Then the first skips all consecutive white space so after it executes, the next character you read will be non-whitespace.
The second reads and ignores characters until it encounters a new-line then reads (and discards) exactly one more character.
The difference will show up if you have (for example) double-spaced text, like:
line 1
line 2
Let's assume you read to somewhere in the middle of line 1. If you then execute the first one, the next character you read in will be the 'l' on line 2. If you execute the second, the next character you read in will be the new-line between line 1 and line 2.
As for the third, if I were going to do this at all, I'd do something like:
int ch;
while ((ch=getchar()) != EOF && ch != '\n')
;
...and yes, this does work correctly -- && forces a sequence point, so its left operand is evaluated first. Then there's a sequence point. Then, if and only if the left operand evaluated to true, it evaluates its right operand.
As for performance differences: since you're dealing with I/O to start with, there's little reasonable question that all of these will always be I/O bound. Despite its apparent complexity, scanf (and company) are usually code that's been used and carefully optimized over years of use. In this case, the hand-rolled loop may be quite a bit slower (e.g., if the code for getchar doesn't get expanded inline) or it may be about the same speed. The only way it stands any chance of being significantly faster is if the person who wrote your standard library was incompetent.
As far maintainability: IMO, anybody who claims to know C should know the scan set conversion for scanf. This is neither new nor rocket science. Anybody who doesn't know it really isn't a competent C programmer.
The first 2 examples use a feature of scanf that I didn't even know existed, and I'm sure a lot of other people didn't know. Being able to support a feature in the future is important. Even if it was a well known feature, it will be less efficient and harder to read the format string than your 3rd example.
The third example looks fine.
(edit history: I made a mistake saying that ANSI-C did not guarantee left-to-right evaluation of && and proposed a change. However, ANSI-C does guarantee left-to-right evaluation of &&. I'm not sure about K&R C, but I can't find any reference to it and no one uses it anyways...)
Many other solutions have the problem that they cause the program to hang and wait for input when there is nothing left to flush. Waiting for EOF is wrong because you don't get that until the user closes the input completely!
On Linux, the following will do a non-blocking flush:
// flush any data from the internal buffers
fflush (stdin);
// read any data from the kernel buffers
char buffer[100];
while (-1 != recv (0, buffer, 100, MSG_DONTWAIT))
{
}
The Linux man page says that fflush on stdin is non-standard, but "Most other implementations behave the same as Linux."
The MSG_DONTWAIT flag is also non-standard (it causes recv to return immediately if there is no data to be delivered).
You should use getline/getchar:
#include <stdio.h>
int main()
{
int bytes_read;
int nbytes = 100;
char *my_string;
puts ("Please enter a line of text.");
/* These 2 lines are the heart of the program. */
my_string = (char *) malloc (nbytes + 1);
bytes_read = getline (&my_string, &nbytes, stdin);
if (bytes_read == -1)
{
puts ("ERROR!");
}
else
{
puts ("You typed:");
puts (my_string);
}
return 0;
I think if you see carefully at right hand side of this page you will see many questions similar to yours. You can use fflush() on windows.
Is there a limit to how many times a loop can run in C?
void main()
{
int T,N,x,X,i;
x=0;
scanf("%d",&T);
while(T>0)
{
T--;
scanf("%d",&N);
X=0;
while(N>0)
{
N--;
scanf("%d",&x);
if(x>X){X=x;}
}
printf("Case: %d",x);
}
}
T has a range of 0-250, and N has a range of 0-1000. x has a range of 0-10,000.
Whenever the N exceeds something above 800, my console stops taking input.
Can this be due to a limit on the input buffer?
There is no limit to how many times a loop may loop. There are limits to the max and minimum values of an int, and those may play into your loop. In this case, 800 should be fine, so there is something else going on here.
Edit: Works for me... the only weird thing I see is that you reset X inside the innermost loop, so the output is always the last integer entered if it's >0, or 0.
Are you piping input to this program? There may be some buffering limitation with that. Try putting the data in a file and read from the file.
It's common practice to loop 10,000 times or (much) more to compare the performance of two small calculations.
If there was a limit, there wouldn't be such as thing as an infinite loop. ;)
Because the comments have gone irreverent on you, I will make this a community wiki and commence with an interrogative-like suggestion that belongs in comments:
Check the return values from all scanf calls. Do this first to determine whether the standard library API is already transmitting information to you -- via "electrostatic transmission", otherwise known as the contents of register eax after you call scanf on x86 architecture. Do not let the light in that register die unobserved. Take the register's electrical charges (bits) into a variable and compare them to both zero (0) and EOF. Those alien transmission were sent to you from the year 1976, when scanf was first written to return an informative numerical value to the caller.
As tomlogic pointed out in comments to an answer, if you are pasting the data, you should instead try using the technique known as "input redirection" or "piping." First, get your data into a file, let's say name filename.dat. Then, issue a command such as the following:
executable-name < filename.dat
Where executable-name is the file you are generating with the C compiler. Technically, the above syntax creates an "input redirection" or "stdin redirection" -- the shell opens the file for read access as file descriptor zero (0), also know as stdin. The child program as spawned from the shell will scanf from the file, rather than the terminal (your paste buffer).
Another approach is to create a "pipe indirection" in which the shell opens another process's output for reading and passes this to the child, again as stdin file descriptor. In this case, the shell probably uses popen rather than open. The syntax for this might be:
cat filename.dat | executable-name as if on a Unix-clone, or
type filename.dat | executable-name if in the context of an IBM® PC-DOS® clone.
I have a weird issue with printing data out. I use printf to print a char* string and then after that print another one. However part of the first string doesn't get printed and when I print the second string the missing part of the first one is prepended to that one. What is happening here?
I'm writting a simple libpcap implimentation. Here is a sample callback function that will produce the same results. I tried removing buffering and adding a putchar('\n') after printing but it didn't help.
void ParseData(u_char* useless, const struct pcap_pkthdr* pkthdr, const u_char* packet){
int packetLen, i;
packetLen = pkthdr->len;
for (i = 0; i < packetLen; i++){
putchar(packet[i]);
}
}
stdio buffers characters. Unless you tell it otherwise, usually it will only actually issue a write when it sees a newline character. If you want a different behavior, you can remedy it with some of these:
After your first printf, call fflush(stdout); to flush the buffer.
Alternatively, call setbuf(stdout, NULL); to disable buffering. Do this before you do any printfs.
Bypass stdio by coding to platform specific APIs like write (POSIX) or WriteFile (Windows). Usually I would recommend against this, especially for something like stdout..
There is a possibility that your first printf is not having a '\n' at the end. In some cases the data might be buffered and printed together when a '\n' is encountered.
But, this is just a guess. Incase if you cannot post code, try the above.
It's called file stream buffering.
You can disable it or change the size of the buffer using setvbuf(). Or just fflush() after every print. However, the stream buffer is (normally) flushed when a line terminator (\n) is present.
I have a similar experience but this has more to do with double byte. I have 2 char* define back to back. I read some char into the first string. Turns out that is was double byte, so the remaining of the string spill over to the second string.