我有一个基本的文本文件,我将程序指向运行,其中包含逐行编号,例如:
3 30 300 3000 30000 300000 3000000 30000000 300000000 -3 -30 -300 -3000 -30000 -300000 -3000000 -30000000 -300000000
我需要将它们打印成均匀间隔的列,我希望它们适合40个字符(4列宽)。我想使用sprintf函数来做到这一点。所以基本上打印每个数字加2个空格进行格式化,总共40个字符以内。到目前为止,这就是我所拥有的。
int main(int argc, char *argv[]){
int a, b, num[1000], nums = 0;
char str[40];
FILE *pt;
int col, max, w;
if(argc < 2){
printf("Usage %s <No Files>\n", argv[0]);
return 1;
}
if((pt = fopen(argv[1], "r")) == NULL){
printf("Unable to open %s for reading.\n", argv[1]);
return 1;
}
while(fscanf(pt, "%d", &b) == 1){
num[nums++] = b;
}
w = sprintf(str, "%*d", num[a]);
if(max < w){
col = 40 / (max + 2);
printf("%d %d\n", w, num[a]);
}
return 0;
}
当我将它指向上面提到的文本文件时,我只是垃圾。有什么建议吗?
答案 0 :(得分:5)
要在宽度为10个字符的4列中打印N个数字,请在每次第4次打印后添加新行(printf("%10d")
)的循环内使用\n
,例如:
for (int i = 1; i <= nums; i++)
{
printf("%10d", num[i-1]); // or printf("%-10d", num[i-1]);
if (i % 4 == 0)
printf("\n"); // or putchar ('\n')
}
以-
更改对齐格式签署%-10d
。
如您所见,此处未使用sprinf
,我使用printf
为每个数字打印屏幕上的值(标准输出)。
<强>更新强>
如果要查找列的最佳宽度,并将其用于输出,例如使用最大数字中的位数(让maxValue
为数组num
中的整数值),您可以找到所需的最小位数(让它为minWidth
),如:
char buff[20] = {0};
int minWidth = strlen(_itoa(maxValue,buff,10));
然后更改打印循环,如:
for (int i = 1; i <= nums; i++)
{
printf("%*d", minWidth + 1, num[i - 1]);
if (i % 4 == 0) putchar('\n');
}
此处vlaue minWidth + 1
将在格式说明符%*d
中使用,而不是*
,而+1
用于在一个空格中的列之间进行最小间隔(当然,那里可以是2或3)。
最后,计算出列宽后,您可以找到屏幕的列数,并使用此值开始新行,例如:
const int screenWidth = 80;
int colWidth = minWidth + 2; // here 2 is added for minimum separation of columns
int colNum = screenWidth / colWidth;
for (int i = 1; i <= nums; i++)
{
printf("%*d", colWidth, num[i - 1]);
if ( !(i % colNum) ) putchar('\n'); // !(i % colNum) is the same to i % colNum == 0
}
答案 1 :(得分:1)
这是我对同一个问题的第二个答案,但这个答案更接近主题 - 这里输出是sprintf
的字符串。
所以,让我们有一组数字int num[1000]
,我们需要将nums
打印成几个字符串(长度受值stringMaxLength
限制),使用格式为宽度依赖的列数字表示的长度(数组中的最大数字)。
以下代码段包含所有操作的注释
// string that will be made from numbers
const int stringMaxLength = 120;
char str[stringMaxLength + 1]; // just one string
// find longest number considering sign
char buff[20] = { 0 };
int maxNumWidth = 0, numWidth;
int n;
for (n = 0; n < nums; n++)
{
numWidth = strlen(_itoa(num[n], buff, 10));
if (numWidth > maxNumWidth)
maxNumWidth = numWidth;
}
int colWidth = maxNumWidth + 1; // a column size with one space between columns
int colNum = stringMaxLength / colWidth; // number of columns in one string
int s, i; // i - nums counter, s - strings counter
for (i = 0, s = 1; i < nums; s++) // loop counts strings but with condition for nums
{
int sizeCnt = 0; // start making new string str
// loop works while there are numbers and the line is not filled completely
while (i < nums)
{
// add next number (column) to the string and increase string size
sizeCnt += sprintf(str + sizeCnt, "%*d", colWidth, num[i++]);
if (i % colNum == 0) // if string has colNum numbers it is full
{
break; // stop while loop
}
}
// next string is ready and can be used
printf("%d : %s\n", s, str); // e.g. for output
}