我需要将C中的一系列数字与 printf()对齐,如下例所示:
-------1
-------5
------50
-----100
----1000
当然,所有这些之间都有数字,但它与手头的问题无关......哦,将破折号视为空格,我使用破折号,因此更容易理解我想要的东西。
我只能这样做:
----1---
----5---
----50--
----100-
----1000
或者这个:
---1
---5
--50
-100
1000
但这些都不是我想要的,我只能使用printf()来实现第一个例子中显示的内容。它有可能吗?
修改
对不起的人,我匆忙,并没有很好地解释自己...我的最后一个例子和你的所有建议(使用类似“%8d”的东西)不起作用,因为虽然最后一个数字是1000但它没有为此,必须一直到1000甚至100或10。
无论要显示的位数,我最多只需要4个前导空格作为最大数字。假设我必须显示1到1000(A)和1到100(B)之间的数字,我使用“%4d”这两个数字,这将是输出:
答
---1
....
1000
我想要的输出是什么......
B:
---1
....
-100
这不是我想要的输出,我实际上想要这个:
--1
...
100
但就像我说的那样,我不知道我必须打印的确切数字,它可以有1位数,它可以有2个,3个或更多,该功能应该为所有人准备。我想要四个额外的前导空间,但这并不相关。
编辑2: 似乎我想要的东西,我需要它的方式,这是不可能的(检查David Thornley和Blank Xavier的答案以及我的评论)。谢谢大家的时间。
答案 0 :(得分:46)
为什么printf("%8d\n", intval);
不适合你?它应该......
您没有显示任何“不工作”示例的格式字符串,因此我不确定还能告诉您什么。
#include <stdio.h>
int
main(void)
{
int i;
for (i = 1; i <= 10000; i*=10) {
printf("[%8d]\n", i);
}
return (0);
}
$ ./printftest
[ 1]
[ 10]
[ 100]
[ 1000]
[ 10000]
编辑:对澄清问题的回应:
#include <math.h>
int maxval = 1000;
int width = round(1+log(maxval)/log(10));
...
printf("%*d\n", width, intval);
宽度计算计算日志基数10 + 1,它给出了位数。花哨的*
允许您将变量用于格式字符串中的值。
你仍然必须知道任何特定跑步的最大值,但是在任何语言或铅笔中都没有办法解决这个问题。纸。
答案 1 :(得分:45)
在我方便的Harbison&amp; amp;斯蒂尔....
确定字段的最大宽度。
int max_width, value_to_print;
max_width = 8;
value_to_print = 1000;
printf("%*d\n", max_width, value_to_print);
请记住,max_width必须是int
类型才能使用星号,并且您必须根据您想要拥有的空间来计算它。在您的情况下,您将必须计算最大数字的最大宽度,并添加4。
答案 2 :(得分:3)
printf("%8d\n",1);
printf("%8d\n",10);
printf("%8d\n",100);
printf("%8d\n",1000);
答案 3 :(得分:1)
尝试转换为字符串,然后使用“%4.4s”作为格式说明符。这使它成为固定宽度格式。
答案 4 :(得分:0)
那么,你想要一个带有空格的8字符宽字段作为填充?试试“%8d”。 Here's a reference
编辑:您尝试做的事情不仅仅是printf可以处理的事情,因为它不知道您编写的最长数字是什么。在执行任何printfs之前,您需要计算最大数字,然后计算出要用作字段宽度的位数。然后你可以使用snprintf或类似的方法在现场制作printf格式。
char format[20];
snprintf(format, 19, "%%%dd\\n", max_length);
while (got_output) {
printf(format, number);
got_output = still_got_output();
}
答案 5 :(得分:0)
据我所知,你想要的填充量会根据你拥有的数据而有所不同。因此,唯一的解决方案是在打印前扫描数据,找出最宽的数据,然后找到一个可以使用asterix运算符传递给printf的宽度值,例如
loop over data - get correct padding, put into width
printf( "%*d\n", width, datum );
答案 6 :(得分:0)
如果您无法提前知道宽度,那么您唯一可能的答案将取决于将您的输出暂存在某种临时缓冲区中。对于小型报告,只收集数据并推迟输出直到输入有界是最简单的。
对于大型报告,如果收集的数据超出合理的内存范围,则可能需要中间文件。
获得数据后,可以使用每个值的惯用语printf("%*d", width, value)
将其后处理到报告中。
或者,如果输出通道允许随机访问,您可以继续编写一个假设(短)默认宽度的报告草稿,并在违反宽度假设的任何时候搜索并编辑它。这也假定您可以以某种无害的方式填充该字段之外的报表行,或者您愿意通过读取 - 修改 - 写入过程替换目前的输出并放弃草稿文件。
但除非你能提前预测正确的宽度,否则如果没有某种形式的双遍算法,就不可能做到你想要的。
答案 7 :(得分:0)
查看已修改的问题,您需要找到要显示的最大数字中的位数,然后使用printf()
生成sprintf()
格式,或使用%*d
生成*
格式作为snprintf()
的int传递的数字位数,然后是值。一旦你获得了最大的数字(并且你必须提前确定),你可以用'整数对数'算法确定数字的位数(在你到零之前可以除以10的次数),或者通过使用缓冲区长度为零的%d
,格式{{1}}和字符串为null;返回值告诉您格式化了多少个字符。
如果您不知道并且无法确定其出现之前的最大数量,那么您就会被嘲笑 - 您无能为力。
答案 8 :(得分:0)
#include<stdio.h>
int main()
{
int i,j,n,b;
printf("Enter no of rows ");
scanf("%d",&n);
b=n;
for(i=1;i<=n;++i)
{
for(j=1;j<=i;j++)
{
printf("%*d",b,j);
b=1;
}
b=n;
b=b-i;
printf("\n");
}
return 0;
}
答案 9 :(得分:0)
[我意识到这个问题已有一百万年的历史了,但是在本质上还有一个(或两个)关于OP,编程教育学和假设制定的更深层次的问题。]
包括mod在内的一些人认为这是不可能的。而且,在某些情况(包括最明显的情况)中,确实如此。但是有趣的是,这对于OP并不是立即显而易见的。
不可能是假设contex在面向行的文本控制台(例如console + sh或X-term + csh或Terminal + bash)上运行从C编译的可执行文件,这是一个非常合理的假设。但是,“正确”的答案(“ %8d
”)对于OP来说还不够好,而且也不是很明显,这一事实表明附近有很多蠕虫……
考虑“诅咒”(及其多种变体)。在其中,您可以 导航“屏幕”,并“移动”光标,并“重绘”基于文本的输出的部分(窗口)。在诅咒的背景下,绝对有可能做到。即动态调整“窗口”的大小以容纳更大的数字。但是,即使Curses也只是屏幕上的“绘画”抽象。没有人建议这样做,也许是正确的,因为在C中使用Curses实现 并不意味着它是“严格地C”。很好
但这到底是什么意思?为了使响应:“不可能”是正确的,这意味着我们要说一些有关运行时系统的信息。换句话说,这不是理论上的(例如,“如何对int
s的静态分配数组进行排序?”),这可以解释为完全忽略任何方面的“封闭系统”运行时。
但是,在这种情况下,我们有I / O:具体来说就是printf()
的实现。但这是一个机会,可以说出一些更有趣的回应(尽管,诚然,提问者可能还没有对此进行深入研究)。
假设我们使用一组不同的假设。假设OP合理地“聪明”,并且了解到不可能在面向行的流上编辑先前的行(如何校正行式打印机输出的字符的水平位置?)。还假设OP不仅仅是一个从事家庭作业的孩子,并且没有意识到这是一个“技巧”问题,目的是挑逗对“流抽象”含义的探索。进一步,让我们假设OP在想:“等等……如果C的运行时环境支持STDOUT的想法-如果STDOUT只是一个抽象,那么为什么拥有1)可以进行的终端抽象就不那么合理呢?垂直滚动,但2)支持可定位的光标?两者都是在屏幕上移动文本。“
因为如果那个是我们要回答的问题,那么您只需要看一下:
看到:
几乎所有视频终端制造商都添加了特定于供应商的转义序列,以执行诸如将光标置于屏幕上任意位置的操作。一个示例是VT52终端,该终端通过发送ESC字符,Y字符,然后发送两个数字,分别代表数字值,该数字值等于x,y位置加上32,从而将光标放置在屏幕的x,y位置(因此,从ASCII空格字符开始,避免使用控制字符)。 Hazeltine 1500具有类似的功能,使用〜,DC1调用,然后使用逗号将X和Y位置分开。虽然这两个终端在这方面具有相同的功能,但必须使用不同的控制序列来调用它们。
第一个支持这些序列的流行视频终端是1978年推出的Digital VT100。该模型在市场上非常成功,它引发了各种各样的VT100克隆,其中最早的也是最受欢迎的是1979年推出价格适中的Zenith Z-19。其他产品包括Qume QVT-108,Televideo TVI-970,Wyse WY-99GT以及可选的“ VT100”或“ VT103”或“ ANSI”模式,在许多其他品牌上具有不同程度的兼容性。假设转义序列有效,这些方法的流行逐渐导致越来越多的软件(尤其是公告板系统和其他在线服务)出现,从而导致几乎所有支持它们的新终端和仿真器程序。
早在1978年就有可能。C本身于1972年“诞生”,而K&R版本则于1978年建立。如果当时存在“ ANSI”转义序列,如果我们也愿意规定,那么会有一个答案“ in C”:“假设您的终端支持VT100。”顺便说一句,不支持ANSI的控制台转义了吗?您猜对了:Windows和DOS控制台。但是在几乎所有其他平台(Unices,Vaxen,Mac OS,Linux)上,您都可以期待。
TL; DR-如果不陈述有关运行时环境的假设,则无法给出合理的答案。由于大多数运行时(除非您使用的是80年代和90年代的台式机市场份额来计算“大多数”)(自VT-52以来!),所以我不知道认为说不可能是完全有道理的,只是为了使之成为可能,这是一个完全不同的工作量级,而不是像%8d
那样简单……看起来就像OP知道的那样。
我们只需要澄清这些假设即可。
以免有人认为I / O是例外,也就是说,只有我们需要考虑运行时(甚至是硬件)的时候,才深入研究IEEE 754浮点异常处理。对于那些感兴趣的人:
Intel Floating Point Case Study
据加州大学威廉·卡汉教授讲解 伯克利一家经典案例发生在1996年6月。 发射后不久,名为阿丽亚娜5号的火箭使车轮转向 分散自身和有效载荷,价值超过十亿美元 法属圭亚那的沼泽。卡汉(Kahan)发现这场灾难可能是罪魁祸首 基于无视默认语言的编程语言 IEEE 754中的异常处理规范。启动后,传感器 报告的加速过大,导致转换为整数 用于重新校准火箭的软件溢出 在发射台上时进行惯性制导。
答案 10 :(得分:0)
fp = fopen("RKdata.dat","w");
fprintf(fp,"%5s %12s %20s %14s %15s %15s %15s\n","j","x","integrated","bessj2","bessj3","bessj4","bessj5");
for (j=1;j<=NSTEP;j+=1)
fprintf(fp,"%5i\t %12.4f\t %14.6f\t %14.6f\t %14.6f\t %14.6f\t %14.6f\n",
j,xx[j],y[6][j],bessj(2,xx[j]),bessj(3,xx[j]),bessj(4,xx[j]),bessj(5,xx[j]));
fclose(fp);