C sleep method obstructs output to console - c

I have a C program, where I just wanted to test if I could reproduce a console spinner used in npm install while it installs a module. This particular spinner simply spins in this order:
|
/
-
\
on the same space, so I use the following program:
#include <stdio.h>
int main() {
char sequence[4] = "|/-\\";
while(1) {
for(int i = 0; i < 4; i++) {
// \b is to make the character print to the same space
printf("\b%c", sequence[i]);
// now I want to delay here ~0.25s
}
}
}
So I found a way to make it rest for that long from <time.h> documentation and made this program:
#include <stdio.h>
#include <time.h>
void sleep(double seconds) {
clock_t then;
then = clock();
while(((double)(clock() - then) / CLOCKS_PER_SEC) < seconds); //do nothing
}
int main() {
char sequence[4] = "|/-\\";
while(1) {
for(int i = 0; i < 4; i++) {
printf("\b%c", sequence[i]);
sleep(0.25);
}
}
}
But now nothing prints to the console. Does anyone know how I can go about producing the behavior I want?
EDIT According to what appears to be popular opinion, I've updated my code above to be the following:
#include <stdio.h>
#include <unistd.h>
int main() {
char sequence[4] = "|/-\\";
while(1) {
for(int i = 0; i < 4; i++) {
printf("\b%c", sequence[i]);
/* fflush(stdout); */
// commented out to show same behavior as program above
usleep(250000); // 250000 microseconds = 0.25 seconds
}
}
}

You will need to flush after you wrote to the console. Otherwise, the program will buffer your output:
fflush(stdout);

Things do get printed to console, it's just does not get flushed. Add fflush(stdout) to see the results, or set the console in an unbuffered mode by calling setbuf:
setbuf(stdout, NULL);
A bigger problem with your code is that your sleep method runs a busy loop, which burns CPU cycles for no good reason. A better alternative would be to call usleep, which takes the number of microseconds:
usleep(25000);

The sleep function isn't really your problem. The issue is that the output is buffered. The simplest thing to do will be to research ncurses.
For now:
fflush(stdout);

Related

How to print to terminal one char and then pause and print another?

I've been trying to print to the terminal with a pause, it's better explained with the following code:
I'm trying to have X print to the terminal and then wait 5s and have X print again but when I run the code, it waits 5s and prints XX can anyone help me get the proper functionality?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void sleepMs(long long delayMs){
const long long NS_PER_MS = 1000 * 1000;
const long long NS_PER_SECOND = 1000000000;
long long delayNs = delayMs * NS_PER_MS;
int seconds = delayNs / NS_PER_SECOND;
int nanoSeconds = delayNs % NS_PER_SECOND;
struct timespec reqDelay = {seconds, nanoSeconds};
nanosleep(&reqDelay, (struct timespec *) NULL);
}
int main()
{
printf("X");
sleepMs(5000);
printf("X");
return 0;
}
Thank you in advance, sorry for any missing tags.
EDIT: I want them to print on the same line
You need to flush the output stream if you want to see the result before printing a \n:
putchar('X');
fflush(stdout);

Print out seconds on screen by replacing them without clear screen

I've tried but still dont know yet. I want to print out the result like this: seconds(10) -> seconds(9) -> ... -> seconds(1) by replacing each integer in every second without system("cls").
sample program
You could print \r to return the cursor to the beginning of the line.
Example:
#include <stdio.h>
#include <threads.h>
int main() {
struct timespec st = {.tv_sec = 1, .tv_nsec = 0};
for(int i = 10; i>=0; --i) {
printf("%2d\r", i); // \r to return to the beginning of the line
fflush(stdout); // flush to ensure it's actually printed
thrd_sleep(&st, NULL); // sleep a second
}
}

problems utilitizing small pauses in c code using nanosleep

I am a C beginner and trying this and that.
I want to display a string letter by letter with tiny pauses in between. So my idea was a small pause using sleep or usleep after displaying each char but I read that using nanosleep in your own function makes more sense. So I put my little pauses in a function "msleep" to get microseconds pauses.
I output my string 3 times.
Once in the main(), then in a do-while-loop in a function (fancyOutput) char by char, and eventually in the same function with printf again to check, if it was handled over correctly.
My problem: I expected, that the middle output would work char by char and separated by 100/1000 seconds breaks, but what I experience is a long break before chowing any char and then a fast output if line two and three. It looks like the compiler "realized what I am planning to do and wants to modify the code to be more efficient." So all my pauses seemed to be combined in one long break.
Maybe you remeber the captions in the tv series "x files" - something like that I want to produce.
For sure there are better and more sophisticated ways to archieve what I am going to try but I want to learn and understand what is going on. Can someone help me with that?
I am using codeclocks on a debian-based distro with gcc.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int msleep(long tms);
void fancyOutput(char inputToOutput[]);
int msleep(long tms)
{
struct timespec ts;
int ret;
if (tms < 0)
{
return -1;
}
ts.tv_sec = tms / 1000;
ts.tv_nsec = (tms % 1000) * 1000000;
do
{
// printf("sleeping for %d", ret);
ret = nanosleep(&ts, &ts);
}
while (ret);
return ret;
}
void fancyOutput(char inputToOutput[])
{
int counter = 0;
do
{
printf("%c", inputToOutput[counter]);
msleep(100);
++counter;
}
while (!(inputToOutput[counter]=='\0'));
printf("\n");
printf("%s\n", inputToOutput); // only check, if string was properly handled over to function
}
char output[] = "This string shall appear char by char in the console.";
void main(void)
{
printf("%s\n", output); // only check, if string was properly set and initialized
fancyOutput(output); // here the function above is called to output the string char by cchar with tiny pauses between
}
You are getting problem with buffer.
When you use printf with no \n (new line) C is buffering the display in order to display information block by block (to optimize displaying speed).
Then you need to either add a \n to your printf or add a flush of the stdout.
An other solution will be to use stderr, which got no buffer, but stderr is meant for error not output :)
You can also check setvbuf in order to change the buffering.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int msleep(long tms);
void fancyOutput(char inputToOutput[]);
int msleep(long tms)
{
struct timespec ts;
int ret;
if (tms < 0)
{
return -1;
}
ts.tv_sec = tms / 1000;
ts.tv_nsec = (tms % 1000) * 1000000;
do
{
// printf("sleeping for %d", ret);
ret = nanosleep(&ts, &ts);
}
while (ret);
return ret;
}
void fancyOutput(char inputToOutput[])
{
int counter = 0;
do
{
printf("%c", inputToOutput[counter]);
flush(stdout);
msleep(100);
++counter;
}
while (!(inputToOutput[counter]=='\0'));
printf("\n");
printf("%s\n", inputToOutput); // only check, if string was properly handled over to function
}
char output[] = "This string shall appear char by char in the console.";
void main(void)
{
printf("%s\n", output); // only check, if string was properly set and initialized
fancyOutput(output); // here the function above is called to output the string char by cchar with tiny pauses between
}
So, I tried the solution to place fflush(stdout); directly after the char-output in the loop. It worked as intended.
Summarizing for those with similar problems (guess this also happens with usleep and similar self-made functions):
As I understaood, printf "collects" data in stdout until it "sees" \n, which indicates the end of a line. Then printf "releases" stdout. So in my initial post it "kept" each single char in stdout, made a pause after each char and finally released stdout in one fast output.
So fflush(stdout); after each char output via empties stdout char by char.
Hope it can help others.

c does not follow the program operation procedure

summary : system("clear"); isn't working well.
I'm using gcc, ubuntu 18.04 LTS version for c programming.
what I intended was "read each words and print from two text files. After finish read file, delay 3 seconds and erase terminal"
so I was make two text files, and using system("clear"); to erase terminal.
here is whole code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void printFiles(char *file1,char *file2,char *change1, char *change2){
FILE *f;
char *text = malloc(sizeof(char)*100);
f=fopen(file1,"r");
system("clear");
//while(!feof(f)){
while(EOF!=fscanf(f,"%s",text)){
//fscanf(f,"%s", text);
printf("%s ",text);
//usleep(20000);
}
//sleep(3);
fclose(f);
printf("\n");
//all comment problems are appear here. and if I give delay, such as usleep() or sleep, delay also appear here. Not appear each wrote part.
f=fopen(file2,"r");
//while(!feof(f)){
while(EOF!=fscanf(f,"%s",text)){
if(strcmp(text,"**,")==0){
strcpy(text,change1);
strcat(text,",");
}
else if(strcmp(text,"**")==0){
strcpy(text,change1);
}
else if(strcmp(text,"##.")==0){
strcpy(text,change2);
strcat(text,".");
}
else if(strcmp(text,"##,")==0){
strcpy(text,change2);
strcat(text,",");
}
printf("%s ",text);
//usleep(200000);
}
fclose(f);
free(text);
sleep(3); //here is problem. This part works in the above commented part "//all comment problems are appear here."
system("clear"); //here is problem. This part works in the above commented part "//all comment problems are appear here."
}
int main(){
char file1[100] = "./file1.txt";
char file2[100] = "./file2.txt";
char change1[100]="text1";
char change2[100]="text2";
printFiles(file1,file2,change1,change2);
return 0;
}
I'm very sorry, files and variables names are changed because of policy. Also, file contents also can not upload.
I can't find which part makes break Procedure-oriented programming. I think that was compiler error, because using one file read and system(clear); works well.
I also make two point variables, such as 'FILE *f1; FILE *f2; f1=fopen(file1); f2=fopen(file2)...`, but same result occur.
Is it compiler error? If it is, what should I do for fix these problem? Thanks.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void printFiles(char *file1,char *file2,char *change1, char *change2){
FILE *f;
char *text = malloc(sizeof(char)*100);
f=fopen(file1,"r");
system("clear");
//while(!feof(f)){
while(EOF!=fscanf(f,"%s",text)){
//fscanf(f,"%s", text);
printf("%s ",text);
fflush(stdout);
//usleep(20000);
}
//sleep(3);
fclose(f);
printf("\n");
//all comment problems are appear here. and if I give delay, such as usleep() or sleep, delay also appear here. Not appear each wrote part.
f=fopen(file2,"r");
//while(!feof(f)){
while(EOF!=fscanf(f,"%s",text)){
if(strcmp(text,"**,")==0){
strcpy(text,change1);
strcat(text,",");
}
else if(strcmp(text,"**")==0){
strcpy(text,change1);
}
else if(strcmp(text,"##.")==0){
strcpy(text,change2);
strcat(text,".");
}
else if(strcmp(text,"##,")==0){
strcpy(text,change2);
strcat(text,",");
}
printf("%s ",text);
fflush(stdout);// The answer.
//usleep(200000);
}
fclose(f);
free(text);
sleep(3); //here is problem. This part works in the above commented part "//all comment problems are appear here."
system("clear"); //here is problem. This part works in the above commented part "//all comment problems are appear here."
}
int main(){
char file1[100] = "./file1.txt";
char file2[100] = "./file2.txt";
char change1[100]="text1";
char change2[100]="text2";
printFiles(file1,file2,change1,change2);
return 0;
}
Hint for
That's probably just buffering. Do fflush(stdout); before you sleep. – melpomene
Thanks.
You can try this solution for delay.
#include <time.h>
#include <stdio.h>
void delay(double seconds)
{
const time_t start = time(NULL);
time_t current;
do
{
time(&current);
} while(difftime(current, start) < seconds);
}
int main(void)
{
printf("Just waiting...\n");
delay(3);
printf("...oh man, waiting for so long...\n");
return 0;
}
Following solution is pretty quite the same of previous one but with a clear terminal solution.
#include <time.h>
#include <stdio.h>
#ifdef _WIN32
#define CLEAR_SCREEN system ("cls");
#else
#define CLEAR_SCREEN puts("\x1b[H\x1b[2J");
#endif
void delay(double seconds)
{
const time_t start = time(NULL);
time_t current;
do
{
time(&current);
} while(difftime(current, start) < seconds);
}
int main(void)
{
printf("Just waiting...\n");
delay(2); //seconds
printf("...oh man, waiting for so long...\n");
delay(1);
CLEAR_SCREEN
return 0;
}

Thread Programming... No output in terminal

I m doing thread programming and trying to implement MonteCarlo technique for calculating Pi value in it. I compiled the code and I have no error but when I execute I get no output for it. Kindly correct me if there's any mistake.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define frand() ((double) rand() / (RAND_MAX))
#define MAX_LEN 1353
const size_t N = 4;
float circlePoints=0;
void* point_counter(void *param){
float xcord;
float ycord;
while(MAX_LEN){
xcord=frand();
ycord=frand();
float cord = (xcord*xcord) + (ycord*ycord);
if(cord <= 1){
circlePoints++;}
}
}
int main()
{
printf("out");
size_t i;
pthread_t thread[N];
srand(time(NULL));
for( i=0;i <4;++i){
printf("in creating thread");
pthread_create( &thread[i], NULL, &point_counter, NULL);
}
for(i=0;i <4;++i){
printf("in joining thread");
pthread_join( thread[i], NULL );
}
for( i=0;i <4;++i){
printf("in last thread");
float pi = 4.0 * (float)circlePoints /MAX_LEN;
printf("pi is %2.4f: \n", pi);
}
return 0;
}
You're hitting an infinite loop here:
while(MAX_LEN){
Since MAX_LEN is and remains non-zero.
As to why you see no output before that, see Why does printf not flush after the call unless a newline is in the format string?
You have an infinite loop in your thread function:
while(MAX_LEN){
...
}
So all the threads you create never come out that loop.
Also, circlePoints is modified by all the threads which will lead to race condition ( what's a race condition? ) and likely render the value incorrect. You should use a mutex lock to avoid it.
while(any_non_zero_number_which does_not_update)
{
infinite loop //not good unless you intend it that way
}

Resources