如何连接字符串以生成固定宽度输出

时间:2016-04-20 01:38:07

标签: c concatenation

我有一个结构数组,其中每个结构包含一个名字和一个姓氏,以及其他信息。我试图以表格形式打印数组,就像这样

+---------------------------+--------+--------+
| Student Name              | Test 1 | Test 2 |
+---------------------------+--------+--------+
| Pousseur, Henri           |   95   |   92   |
| Boyer, Charles            |   90   |   97   |
+---------------------------+--------+--------+

但是,我的输出看起来像这样

+---------------------------+--------+--------+
| Student Name              | Test 1 | Test 2 |
+---------------------------+--------+--------+
| Pousseur, Henri                  |   95   |   92   |
| Boyer, Charles                     |   90   |   97   |
+---------------------------+--------+--------+

我的问题是,如何将姓氏连接到名字(中间用逗号),然后将整个内容打印为固定宽度的字符串?这样我的桌子就能正确排列。

这是我的代码:

#include <stdio.h>
#define NAME_LEN 25

typedef struct
{
    char fname[NAME_LEN+1];
    char lname[NAME_LEN+1];
    int score1;
    int score2;
} STUREC;

void printRecords(STUREC records[], int count)
{
    printf("+---------------------------+--------+--------+\n");
    printf("| Student Name              | Test 1 | Test 2 |\n");
    printf("+---------------------------+--------+--------+\n");

    for (int i = 0; i < count; i++)
        printf ("| %-s, %-26s| %4d   | %4d   |\n", records[i].lname, records[i].fname, records[i].score1, records[i].score2 );

    printf("+---------------------------+--------+--------+\n");
}

int main(void)
{
    STUREC records[] = {
        { "Henri"  , "Pousseur", 95, 92 },
        { "Charles", "Boyer"   , 90, 97 }
    };

    printRecords(records, 2);
}

2 个答案:

答案 0 :(得分:1)

请注意printf会返回打印的字符数。因此,如果要在固定宽度内打印名称,可以打印名称,然后根据需要输出空格以填充宽度。

#define WIDTH 26

int count = printf( "%s, %s", records[i].lname, records[i].fname );
if ( count < WIDTH )
    printf( "%*s", WIDTH-count, "" );

在格式字符串"%*s"中,*告诉printf字符串的宽度将作为参数传递。 WIDTH-count参数是需要打印的空格数,""只是一个空字符串。例如,如果count为16,则WIDTH-count为10,因此printf相当于

printf( "%10s", "" ); 

将打印10个空格。

答案 1 :(得分:1)

这只是@ user3386109答案的广告。

添加

#define WIDTH 27 // You get a max width of 26

程序开头的某个地方和一个字符串

char fullname[WIDTH];

在主要开头的某个地方。

然后进行如下更改:

printf("\n+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
    printf("| Student Name              |   ID   | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |\n");
    printf("+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");

    for (i = 0; i < count; i++)
    {
       int lname_len=strlen(records[i].lname);
       int fname_len=strlen(records[i].fname);
        snprintf(fullname,WIDTH,"%s,%s%*s", records[i].lname,records[i].fname,(WIDTH>(lname_len+fname_len)?(WIDTH-(lname_len+fname_len)):0),"");

        /* The above step concatenates - since you're very interested in it -
         * the sirname and the first name into a string fullname making sure
         * that the string is padded to 26 characters utmost.
         */

        printf ("| %s | %-7.6d| %4d   | %4d   | %4d   | %4d   | %4d   | %6.2f  |  %-2s   |\n", fullname, records[i].id, records[i].score1,
                 records[i].score2, records[i].score3, records[i].score4, records[i].score5,
                  records[i].ave, records[i].grade);
    }
    printf("+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");

    printf("\nHave A Terrible Day!\n\n");

注意三元表达式:

(WIDTH>(lname_len+fname_len)?(WIDTH-(lname_len+fname_len)):0)
snprintf中的

。这将被评估为未使用的宽度,如果我们使用emptry字符串""或空字符填充的话。

如果您不理解,请查看here