2017-07-19 59 views
0

与sprintf的列我有一个基本的文本文件,我点我的程序在运行,通过线等具有数行:格式化文本文件转换成以C

 
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; 

} 

当我将它指向上面提到的文本文件时,我只是得到垃圾。有什么建议?

+2

像'“%* d” A符意见'需要两个参数,一个多少地方,一个是整数值。你正在提供一个。如果你不打算这样做,你应该消除'*'部分。 – tadman

+3

为什么不使用'%40d'或'%-40d'? –

+0

*“因此,基本上打印出每个数字[其中4个?]加上2个格式的空格,并且总共包含40个字符。”如果最长的字符串是'10-chars'(例如'-300000000' )。 '10 + 2 + 10 + 2 + 10 + 2 + 10 = 48'' –

回答

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 
} 
+0

谢谢!我试图寻找一种特别适用于sprintf的解决方案。我非常感谢帮助。你们是最棒的! – Kaz

+0

@David C. Rankin谢谢你的帮助。我对所有需要做的事情有了更好的了解。 – Kaz

5

要打印N个数在4列宽度为10个字符的格式%-10d变化对准使用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') 
} 

符号-内部。

正如你所看到的sprinf这里没有使用,我使用printf为每个数字打印屏幕上的值(标准输出)。

UPDATE:

如果您要查找的列的最佳宽度,并用它来输出,例如使用中你最大的号码位数(让它成为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 O r 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 
} 
+0

nit:'putchar('\ n')' - 是一个好的编译器会修复它,但是... –

+0

@ DavidC.Rankin是的,putchar功能更简单,适合在这里更好 – VolAnd

+1

嗯,它更像是一个“为什么使用非常复杂的* variadic *'printf'函数输出单个字符?“正确的工具有'putchar'和'fputc'。但是请注意,我认为它是一个* nit * - 它是小土豆,你所做的事是正确的,但是在教授新的C程序员时,你总是想引发关于这个工作最有效的工具是什么的思想: - 你以任何一种方式得票... –