如何使用printf重复字符?


79

我想做一些printf("?", count, char)重复角色count时间的事情。

什么是完成此操作的正确格式字符串?

编辑:是的,很明显,我可以printf()循环调用,但这就是我想要避免的事情。


2
你打算要几个?
WhozCraig

4
不知道编译时的计数并不是编写循环的障碍。
基思·汤普森

您的问题很明确(真正的答案是没有一种printf格式可以满足您的要求),但是您的评论使我不确定您要问什么。您谈论的是格式字符串和传递给函数的参数。您要问什么功能?似乎有些事情您没有告诉我们。
基思·汤普森

@KeithThompson我为'printf'编写了一个包装器,因此这些参数与原始参数相同,对于造成的混淆,我们深表歉意。我应该已经描述了需要更好的理由,您是对的。
Muis

恐怕我仍然不清楚您要做什么,或者(@synthesizerpatel没有冒犯)为什么您接受所做的回答,但这并不是认真的解决方案。
基思·汤普森

Answers:


62

简短答案-是,长答案:不是您想要的。

您可以使用%*形式的printf,它接受可变的宽度。而且,如果您使用“ 0”作为要打印的值,请结合使用左对齐零填充的右对齐文本。

printf("%0*d\n", 20, 0);

产生:

00000000000000000000

我的舌头紧紧地贴在脸颊上,我提供了这个恐怖的小片段代码。

有时候,您不得不做一些糟糕的事情以记住为什么其余时间会如此努力。

#include <stdio.h>

int width = 20;
char buf[4096];

void subst(char *s, char from, char to) {
    while (*s == from)
    *s++ = to;
}

int main() {
    sprintf(buf, "%0*d", width, 0);
    subst(buf, '0', '-');
    printf("%s\n", buf);
    return 0;
}

3
我不清楚自己在想什么,但是在您的代码中上限是4096。我想您可以malloc缓冲一下。
基思·汤普森

2
很公平。刀战==避免了!
synthesizerpatel

4
这种样式比直接在循环中分配char更为糟糕。
liuyang1

2
是的 这种方法很糟糕,但确实回答了OP的问题。
synthesizerpatel

2
您能说明恐怖表演的意思吗?我觉得您正在尝试警告某些问题,但是我不确定是什么...您是否只是在指出使用“%*”时发生溢出的危险?
cheshirekow

117

您可以使用以下技术:

printf("%.*s", 5, "=================");

它将打印出来。"=====" 它在Visual Studio上对我有用,没有理由在所有C编译器上都不起作用。


3
不幸的是,考虑到它不仅是正确的而且可以跨平台工作,因此该答案的评分还没有更高。已在OSX,Linux和OpenBSD以及C语言以及Perl(封装了C语言printf)中进行了测试
synthesizerpatel

3
谢谢,我记得10年前做过,但是忘记了,然后重新发现了。
rep_movsd

19
这不是完全灵活的。如果宽度大于字符串本身,则打印宽度不会超过字符串(至少在我对gcc的简单实验中没有)。
Mats Petersson,

1
这比synthesizerizerpatel的答案更好。当我尝试使用空格而不是零并且宽度为零时,仍然打印单个空格。这不是。
黑色

1
好赶上!@rep_movsd
Juan Diego Godoy Robles

24

如果您将自己限制为重复0或空格,则可以执行以下操作:

对于空格:

printf("%*s", count, "");

对于零:

printf("%0*d", count, 0);

18

在C ++中,您可以使用std :: string获取重复字符

printf("%s",std::string(count,char).c_str());

例如:

printf("%s",std::string(5,'a').c_str());

输出:

aaaaa

15
问题是关于C,而不是C ++。
基思·汤普森

9
尽管不是严格的C语言,但这对我有所帮助。谢谢
波特兰赛跑者


12

哪有这回事。您必须使用printf或编写一个循环puts,或者编写一个将字符串计数时间复制到新字符串中的函数。


2
很奇怪,我可以使用最复杂的表达式,但是不支持诸如重复字符之类的简单操作。
Muis

为什么?您只需在要重复的内容周围添加一个循环即可完成此操作。printf所做的大部分事情都是您无法用自己的代码完成的事情[非常容易]。让库做困难的事情,让应用程序做简单的事情,我认为这就是这里的主题。
Mats Petersson

5
而且,如果您对此感到强烈,我想C标准委员会会对改进的建议感兴趣,并且在glibc中进行示例实现可能会增加它成为标准的机会。如果您实施它,也许其他人会认为这是一个好主意。自从首次引入printf以来,它才失踪了近50年,所以这可能只是一个疏忽……;)
Mats Petersson

@MatsPetersson那没办法,因为我事先不知道格式字符串,请参阅我对Mokammel的回复。
Muis

2
为什么要对此一票否定-如果您对这个答案不满意,请让我知道您对此不满意...
Mats Petersson

6

printf不会这样做-并且printf对于打印单个字符来说过于刻板。

char c = '*';
int count = 42;
for (i = 0; i < count; i ++) {
    putchar(c);
}

不必担心这种效率低下的问题。putchar()缓冲其输出,因此除非需要,否则不会为每个字符执行物理输出操作。


我不知道将传递给我的函数的格式字符串或参数,它们可以从xml文件中读取或由用户输入。
Muis

您有字符和需要打印的次数,对吗?您还需要什么信息?要使用打印单个字符printf,格式字符串为"%c"。但是您不需要使用printf,在这种情况下,您根本不需要格式字符串。(根本没有printf格式字符串可以多次打印字符,但是还有其他更好的方法可以完成此任务。)
Keith Thompson

就像我说的,我不知道函数的参数代表什么。假设我从XML文件中读取了格式字符串和参数,并将它们传递给printf(),我的函数将如何知道它需要循环并且第二个参数代表一个计数?这就是我的意思是在编译时不知道我的输入。
Muis

4
@Joshua:什么函数的参数?您的问题甚至没有提到函数。
基思·汤普森

1
@Joshua,您真的很困惑,这是因为您过度使用了编译时间和函数“将要知道”。实际上,这并不像您使它看起来那样困难。您需要一个函数来打印字符“ x” n次。如果它来自xml,则解析xml并找出要打印的字符以及需要打印多少次。使用strlen可以在xml字符串字段确定需要打印字符“ x”多少次的地方获得字符串长度。
SayeedHussain

6

如果您有一个支持alloca()函数的编译器,那么这可能是解决方案(尽管很丑):

printf("%s", (char*)memset(memset(alloca(10), '\0', 10), 'x', 9));

它基本上在堆栈上分配10个字节,并用'\ 0'填充,然后前9个字节用'x'填充。

如果您有C99编译器,那么这可能是一个更整洁的解决方案:

for (int i = 0;  i < 10;  i++, printf("%c", 'x'));

4
我建议putchar('x')而不是printf("%c", 'x')
Paddu 2014年

为什么?执行时间更少吗?
71GA,

4
#include <stdio.h>
#include <string.h>

void repeat_char(unsigned int cnt, char ch) {
    char buffer[cnt + 1];
    /*assuming you want to repeat the c character 30 times*/
    memset(buffer,ch,cnd); buffer[cnt]='\0';
    printf("%s",buffer)
}

2

您可以创建一个函数来完成这项工作并使用它

#include <stdio.h>

void repeat (char input , int count )
{
    for (int i=0; i != count; i++ )
    {
        printf("%c", input);
    }
}

int main()
{
    repeat ('#', 5);
    return 0;
}

这将输出

#####

2
putchar()更适合repeat()循环
rsaxvc

的确如此,但是我试图使我的代码变得非常基础,以使其对任何入门级编码器都
难以理解

使用会更好i < count。否则,计数的负输入可能会导致大量不必要的打印。
ワイきんぐ

1
printf("%.*s\n",n,(char *) memset(buffer,c,n));

n<= sizeof(buffer)[也许也n <2 ^ 16]

但是,优化器可能会将其更改为puts(buffer),然后缺少EoS将会...

并且假定memset是汇编程序指令(但是在芯片上仍然是循环)。

严格地看,给定前提条件'No loop'是没有解决方案的。


0
char buffer[41];

memset(buffer, '-', 40);    // initialize all with the '-' character<br /><br />
buffer[40] = 0;             // put a NULL at the end<br />

printf("%s\n", buffer);     // show 40 dashes<br />

-2

我想这样做。

void printchar(char c, int n){
     int i;
     for(i=0;i<n;i++)
         print("%c",c);
}

printchar("*",10);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.