tags:

views:

262

answers:

4

I have a situation where I have to print out a NUL character if there is no action in a part of my program. Take for example the code below:

char x = '\0';

...

printf("@%c@\n", x);

I want it to print this:

@@

but it prints out

@ @

Whats the correct way not to have the \0 character printed out a space as above?

+5  A: 
if (x == 0)
    printf("@@\n");
else
    printf("@%c@\n", x);

It's not actually printing a space, it actually outputs the \0. It's just that whatever you're viewing the text with is displaying the \0 as a space.

Dean Harding
Theres more to the code so I dont think method would suite me well
Steve Obbayi
+1  A: 

What system are you on? That code prints @@ for me. Here's my sample program:

#include <stdio.h>

int main(int argc, char *argv[])
{
  char x = '\0';
  printf("@%c@\n", x);
  return 0;
}

And my log:

$ make
cc -Wall -o app main.c
$ ./app 
@@
Carl Norum
Perhaps printf is undefined in that case, or incorrectly implemented on one of the systems?
Smashery
Try `./app | hexdump -C` (installing hexdump if necessary). You can see that it actually does output the NUL byte; the terminal just displays it as the lack of a character.
Tyler McHenry
Sure, of course it outputs that byte; but the output in the terminal window is still `@@`. It's the same as if you stuck a bell character in there (or anything else non-printing, I'd guess). Dunno why that's worth a downvote though.
Carl Norum
Surprisingly on windows a single space is added
Steve Obbayi
I didn't downvote you. Here, have an upvote to counter.
Tyler McHenry
@sobbayi, as others have mentioned, it's an effect of your terminal program, not of the program doing the printing.
Carl Norum
@Carl - what do you mean it's an effect of the terminal program? He want's no output if `x==0`, not output that's invisible if looking at it the right way. In other words, if the output were piped to a file no '\0' character should be embedded in the file.
Michael Burr
A: 

Slightly more compact form of @codeka's solution:

#include <stdio.h>

int main(void) {
    char x = '\0';
    printf(x ? "@%c@\n" : "@@\n", x);
    return 0;
}
Sinan Ünür
Is `printf("@@\n", x);` allowed?
Alok
Alok: Yes. The standard says: "If the format is exhausted while arguments remain, the excess arguments areevaluated (as always) but are otherwise ignored."
caf
FYI 7.19.6.1 in WG14/N1124
Sinan Ünür
@caf, @Sinan, thanks.
Alok
A: 

You could use the %s specifier with a precision of 1:

printf( "@%.1s@", &x);

This would treat the data in x as '\0' terminated string, but would only ever print at most a single character, so it doesn't matter that there's no '\0' terminator after the character. If x == 0 then it's an empty string, so nothing is printed between the '@' characters.

Of course if you do this you have to pass a pointer to the character rather than the character itself (hence the &x).

Kind of hacky, but I think still within acceptable bounds for the problem.

Michael Burr