【问题标题】:Aligning strings equally等量对齐字符串
【发布时间】:2016-09-16 03:17:29
【问题描述】:

我正在尝试将这些字符串与它们各自的索引对齐。字符串如下所示:

char *mystrings[] = {"Fred", "Augustine", "Bob", "Lenny", "Ricardo"};

我的输出如下所示:

Fred 0
Augustine 1
Bob 2
Lenny 3
Ricardo 4

但我喜欢这样的事情:

Fred       0
Augustine  1
Bob        2
Lenny      3
Ricardo    4

索引的对齐方式相同。我只是想让它更具可读性。这是我的代码到目前为止的样子:

#include <stdio.h>
#include <stdlib.h>

int
main(void) {
    int i;
    char *mystrings[] = {"Fred", "Augustine", "Bob", "Lenny", "Ricardo"};

    for (i = 0; i < 5; i++) {
        printf("%s %d\n", mystrings[i], i);
    }

    return 0;
}

有什么办法可以做到这一点吗?比如比较索引和最长的字符串,然后像这样为整数留出空格?

【问题讨论】:

  • printf man page中的“字段宽度”
  • 为什么在char *mystrings[MAXSIZE] 中使用MAXSIZE - 让编译器完成这项工作,即char *mystrings[],,,
  • @EdHeal 我的错。我会改变的。

标签: c


【解决方案1】:

额外循环计算最大宽度,然后使用* printf 标志从参数中获取宽度(乘以 -1 导致左对齐)

char *mystrings[] = {"Fred", "Augustine", "Bob", "Lenny", "Ricardo"};
int width = 0;
for (int i = 0; i < sizeof(mystrings)/sizeof(char*); i++) {
    width = strlen(mystrings[i]) > width? strlen(mystrings[i]) : width;
}

for (int i = 0; i < sizeof(mystrings)/sizeof(char*); i++) {
    printf("%*s %d\n", -1 * width, mystrings[i], i);
}

【讨论】:

  • 这是最好的方法。
【解决方案2】:

您需要在格式规范中指定字符串的宽度。
然后,您需要使用 - 说明符来指示您希望输出左对齐。

使用

printf("%-10s %d\n", mystrings[i], i);

将使用 10 个字符作为 mystrings[i] 并将左对齐输出。

如果您不知道字符串的长度,对这样的数字进行硬编码将是一个问题。为了使您的程序更健壮,您可以计算字符串的最大长度,然后从中计算格式字符串。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 5

int main(void) {
   int i;
   char *mystrings[MAXSIZE] = {"Fred", "Augustine", "Bob", "Lenny", "Ricardo"};

   int maxLen = 0;
   for (i = 0; i < MAXSIZE; i++) {
      int len = strlen(mystrings[i]);
      maxLen = (len > maxLen) ? len : maxLen;
   }

   char formatString[50];
   sprintf(formatString, "%%-%ds %%d\n", maxLen + 1);

   for (i = 0; i < MAXSIZE; i++) {
      printf(formatString, mystrings[i], i);
   }

   return 0;
}

输出

Fred       0
Augustine  1
Bob        2
Lenny      3
Ricardo    4

【讨论】:

  • 据我所见,解决方案很好,但在我看来,除非绝对必要,否则 C 程序员应该避免走动态格式字符串的道路。
  • @self 有什么特别的理由避免使用动态格式字符串? (除了它们可能难以阅读)((并映射到 nethack 中的 lice .. 或流氓,我忘记了))
  • @Tibrogargan 如果格式字符串恰好来自用户输入,它就会成为一个漏洞。并不是说这里就是这种情况,但通常您不希望将用户输入用作格式字符串。
【解决方案3】:

您需要做的是达到字符串的最大长度。您可以获取字符串的最大长度,然后通过一些简单的算术计算出您需要多少填充(字符串末尾的空格)。在不使用printf 的情况下,出于教育目的,我将向您展示如何做到这一点。

输出:

Fred      0
Augustine 1
Bob       2
Lenny     3
Ricardo   4

这是一个例子:

#include <stdio.h>
#include <string.h>

static size_t max_len(const char * const data[], size_t size) {
    size_t i = 0;
    size_t max = strlen(data[0]);

    for(i = 1; i < size; i++) {
        size_t len = strlen(data[i]);

        if(len > max) {
            max = len;
        }
    }
    return max;
}

int main(void) {
    const char *const mystrings[] = {
        "Fred", "Augustine", "Bob", "Lenny", "Ricardo"
    };

    size_t m = max_len(mystrings, 5);
    size_t i;

    for(i = 0; i < 5; i++) {
        const char *item = mystrings[i];
        size_t len = strlen(item);
        size_t padding = 0;
        /* +1 for padding byte */
        if(len + 1 < m) {
           padding = m - len;
        }

        printf("%s ", item);

        size_t ii;

        for(ii = 0; ii < padding; ii++) {
            fputc(' ', stdout);
        }

        printf("%zu\n", i);
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 2017-04-20
    • 2013-03-25
    • 2016-02-05
    相关资源
    最近更新 更多