I'm trying to do a naive implementation of the C-standard function printf. So far I've just written some testing code to help me better understand the use of variable arguments lists. However, I don't know why my output contains an extra line.
Here is my code:
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
void print_test_helper(char *string, va_list args)
{
while (*string)
{
if (*string == '%')
{
string = string + 2; //increment pointer by two spots to "\n"
printf("%s", (va_arg(args, char*)));
}
else
{
write(1, &*string, 1);
string++;
}
}
}
void print_test(char *string, ...)
{
va_list ap;
va_start(ap, string);
print_test_helper(string, ap);
}
int main()
{
print_test("this is a %s\n", "string");
return 0;
}
The way I see it, my print_test_helper should keep writing the string passed to it up until it sees the '%' character, after which it skips two spots to the newline character. The function then calls the printf method to simply printout the argument held in the list, but the output is like so:
this is a
string
As you can see, it contains a new line. Any ideas why?
Edit:
changing the line printf("%s", va_arg(args, char*)) to write(1, va_arg(args, char*), 6); produces the expected behavior. Is this an issue with the interaction between write and printf?
Edit 2:
See the answer below!
#Achal pointed me in the right direction about buffering in the printf. As far as I can tell according to this stack overflow post, printf isn't guaranteed to print to the console unless a few conditions are met. A few of those namely being an fflush, a program exit, or a newline.
In my case, the function was writing out every character to the stdout (write is not buffered) and when it encountered the "%s\n", printf was doing its job, only it was buffered. So my assumption is that when "\n" gets written to the stdout, printf realizes it needs to dump its buffer and it does so, only after write puts down the newline.
As mentioned by #M.M it's not a good idea to mix write and printf and I guess this post is testament to that. I didn't intend to end up with it like that though, I was simply using printf for testing since I was lazy, but I ended up learning more about how it works. Cheers.
Related
I am trying to print an element of the cube_pattern string, but when I execute my code nothing is printed to the console and my code freezes for a few seconds:
#include <stdio.h>
#define SOLVED_CUBE "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB"
char cube_pattern[54] = SOLVED_CUBE
void print_pattern() {
printf("%s", cube_state[0]);
}
void main() {
print_pattern();
}
I tried calling fflush(stdout) but it still doesn't work:
void print_pattern() {
printf("%s", cube_state[0]);
fflush(stdout);
}
"UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB" contains 54 characters. Your char array only can store 54 characters. This does not leave space for a null terminator. Thus when you try to print using the %s specifier, you invoke undefined behavior. Maybe when it looks for the 55th character, it finds 0, but maybe not.
I don't see that using #define gains you anything. I would simply:
char cube_pattern[] = "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
Your code has multiple errors. First, you have multiple typos. For example, cube_state should be cube_pattern. Second, you are using the printf() formatter %s, but only passing it one character (cube_pattern[0]). Lastly, your array is only 54 bytes long, but your string needs 55 bytes (54 characters + one NULL character).
This code works for me:
#include <stdio.h>
char cube_pattern[55] = "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
void print_pattern() {
printf("%s\n", cube_pattern);
}
int main() {
print_pattern();
}
I have also changed printf("%s", cube_pattern); to printf("%s\n", cube_pattern);. Adding a new line will flush the buffer if your output is line-buffered, which is generally what you want. Alternatively, you could also use fflush(stdout).
I am trying to print something on the console just by using the syscall write(). So far, it is more difficult than I thought.
The function is kept simple:
void writeOutput(char a, int64_t b, uint8_t c) {
char bNew[]; // what should be the size of that array=
while(b != 0x0000000000000000) {
int leftover = b%10;
bNew[i] = intToChar(leftover);
b = b/10;
i++;
}
}
char intToChar(int num) {
return '0' + num;
}
a should be formatted as char, b as a decimal number and c as an octal number.
For example a possible input is:
writeOutput('a', -0xffff, 17); // ouput is "a -65535 21"
The the printed arguments should be separated by spaces and terminated by a newline to standard output. Also, I am trying to do that without the the functions of the sprintf-family. This makes it a little bit trickier.
EDIT: My question is: How is it possible to do that with write()? (Sry, missed that!)
The code is online.
EDIT2: My main problem is doing it without using the sprintf-family. I hoped you might help me.
you can call the write() with first argument which is an fd as stdout. it will write to the stdout and which is your console. but before that you need have a string buffer for that you can use sprintf' orsnprintfwith the same formatting asprintf`. but the printf way is easier and it should serve the purpose unless you have some very special use case.
#include <unistd.h>
int main(void) {
write(1,"Hello World!", 12);
return 0;
}
I want to input text from stdin and then display it on the screen, while numbering the lines. The last part of my program is not working, I don't know how to use the read() function correctly.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#include <string.h>
int main()
{
char s[201];
int i=0, f = open("text.dat", O_RDWR | O_CREAT | O_TRUNC);
while (fgets(s,200,stdin) != NULL)
write(f,s,strlen(s));
char *buf;
while (read(f,buf,200) > 0)
printf("%d %s", i++, *buf);
close(f);
return 0;
}
First of all you consume stdin:
while (fgets(s,200,stdin) != NULL)
write(f,s,strlen(s));
Then you attempt to read from the file f. However, the file f is already at its end, and so the first call to read() returns 0. Since there is nothing to read. You would need to move the file pointer back to the beginning of the file.
But your read() based loop will still not do what you want. That's because you want line oriented input. So you should use fgets rather than read. Just in the same way that you handled stdin in a line oriented way, you need to handle your printing to stdout.
And as Mats points out, you never allocated buf. So if there had been anything to read, you would be de-referencing an un-initialized pointer.
Having said all of that, it would seem to me to make more sense to run just a single loop. Call printf() inside the loop that calls write().
while (fgets(s,200,stdin) != NULL)
{
write(f,s,strlen(s));
printf("%d %s", i, s);
i++;
}
Weird output: I would have thought that this portion would crash pretty badly:
char *buf;
while (read(f,buf,200) > 0)
printf("%d %s", i++, *buf);
buf is not initialized to anything, and thus points "over there" (general direction of "nowhere useful"). This would cause a SIGSEGV ("Segmentation fault") in a Linux/Unix system, I would expect. You are not using a Turbo/Borland C under DOS by any chance - that's the only scenario where I could possibly imagine that this wouldn't crash. Windows wouldn't say SIGSEGV, but it would still not allow your code to work.
Of course, you may be saved by the fact that you are at the end of the file, and thus don't read anything at all.
Perhaps you meant this:
char buf[200];
while (read(f,buf,200) > 0) ....
I have a very simple program to print the chars in a string but for some reason it is not working:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void * print_chars(char *process_string) {
int i;
int string_len;
string_len = strlen(process_string);
printf("String is %s, and its length is %d", process_string, string_len);
for(i = 0; i < string_len; i++) {
printf(process_string[i]);
}
printf("\n");
}
int main(void) {
char *process_string;
process_string = "This is the parent process.";
print_chars(process_string);
return 0;
}
When I run it in Netbeans, I get the following:
RUN FAILED (exit value 1, total time: 98ms)
If I remove the line
printf(process_string[i]);
the program runs but nothing prints out to the console (obviously).
Any ideas what I'm missing here?
You need a format in the line
printf(process_string[i]);
i.e.
printf("%c", process_string[i]);
There are a couple of problems.
One is that you're not seeing any output from the printf("String is %s, and its length is %d", ...). This is because standard output is line buffered by default, and you are not including a newline, so it never actually decides that there's a line ready to print. If you change the format string to add a \n, you will see the output from this command.
The second is that you are passing a char into the first argument of printf(), where it expects a char *. This causes it to crash, as it tries to interpret that character as a pointer. You want to pass something like printf(process_string) instead. However, it's generally a bad idea to pass a variable string directly into the first argument of printf(); instead, you should pass a format string that includes %s, and pass the string in as the corresponding argument: printf("%s\n", process_string). Or, if you want to print it character by character, printf("%c", process_string[i]), followed by a printf("\n") to flush the buffer and actually see the output. Or if you're doing it character by character, putchar(process_string[i]) will be simpler than printf().
printf() expects, as first parameter, a pointer to char. What you are passing is a char, not a pointer to one.
Anyway, printf() is not the function to use here. Try putc()...
This is my source code:
#include <stdio.h>
#include <string.h>
void main()
{
int broj_znakova,i=0;
char niz1[81],niz2[81];
printf("Enter something, for end Ctrl/c \n\n");
while(fgets(niz1,81,stdin)!=NULL)
{
continue;
}
printf("You just enter: %s \n",niz1);
printf("This string is long %d\n",(strlen(niz1)-1));
strcpy(niz1,niz2);
printf("niz2 is %s\n",niz2);
if(strcmp(niz1,niz2)==0)
{
printf("niz1 and niz2 is same\n");
}
else
{
printf("niz1 != niz2\n");
}
while(niz1[i]!='\n')
{
if(niz1[i]==' ')
{
broj_znakova ++;
i=i+1;
}
}
printf("Spaces in string = %d\n",broj_znakova);
}
When i press Ctrl/c i got a bunch of strange characters, can someone help???
I google something about flushing but i'm new :)
The contents of niz2 is not initialized. It will result in undefined behavior. Perhaps you meant to copy niz1 to niz2. If so, then you need to reverse the parameters in the strcpy call. With strcpy, the first parameter is the target.
Note too that the variable broj_znakova is never initialized.
C does not "zero out" information in memory (in general) so when it allocates variables, you get whatever is there in memory at the time (whether it is logically readable as words or not), if you are printing something without the system knowing this is a string then it will keep printing until it encounters a NULL terminating character, if there is none, it tries to print whatever is in memory and this produces the weird characters.
On this line
strcpy(niz1,niz2);
I believe your parameters are reverse, it should be strcpy(niz2, niz1); The strange characters you are seeing is because niz2[81] has memory allocated, but it's not "filled in". So you get whatever 'magical' data that allocation may contain. That is, until you put something in it, or do memset, etc.