如何使右列垂直对齐

时间:2015-12-10 20:42:22

标签: c format string-length

我需要在右侧以垂直方向排列一列正确的星号。根据输入的长度,右侧的星号是关闭的。

#include <stdio.h>
#include <string.h>
#define CHECKHEADER1 "************************************************************\n"
#define CHECKHEADER2 "*                                                          *\n"
#define MAX 2

typedef char STR30[30+1];
typedef char STR302[30+1];
typedef struct EmployeeRecord
{
    STR30 FullName;
    STR302 GoodFullName;

} EmployeeRecord;

void CheckPrinter();
void PrintCheckHeadings(EmployeeRecord name[]);
void PrintCheckStub();

int CheckNumber = 100;
FILE * cfgfile;

int main(void)
{
    int i;
    EmployeeRecord name[MAX];
    for ( i = 0; i < MAX; i++)
    {
    printf("enter username: ");
    scanf("%s",name[i].FullName);
    }
    //name[1].FullName = "Sam Smithh";
    //EmployerData = fopen("EmployerData.txt", "r");
    cfgfile = fopen("strings.txt", "r");
    if (cfgfile==NULL) printf("can't open file\n");
    //CheckPrinter();
        printf("%-1s%6s%s", "*",name[0].FullName,"*\n");
    PrintCheckHeadings(name);
}
/*
void CheckPrinter()
{
    PrintCheckHeadings();
}
*/
void PrintCheckHeadings(EmployeeRecord name[])
{
    //printf(CHECKHEADER1);
    //printf(CHECKHEADER2);
    //printf("%-1s%37s%5i%17s", "*","Check Number", CheckNumber,"*");
     int i=0, j=0,x=0;
      int maxline = 60;
       char cfgstring[16][60];
         for(x=0; x<MAX; x++) printf("%s%25s\n",cfgstring[j],"*");
{

 while (fgets(cfgstring[i], maxline, cfgfile)) {      // while not EOF
    cfgstring[i][strlen(cfgstring[i])-1] = '\0';      // remove CR from line
    i++;
   }

    printf(CHECKHEADER1);
    printf(CHECKHEADER2);
    printf("%-1s%37s%5s%18s", "*","Check Number ", cfgstring[1],"*\n");
    printf("%-1s%5s%41s","*  ", cfgstring[2],"*\n");
    printf("%-1s%5s%35s","*  ", cfgstring[3],"*\n");
    printf("%-1s%5s%31s","*  ", cfgstring[4],"*\n");
    printf(CHECKHEADER2);
    printf(CHECKHEADER2);
    printf("*  Pay to the order of                                     *\n");
    printf(CHECKHEADER2);
    printf("%-1s%6s%s", "*",name[x].FullName,"*\n");
    printf(CHECKHEADER2);
    printf("%-1s%15s","*","Sum in words\n");
    printf(CHECKHEADER2);
    printf(CHECKHEADER2);
    printf("%-1s%18s","*","Reference Number\n");
    printf(CHECKHEADER2);
    printf(CHECKHEADER2);
    printf(CHECKHEADER1);
}
 fclose(cfgfile);
}
void PrintCheckStub()
{


}

这就是我的样子:enter image description here 这就是它需要的样子:enter image description here

请指出我正确的方向,我需要学习如何做到这一点,所以我不希望它完全为我完成。 strcpy + strcat是正确的方法吗?

看起来很棒!

printf("*  %-25s%7s%11.2f%10s%9.2f *\n",MyAssociate[i].FullName,"Reg Pay",MyAssociate[i].Payrate,"Fed Tax",MyAssociate[i].FedTax);
printf("*  %-25s%7s%11.2f%12s%7.2f *\n",cfgstring[3],"OVT Pay",MyAssociate[i].OVT,"State Tax",MyAssociate[i].StateTax);
printf("*  %-25s%7s%9.2f%10s%9.2f *\n","New Corio, New Mexico","Gross Pay",MyAssociate[i].Gross,"SSI Tax",MyAssociate[i].SsiTax);
printf("*  %-25s%7s%11.2f%12s%7.2f *\n","65790","Net Pay",MyAssociate[i].NetPay,"Tax Total",TOTtax);

输出: enter image description here

2 个答案:

答案 0 :(得分:1)

您可以使用以下模板“左对齐”任何内容:

printf("*  %-56s*\n", "foo");

示例:

//         0         1         2         3         4         5         6
//         0123456789012345678901234567890123456789012345678901234567890123456789
   printf("*  Pay to the order of                                     *\n");

   printf("*  %-56s*\n", "");
   printf("*  %-56s*\n", name[x].FullName);
   printf("*  %-56s*\n", "");
   printf("*  %-56s*\n", "Sum in words");
   printf("*  %-56s*\n", "");

如果要将内容进一步向右移动,请根据需要调整前缀空格数和格式字符串%-56s

注意:printf()确实会返回与sprintf()非常相似的字符数。

示例输出:

*  Pay to the order of                                     *
*                                                          *
*  Foo B Bar                                               *
*                                                          *
*  Sum in words                                            *
*                                                          *
*  Reference Number                                        *

答案 1 :(得分:1)

以下代码:

  1. 清理控制逻辑
  2. 删除了不必要的杂乱
  3. 可能应该将#define MAX_CFG_STR_LEN从60
  4. 大幅减少
  5. 清理EmployeeRecord结构的定义
  6. 只有第1行... 4(第0行未使用)所以为什么cfgstring[][]数组定义为16行?
  7. 我没有弄乱右手*的对齐,所以需要'调整'
  8. 添加了适当的错误检查
  9. 将打印头行显示修改为易于调整的功能
  10. 您可以将所有固定内容行放入表中,然后只需调用printf()并输出所需的表条目,而不是函数:printCheckHeader1()printCheckHeader2()。建议将该表作为`static const table [] = {...};
  11. 从cfgfile的每个输入中删除尾随换行符,同时处理多字符换行符,并且不修剪任何有效字符
  12. 这不是完成的代码,但确实解决了OP发布的代码中最糟糕的问题

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    
    
    #define MAX 2
    #define NUM_CFG_STRINGS (16)
    #define MAX_CFG_STR_LEN (60)
    
    typedef char STR30[30+1];
    typedef char STR302[30+1];
    typedef struct EmployeeRecord
    {
        STR30 FullName;
        STR302 GoodFullName;
    
    } EmployeeRecord;
    
    // prototypes
    void printCheckHeader1( void );
    void printCheckHeader2( void );
    #if 0
    void CheckPrinter( void );
    #endif
    void PrintCheckHeadings(EmployeeRecord name[]);
    void PrintCheckStub( void );
    
    #if 0
    static int CheckNumber = 100;
    #endif
    
    static FILE * cfgfile;
    
    static char cfgstring[ NUM_CFG_STRINGS ][ MAX_CFG_STR_LEN ];
    
    
    int main(void)
    {
        int i;
        EmployeeRecord name[MAX];
    
        for ( i = 0; i < MAX; i++)
        {
            printf("enter username: %d ", i);
            if( 1 != scanf(" %s",name[i].FullName) )
            {
                fprintf( stderr, 
                         "scanf for username: %d failed due to %s\n", 
                          i, 
                          strerror(errno));
                exit( EXIT_FAILURE );
            }
        }
    
        //name[1].FullName = "Sam Smithh";
        //EmployerData = fopen("EmployerData.txt", "r");
    
        cfgfile = fopen("strings.txt", "r");
        if (cfgfile==NULL)
        {
            fprintf( stderr, 
                     "can't open file: strings.txt due to %s\n",
                     strerror(errno));
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        while (i < NUM_CFG_STRINGS 
            && fgets(cfgstring[i], MAX_CFG_STR_LEN, cfgfile))
        {      // while not EOF
            char *newline = NULL
            if( NULL != (newline = strstr( cfgstring[i], "\n") ) )
            { // then newline found
                *newline = '\0';      // remove CR from line
            }
            i++;
        }
        fclose(cfgfile);
    
        #if 0
        CheckPrinter();
        #else
        printf("*  %-30.30s                           *\n", name[0].FullName);
        PrintCheckHeadings(name);
        #endif
    
        return 0;
    } // end function: main
    
    
    #if 0
    void CheckPrinter()
    {
        PrintCheckHeadings();
    }
    #endif
    
    
    void PrintCheckHeadings(EmployeeRecord name[])
    {
        //printf(CHECKHEADER1);
        //printf(CHECKHEADER2);
        //printf("%-1s%37s%5i%17s", "*","Check Number", CheckNumber,"*");
    
    
        for(int x=0; x<MAX; x++)
        {
            printCheckHeader1();
            printCheckHeader2();
            printf("*  Check Number   %-40.40s *\n", cfgstring[1]);
            printf("*  %-60.60s*\n", cfgstring[2]);
            printf("*  %-60.60s*\n", cfgstring[3]);
            printf("*  %-60.60s*\n", cfgstring[4]);
            printCheckHeader1();
            printCheckHeader2();
            printf("%s\n", "*  Pay to the order of                                     *");
            printCheckHeader2();
            printf("*  %-60.60s*\n", name[x].FullName);
            printCheckHeader2();
            printf("%s\n", "*  Sum in words                                            *");
            printCheckHeader2();
            printCheckHeader2();
            printf("%s\n", "*  Reference Number                                        *");
            printCheckHeader2();
            printCheckHeader2();
            printCheckHeader1();
        }
    
    } // end function: PrintCheckHeadings
    
    
    #if 0
    void PrintCheckStub()
    {
    
    
    } // end function: PrintCheckStub
    #endif
    
    
    // output: "************************************************************\n"
    void printCheckHeader1()
    {
        for( int i=0; i<60; i++)
        {
            printf( "*" );
        }
        printf( "\n" );
    } // end function: printCheckHeader1
    
    
    // output:"*                                                          *\n"
    void printCheckHeader2()
    {
        for( int i=0; i<60; i++)
        {
            if( i<1 ) printf( "*" );
    
            else if( i< 59 ) printf( " " );
    
            else printf( "*\n" );
        }
    } // end function: printCheckHeader2