Why the command \r in printf() doesn't work? - c

I'm trying to update a text on the terminal without have to print again the text. Right now I'm trying to do it on a simple code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[]){
for(int i=0;i<=100;++i){
printf("\r[%3d%%]",i);
sleep(1);
}
printf("\n");
return 0;
}
The code literally print nothing, with the pointer blinking at the start of the line.
Can someone help me?

The standard output stream is typically line buffered, so if you don't print a newline (i.e. \n) then the output will remain in the buffer.
After calling printf, call fflush(stdout);. This will flush the standard output stream so that you can see the text.

Related

C - Redirecting awk/sed stdout to pipe doesn't work

So I have an exercise to do, and one part of this exercise requires us to execute a command passed as an argument, be able to pass it some strings on stdin, and get its output on stdout and stderr.
How I did it, I need to redirect the stdout and stderr (of the child, which is gonna call an exec) to a couple of pipes (other end of the pipes is held open by the parent).
I managed to do it, when I ask it to execute bash and send it "ls", it gives me what i want, where i want it. Same with cat and others.
Problem is, when I try executing awk or sed, nothing is ever written on the pipe. Ever.
If i leave stdout untouched, it does print it how it should. But as soon as i redirect the stdout, nothing.
I tried everything, select(), wait(), sleep() (even though it's not allowed). Nothing seems to work.
I made a minimum working example of what i mean (clearly, it lacks of conventions and mindful writing, as free() and close(), but it does it's job) which Is the one I'm attaching. The code works when i call it like this:
./program $(which bash)
It prompts for something, i write "ls" and it gives me the result expected
but when i try
./program $(which awk) '{print $0;}'
I get nothing at all
Here's the code (minimum working example):
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
int main(int argc, char* argv[]){
int fdStdinP[2],fdStdoutP[2];
char *string,*array[3];
array[0]=argv[1];
array[1]=argv[2];
array[2]=0;
pipe(fdStdinP);
pipe(fdStdoutP);
int pid=fork();
if(pid==0){
close(fdStdinP[1]);
close(fdStdoutP[0]);
dup2(fdStdinP[0],0);
close(fdStdinP[0]);
dup2(fdStdoutP[1],1);
close(fdStdoutP[1]);
//as suggested, the file descriptors are now closed
execvp(argv[1],array);
perror("");
return 0;
}
close(fdStdinP[0]);
close(fdStdoutP[1];
string=calloc(1024,sizeof(char));
read(0,string,1024);
write(fdStdinP[1],string,1024);
free(string);
string=calloc(1024,sizeof(char));
read(fdStdoutP[0],string,1024);
printf("I have read:%s",string);
return 0;
}
Thank you for your time.
Awk continues to wait for input and buffers its output, so appears to hang. Closing the sending end will tell awk that it's input has ended so that it will end and flush its output.
write(fdStdinP[1],string,1024);
close(fdStdinP[1]); // just added this line.

how to use unicode blockelements in C?

I want to use unicode blocks in my C program to display them in the console like ▇, ░ and so on. However, whenever I try to use the escape sequence for unicode characters, I only get weird letters like:
printf("/u259A"); //259A is the unicode for ▚
Output: ÔûÜ
I looked up how to include unicode charactes then tried to use wchar_t:
#include <locale.h>
#include <stdio.h>
int main(int argc, char const *argv[]) {
setlocale(LC_ALL, "");
wchar_t c = "\u259A";
printf("%c",c);
return 0;
}
but that only gave me ☺ as the output instead of ▚. Removing setlocale() would give me a blank output. I dont know what do to from this point on. The only thing I saw was using printf("\xB2"); which gave you ▓. But I dont understand where the B2 comes from or what it stands for.
So what worked for me was the following:
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
int main(int argc, char const *argv[]) {
_setmode(_fileno(stdout), _O_U16TEXT);
wprintf(L"\x2590 \x2554 \x258c \x2592"); //Output : ▐ ╔ ▌ ▒
return 0;
}
the function _setmode() is apparently for setting the console on u16 text encoding. wprintf() allows you to print wide characters (unicode aswell). The L"" before the string indicates to the compiler, that the following string is a unicode string. Thanks to everyone for their time and answers!

Instant write buffer to stdout

Is possible to write a large block of text into stdout all at once.
For instance, I get a 50kb text file and put it into story.txt. I am curious if I can dump the contents of this file into stdout without the user noticing any text slowly coming in. One moment there is no text, next the whole buffer is flushed into stdout.
I was trying to do it with the following code but no matter what buffering mode I set it didn't manage to write the file all at once, only in parts.
/* dumps a lot of text at once */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
char story[100000];
char buffer[100000];
int main(int argc, char **argv)
{
FILE *handle = fopen("coolstory.txt", "r");
size_t n = fread(&story[0], 1, 100000, handle);
fclose(handle);
/* try to flush all at once... */
fclose(stdout);
freopen("/dev/tty", "w", stdout);
setvbuf(stdout, &buffer[0], _IOFBF, 100000);
fwrite(story, n, 1, stdout);
fflush(stdout);
printf("\nread %u bytes.\n", n);
return 0;
}
The reopen part was me wondering if setvbuf/flush would behave differently if I called them right after the stdout was opened. Unfortunately it did nothing.
I just want to know whether it is possible, and if not, why.
I'm on ubuntu linux 14.04.
Note: it is usually a bad idea to #include header files that are not used.
I ran this version of the code:
/* dumps a lot of text at once */
//#include <unistd.h>
#include <stdio.h>
//#include <stdlib.h>
//#include <fcntl.h>
//#include <string.h>
char story[100000];
int main( void )
{
FILE *handle = fopen("value_chainLength.txt", "r");
size_t n = fread(story, 1, 100000, handle);
fclose(handle);
fwrite(story, n, 1, stdout);
fflush(stdout);
printf("\nread %lu bytes.\n", (long unsigned)n);
return 0;
}
on a 46550749 byte text file
The output was done on a terminal almost as fast as I could press and release the 'enter' key.
the last line output was:
read 100000 bytes.
I did notice ever so slight a hesitation before printing the last line, all the lines before that point were practically instantaneous.

Why do std::cout and printf() not print between usleep() delays?

i have a program that is supposed to print "Hello, World!" in slowly scrolling text. I am using the unistd.h library for the usleep() function, and i'm using std::cout to print the characters to the standard output:
#include <iostream>
#include <stdio.h>
#include <unistd.h>
char hello[13]={'H','e','l','l','o',',',' ','W','o','r','l','d'};
int main (){
for(int i=0; i<14; i++){
std::cout<<hello[i]; //it prints the entire string after
usleep(100000); //100000 ms, but it should print a char after
} //every 100 ms.
}
You might need to flush the output stream.

Wrong printing when using signal handler

I have encountered problems on signal handling when writing a shell-like program on C.
Here is the simplified version of my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define SIZE 255
void sig_handler(int sig){
if (sig == SIGINT)
printf("\n[shell]$\n");
}
int main()
{
char input[SIZE];
printf("[shell]$");
signal(SIGINT,sig_handler);
while( gets(input) != NULL ){
// code of the shell including command interpreter and command execution
printf("[shell]$");
}
return 0;
}
When I run the program and try out SIGINT with command - "cat", the output shows as the following:
[shell]$ ^C (ctrl+C pressed for the first time)
[shell]$
^C (the input position go to the next line, which is unwanted)
[shell]$
cat (I want it in the same line with [shell]$)
^C
[shell]$
[shell]$ (duplicate printing occurs)
I have tried to modify the function void sig_handler(int sig) by deleting the second \n. However, the situation becomes worse than before. The program doesn't automatically trigger the signal event on the first pressing of ctrl+C.
To clarify my problem, here are the two questions I ask:
1. How to make the input position on the same line with [shell]$ ?
2. How to solve the duplicate printing problem ?
What #zneak said is true, you can use fflush and delete the second \n in sig_handler,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define SIZE 255
void sig_handler(int sig){
if (sig == SIGINT)
printf("\n[shell]$");
fflush(stdout);
}
int main()
{
char input[SIZE];
printf("[shell]$");
fflush(stdout);
signal(SIGINT,sig_handler);
while( gets(input) != NULL ){
// code of the shell including command interpreter and command execution
printf("[shell]$");
}
return 0;
}
First and foremost, printing from signal handler is a bad idea. Signal handler is like an interrupt handler - it happens asynchronously, it could be raised while being inside your standard library code and calling another stdlib routine might mess up with non-reentrant internals of it (imagine catching SIGINT while inside of printf() in your loop).
If you really want to output something from within, you better use raw write() call to stderr file descriptor.

Resources