views:

130

answers:

5

In C++:

int main()
{
    cout << setfill('#') << setw(10) << 5 << endl;

    return 0;
}

Outputs:

#########5

Is there any setfill() alternative for C? Or how to do this in C without manually creating the string?

Thanks in advance.

+1  A: 

Not built in as standard

I would probably sprintf() the number to a string and get the count of characters then output the correct number of '#' first before printing the string.

Martin Beckett
A: 

The following will do it using memset in C assuming a 1-byte char. It still creates a 'string', though I'm not sure how manually you don't want it to be.

int main(void)
{

   char buf[MAX_LENGTH];

   memset(buf, '#', 10);
   buf[10]='\0';
   printf("%s5\n", buf);
}

Depending what you want to actually do with it, you could dynamically create the buffer to be the appropriate size and return it from a helper function if you so desire.

Dusty
No need to assume `sizeof (char) == 1`. The standard defines it as such. (What may change is number of bits, see CHAR_BIT.)
pmg
Assuming the 5 was a variable and not a literal 5 - that would output 10 '#' and then the number - the OP wants to print a field 10chars wide, left filled with #
Martin Beckett
Ah indeed, I didn't look closely enough. Then yeah, you're basically stuck determining the size of whatever you actually want, then combining it with something like the above to pad.
Dusty
+3  A: 
 int x= 5; 
 printf("%010d",x);

will output : 0000000005

Now if you really want '#' instead of '0' you'll have to replace them manually in the string.

Maybe :

char buf[11], *sp = buf; 
snprintf(buf, 11, "%10d", x); 
while( (sp = strchr(sp, ' ')) != '\0'){ *sp = '#'; }
puts(buf); 
Ben
The proper way to use `printf` to print a string variable is `printf("%s", buf);` Or better yet, use puts.
Ben Voigt
Alright, edited.
Ben
+2  A: 

No, there is no direct alternative.

But if you have a well-behaved snprintf (one that behaves as described by the C99 Standard), this works without creating a new string; creating only 2 temporary ints

#include <stdio.h>

int main(void) {
  int filler = '#'; /* setfill('#') */
  int width = 10;   /* setw(10)     */
  int target = 5;   /* 5            */

  /* ******** */
  int s = snprintf(NULL, 0, "%d", target);
  for (int i = 0; i < width - s; i++) {
    putchar(filler);
  }
  printf("%d\n", target);
  /* ******** */

  return 0;
}

EDIT: running version at ideone.


EDIT2: Differences between the C99 Standard's snprintf and Windows _snprintf (thank you for the link, Ben):

  • prototype: int snprintf(char *restrict buffer, size_t n, const char *restrict format, ...);
  • prototype: int _snprintf(char *buffer, size_t n, const char *format, ...);
  • snprintf writes no more than (n-1) bytes and a NUL
  • _snprintf writes no more than (n) bytes, the last of which may be NUL or other character
  • snprintf returns the number of characters needed for format (can be larger than n) or -1 in case of encoding error
  • _snprintf returns a negative value if n is not large for the string; or n if a NUL byte hasn't been written to buffer.

You can run the mis-behaving _snprintf in a loop, increasing n until you find the right value

/* absolutely not tested, written directly on SO text editor */
int i;
size_t rightvalue = 0;
char buffer[SOME_DEFAULT_VALUE];
do {
    if (sizeof buffer < rightvalue) /* OOPS, BIG BIG OOPS */;
    i = _snprintf(buffer, rightvalue, "%d", 42);
} while (i != rightvalue++);
/* rightvalue already has space for the terminating NUL */
pmg
`snprintf()` not found in VS2008. what is wrong with `snprintf`?
Donotalo
VS2008 is not a C99 compiler. Microsoft say so themselves. snprintf first appearance on the Standard was for C99, but it existed "in the wild" before that. Some of those "wild" versions do not work the same way described by the Standard. (I had the idea Windows had one of the mis-behaving "wild" versions)
pmg
It does: `_snprintf`, description here: http://msdn.microsoft.com/en-us/library/2ts7cx93.aspx
Ben Voigt
+1  A: 

Everybody wants to call printf twice... printf is one of the most expensive functions around.

Here:

char buffer[18] = "##########";
puts(buffer + snprintf(buffer+strlen(buffer), 8, "%d", 5));
Ben Voigt