【问题标题】:How to get right column to align vertically如何让右列垂直对齐
【发布时间】:2016-03-16 15:31:07
【问题描述】:

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

#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()
{


}

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

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

输出:

【问题讨论】:

  • @WeatherVane 认为我明白你的意思。但是如果字符串长度不同, %s 不会对齐右手边?我可能是错的......我是新手,很困惑。
  • 另一种方法是使用sprintf() 来构建您需要的子字符串,它会返回它们的长度。
  • 请注意,如果无法打开文件,您的程序会继续运行。
  • @PaulH.1) 除了问题之外......我不在乎,直到我让它正常工作。 2) cfgfile = fopen("strings.txt", "r"); if (cfgfile==NULL) printf("无法打开文件\n");
  • @WeatherVane 谢谢你的信息!是否可以将它与结构数组一起使用? sprintf("* " 名称[x].FullName,"*\n");我收到错误

标签: c format string-length


【解决方案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                                        *

【讨论】:

  • 这是否在右侧对齐星号。这样右边的所有星号都排成一排?
  • @GeekyDewd 应该。
  • 我在主帖中放了一个屏幕截图。
  • 我需要调整工作时间、净工资(需要调整小数点)
  • 对齐小数点,1) 确保字段始终从同一列开始 2) 使用类似于:%15.2f 的格式说明符
【解决方案2】:

以下代码:

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

这不是完成的代码,但确实纠正了 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多