C 语言有 setfill() 替代方案吗?

发布于 2024-09-26 05:20:34 字数 266 浏览 7 评论 0原文

在 C++ 中:

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

    return 0;
}

输出:

#########5

C 是否有任何 setfill() 替代方案?或者如何在 C 中执行此操作而无需手动创建字符串?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

享受孤独 2024-10-03 05:20:34
 int x= 5; 
 printf("%010d",x);

将输出:
0000000005

现在,如果您确实想要“#”而不是“0”,则必须在字符串中手动替换它们。

或许 :

char buf[11], *sp = buf; 
snprintf(buf, 11, "%10d", x); 
while( (sp = strchr(sp, ' ')) != '\0'){ *sp = '#'; }
puts(buf); 
 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); 
硬不硬你别怂 2024-10-03 05:20:34

不,没有直接的替代方案。

但是,如果您有一个行为良好的 snprintf (其行为符合 C99 标准所描述的),则无需创建新字符串即可工作;仅创建 2 个临时 int

#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;
}

编辑:在 ideone 运行版本。


EDIT2:C99 标准的 snprintf 和 Windows _snprintf 之间的差异(感谢您的链接,Ben):

  • 原型:int snprintf( char *限制缓冲区, size_t n, const char *限制格式, ...);
  • 原型: int _snprintf(char *buffer, size_t n, const char *format, ...); code>
  • snprintf 写入不超过 (n-1) 个字节,NUL
  • _snprintf 写入不超过 (n) 个字节,最后一个可能是 NUL 或其他字符
  • snprintf 返回格式所需的字符数(可以大于n)或-1,以防编码错误
  • _snprintf<如果 n 对于字符串来说不大,/code> 返回负值;或 n 如果 NUL 字节尚未写入缓冲区。

您可以在循环中运行行为不当的 _snprintf,增加 n 直到找到正确的值

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

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 */
柠檬 2024-10-03 05:20:34

每个人都想调用 printf 两次... printf 是最昂贵的函数之一。

这里:

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

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));
攒一口袋星星 2024-10-03 05:20:34

不是按照标准内置的,

我可能会 sprintf() 将数字转换为字符串并获取字符数,然后在打印字符串之前首先输出正确的“#”数量。

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.

丑丑阿 2024-10-03 05:20:34

下面将使用 C 中的 memset 来完成此操作(假设为 1 字节字符)。它仍然创建一个“字符串”,尽管我不确定您不希望它是多么手动。

int main(void)
{

   char buf[MAX_LENGTH];

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

根据您实际想要用它做什么,您可以动态创建适当大小的缓冲区,并根据需要从辅助函数返回它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文