问题
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?
回答1:
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 int
s
#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 charactersnprintf
returns the number of characters needed for format (can be larger thann
) or-1
in case of encoding error_snprintf
returns a negative value ifn
is not large for the string; orn
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 */
回答2:
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);
回答3:
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));
回答4:
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.
回答5:
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.
来源:https://stackoverflow.com/questions/3867633/is-there-any-setfill-alternative-for-c