Is there any setfill() alternative for C?

喜欢而已 提交于 2019-12-20 01:05:58

问题


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 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 */



回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!