如何让右列垂直对齐

How to get right column to align vertically

我需要在右侧垂直排列一列星号。根据输入的长度,右侧的星号将关闭。

#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] = '[=10=]';      // 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()
{


}

这是我的样子: 这就是它需要的样子:

请给我指明正确的方向,我需要学习如何去做,所以我不希望它完全为我完成。 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);

输出:

您可以使用以下模板"left align"任何您想要的东西:

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() return 所写的字符数与 sprintf() 非常相似。

示例输出:

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

以下代码:

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

这不是完成的代码,但确实纠正了 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 = '[=10=]';      // 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