如何居中对齐N行文本

时间:2015-11-10 15:14:01

标签: c formatting user-input

显然没有标准化的方法来对齐C中的文本,所以我

想知道如何编写if语句来居中对齐下N行

的文字。例如,如果程序在文本文件中找到.ce2,它应该

打印页面中间的下两行,然后照常进行。

.ce2 This is my heading
Lesson 1
Task 2

输出:

                       This is my heading

                           Lesson 1

Task 2

下面是我编写的代码,我实现了.br功能来打破

句子以及.sp功能,可在文本中添加空白行。

int main(void) {
FILE *fp = NULL;
char file_name[257] = {'\0'};
char line[61] = {'\0'};
char word[61] = {'\0'};
int out = 0;
int blanks;
int space;

printf ( "Enter file name:\n");
scanf ( " %256[^\n]", file_name);

if ( ( fp = fopen ( file_name, "r")) == NULL) {
    printf ( "could not open file\n");
    return 1;
}

while ( ( fscanf ( fp, "%60s", word)) == 1) { //breaks the sentence after .br
    if ( strcmp ( word, ".br") == 0) {
        printf ( "%s\n", line);
        line[0] = '\0';
        out = 1;
    }

    if ( strncmp ( word, ".sp", 3) == 0) { // creates n amount of spaces after .sp
        if ( ( sscanf ( &word[3], "%d", &blanks)) == 1) {
        printf ( "%s\n", line);
            while ( blanks) {
                blanks--;
                printf ( "\n");
                                }
            line[0] = '\0';
            out = 1;
                        }

    if ( strncmp ( word, ".ce", 3) == 0) { // centre the next n lines
        if ( ( sscanf ( &word[3], "%d", &space)) == 1) {
   //this is the if statement I am stuck at on what to include                
}
            line[0] = '\0';
            out = 1;
                        }

2 个答案:

答案 0 :(得分:4)

printf没有提供用于居中文本的机制,但它确实提供了一种右对齐文本的机制(字段宽度)和一种将字段宽度指定为参数的机制。将这两者放在一起,很容易使文本居中:

int print_centered(FILE* f, const char* str, int width) {
  int len = strlen(str);
  if (len < width) 
    return fprintf(f, "%*s\n", (width + len) / 2, str);
  else /* Line is too long to fit */
    return fprintf(f, "%s\n", str);
}

如果你想截断太长而不适合的行,你可以使用“precision”,在%s格式的情况下限制要打印的字符串的长度:

int print_centered_or_truncated(FILE* f, const char* str, int width) {
  int len = strlen(str);
  if (len < width) 
    return fprintf(f, "%*s\n", (width + len) / 2, str);
  else /* Line is too long to fit */
    return fprintf(f, "%.*s\n", width, str);
}

有关详细信息,请参阅man fprintf

答案 1 :(得分:0)

此函数将获取要将文本居中的缓冲区的宽度,printf接受的格式和任何其他参数,如果宽度小于输出缓冲区,它将截断。

#include <stdarg.h>

/***********************************
 * This function will center a     *
 * buffer of size 'width', and     *
 * it will truncate larger strings *
 **********************************/
int center_printf(int width, const char* format, ...)
{
   char *tmp = NULL, *output = NULL;
   int length, leading_spaces, ret;
   va_list args;

   if ( width <= 0 )                // Abort on incorrect width.
   {
      ret = -1;
      goto cleanup;
   }

   tmp = (char *)malloc ( width );
   if (tmp == NULL)
   {
      ret = -1;
      goto cleanup;
   }

   output = (char *)malloc ( width );
   if ( output == NULL )
   {
      ret = -1;
      goto cleanup;
   }

   va_start ( args, format );
   memset ( output, 0x20, width );    // Fill the output buffer with spaces.

   length = vsnprintf ( tmp, width, format, args );
   leading_spaces = ( length >= width ) ? 0 : (width - length)/ 2;
   memcpy ( output + leading_spaces, tmp, length );

   ret = printf ( output );
   va_end( args );

cleanup:
   if ( tmp != NULL )
      free ( tmp );
   if ( output != NULL )
        free ( output );

   return ret;
}

编辑: 根据chux和rici的评论修正了我的功能。

int center_printf(int width, const char* format, ...)
{
   char *output = NULL;
   int length, ret;
   va_list args;

   if ( width <= 0 )                // Abort on incorrect width.
   {
      ret = -1;
      goto cleanup;
   }

   output = (char *)malloc ( width + 1 );
   if (output == NULL)
   {
      ret = -1;
      goto cleanup;
   }

   va_start ( args, format );
   length = vsnprintf ( output, width + 1, format, args );
   ret = printf ( "%*s", ( length >= width ) ? 0 : (width + length)/2 , output );
   va_end( args );

cleanup:
   if ( output != NULL )
      free ( output );

   return ret;
}

用法:

center_printf (50, "%s: testing 123", __FUNCTION__);