如果我只使用 Welcome 消息,我的代码可以正常工作,但是当打印p->client_name
指针时,消息不会居中。
所以我的问题是如何将消息和客户端名称集中在一起,就好像它是一条消息一样。为什么它目前仅以消息 welcome
为中心sprintf(message,"============================================================");
send_message(RED, message);
const char *mes = "Welcome";
sprintf(message, "[ %*s %s ]", (45 - strlen(message)) / 2 + ((strlen(message) % 2 == 0) ? 1 : 0) + strlen(message), mes, p->client_name);
send_message(RED, message);
sprintf(message,"============================================================");
send_message(RED, message);
示例:
=============================================
[ Welcome Carol ]
=============================================
答案 0 :(得分:1)
此代码看起来很有效。评论解释了计算。测试代码显示了我如何测试这些东西。
/*
** Centre a pair of words in a given width without creating a single
** string to centre.
**
** Format will be "[ %*s %-*s ]"; what are the values required for the
** two lengths R1, R2 for a given width W and lengths L1, L2?
**
** +----------------------------------------------------------+
** [ @.........R1..........@ @..............R2..............@ ]
** [ XXXXXXXXXXXXXXXX YYYYYYYYYYYYYYYYYYYYYYYYY ]
** [ G1 | L1 | | L2 | G2 ]
** +----------------------------------------------------------+
**
** W = G1 + L1 + 1 + L2 + G2
**
** G1 = G2 or G1 + 1 = G2
** L1 + L2 + 1 <= W (return G1 = G2 = 1 if it is bigger)
**
** For the purposes of the calculation, the leading "[ " and trailing " ]"
** are not counted as part of W.
**
** Total Padding T = W - (L1 + L2 + 1)
** Hence: G1 = T / 2
** G2 = T - G1
** R1 = L1 + G1
** R2 = L2 + G2
*/
static void centre_two_lengths(int w, int l1, int l2, int *r1, int *r2)
{
int t = w - (l1 + l2 + 1);
if (t <= 0)
{
*r1 = *r2 = 1;
}
else
{
int g1 = t / 2;
int g2 = t - g1;
*r1 = l1 + g1;
*r2 = l2 + g2;
}
}
#include <stdio.h>
#include <string.h>
static void test_width(int width)
{
const char *data[] =
{
"A", "B",
"AA", "B",
"A", "BB",
"A", "BBB",
"A", "BBBB",
"AAA", "B",
"Hello", "World",
"Middle of", "the road",
"Welcome", "to Jurassic Park",
"Bienvenue", "a Paris",
"Twelve Place", "Twice - Over",
"Eleven Here", "Thirteen Here",
"Much much longer", "than this",
"A", "Discourse on Inequality",
"What sort of pedant am", "I",
"What an essay", "busting all the limits",
};
int num_pairs = (sizeof(data) / sizeof(data[0])) / 2;
for (int i = 0; i < num_pairs; i++)
{
int r1;
int r2;
const char *s1 = data[2 * i + 0];
const char *s2 = data[2 * i + 1];
int l1 = strlen(s1);
int l2 = strlen(s2);
centre_two_lengths(width, l1, l2, &r1, &r2);
printf("W = %2d, L1 = %2d, L2 = %2d, R1 = %2d, R2 = %2d ", width, l1, l2, r1, r2);
printf("[ %*s %-*s ]\n", r1, s1, r2, s2);
}
}
int main(void)
{
for (int width= 24; width < 30; width++)
test_width(width);
return(0);
}
请注意,代码不会尝试处理L1
或L2
为零的情况。除非非零长度太大,否则在大多数情况下都可以这样做。但这似乎没必要。目标是使两个(非零长度)字符串居中。计算也不会尝试处理字符串中的前导或尾随空格;简单地假设没有前导或尾随空格。
它还假设一个单字节代码集;如果它具有ASCII范围之外的字符(并且它不会处理控制字符 - 后空格,制表符,换行符,回车符等等 - 它们也不会正确地居中于UTF-8)。
输出:
W = 24, L1 = 1, L2 = 1, R1 = 11, R2 = 12 [ A B ]
W = 24, L1 = 2, L2 = 1, R1 = 12, R2 = 11 [ AA B ]
W = 24, L1 = 1, L2 = 2, R1 = 11, R2 = 12 [ A BB ]
W = 24, L1 = 1, L2 = 3, R1 = 10, R2 = 13 [ A BBB ]
W = 24, L1 = 1, L2 = 4, R1 = 10, R2 = 13 [ A BBBB ]
W = 24, L1 = 3, L2 = 1, R1 = 12, R2 = 11 [ AAA B ]
W = 24, L1 = 5, L2 = 5, R1 = 11, R2 = 12 [ Hello World ]
W = 24, L1 = 9, L2 = 8, R1 = 12, R2 = 11 [ Middle of the road ]
W = 24, L1 = 7, L2 = 16, R1 = 1, R2 = 1 [ Welcome to Jurassic Park ]
W = 24, L1 = 9, L2 = 7, R1 = 12, R2 = 11 [ Bienvenue a Paris ]
W = 24, L1 = 12, L2 = 12, R1 = 1, R2 = 1 [ Twelve Place Twice - Over ]
W = 24, L1 = 11, L2 = 13, R1 = 1, R2 = 1 [ Eleven Here Thirteen Here ]
W = 24, L1 = 16, L2 = 9, R1 = 1, R2 = 1 [ Much much longer than this ]
W = 24, L1 = 1, L2 = 23, R1 = 1, R2 = 1 [ A Discourse on Inequality ]
W = 24, L1 = 22, L2 = 1, R1 = 1, R2 = 1 [ What sort of pedant am I ]
W = 24, L1 = 13, L2 = 22, R1 = 1, R2 = 1 [ What an essay busting all the limits ]
W = 25, L1 = 1, L2 = 1, R1 = 12, R2 = 12 [ A B ]
W = 25, L1 = 2, L2 = 1, R1 = 12, R2 = 12 [ AA B ]
W = 25, L1 = 1, L2 = 2, R1 = 11, R2 = 13 [ A BB ]
W = 25, L1 = 1, L2 = 3, R1 = 11, R2 = 13 [ A BBB ]
W = 25, L1 = 1, L2 = 4, R1 = 10, R2 = 14 [ A BBBB ]
W = 25, L1 = 3, L2 = 1, R1 = 13, R2 = 11 [ AAA B ]
W = 25, L1 = 5, L2 = 5, R1 = 12, R2 = 12 [ Hello World ]
W = 25, L1 = 9, L2 = 8, R1 = 12, R2 = 12 [ Middle of the road ]
W = 25, L1 = 7, L2 = 16, R1 = 7, R2 = 17 [ Welcome to Jurassic Park ]
W = 25, L1 = 9, L2 = 7, R1 = 13, R2 = 11 [ Bienvenue a Paris ]
W = 25, L1 = 12, L2 = 12, R1 = 1, R2 = 1 [ Twelve Place Twice - Over ]
W = 25, L1 = 11, L2 = 13, R1 = 1, R2 = 1 [ Eleven Here Thirteen Here ]
W = 25, L1 = 16, L2 = 9, R1 = 1, R2 = 1 [ Much much longer than this ]
W = 25, L1 = 1, L2 = 23, R1 = 1, R2 = 1 [ A Discourse on Inequality ]
W = 25, L1 = 22, L2 = 1, R1 = 22, R2 = 2 [ What sort of pedant am I ]
W = 25, L1 = 13, L2 = 22, R1 = 1, R2 = 1 [ What an essay busting all the limits ]
W = 26, L1 = 1, L2 = 1, R1 = 12, R2 = 13 [ A B ]
W = 26, L1 = 2, L2 = 1, R1 = 13, R2 = 12 [ AA B ]
W = 26, L1 = 1, L2 = 2, R1 = 12, R2 = 13 [ A BB ]
W = 26, L1 = 1, L2 = 3, R1 = 11, R2 = 14 [ A BBB ]
W = 26, L1 = 1, L2 = 4, R1 = 11, R2 = 14 [ A BBBB ]
W = 26, L1 = 3, L2 = 1, R1 = 13, R2 = 12 [ AAA B ]
W = 26, L1 = 5, L2 = 5, R1 = 12, R2 = 13 [ Hello World ]
W = 26, L1 = 9, L2 = 8, R1 = 13, R2 = 12 [ Middle of the road ]
W = 26, L1 = 7, L2 = 16, R1 = 8, R2 = 17 [ Welcome to Jurassic Park ]
W = 26, L1 = 9, L2 = 7, R1 = 13, R2 = 12 [ Bienvenue a Paris ]
W = 26, L1 = 12, L2 = 12, R1 = 12, R2 = 13 [ Twelve Place Twice - Over ]
W = 26, L1 = 11, L2 = 13, R1 = 11, R2 = 14 [ Eleven Here Thirteen Here ]
W = 26, L1 = 16, L2 = 9, R1 = 1, R2 = 1 [ Much much longer than this ]
W = 26, L1 = 1, L2 = 23, R1 = 1, R2 = 24 [ A Discourse on Inequality ]
W = 26, L1 = 22, L2 = 1, R1 = 23, R2 = 2 [ What sort of pedant am I ]
W = 26, L1 = 13, L2 = 22, R1 = 1, R2 = 1 [ What an essay busting all the limits ]
W = 27, L1 = 1, L2 = 1, R1 = 13, R2 = 13 [ A B ]
W = 27, L1 = 2, L2 = 1, R1 = 13, R2 = 13 [ AA B ]
W = 27, L1 = 1, L2 = 2, R1 = 12, R2 = 14 [ A BB ]
W = 27, L1 = 1, L2 = 3, R1 = 12, R2 = 14 [ A BBB ]
W = 27, L1 = 1, L2 = 4, R1 = 11, R2 = 15 [ A BBBB ]
W = 27, L1 = 3, L2 = 1, R1 = 14, R2 = 12 [ AAA B ]
W = 27, L1 = 5, L2 = 5, R1 = 13, R2 = 13 [ Hello World ]
W = 27, L1 = 9, L2 = 8, R1 = 13, R2 = 13 [ Middle of the road ]
W = 27, L1 = 7, L2 = 16, R1 = 8, R2 = 18 [ Welcome to Jurassic Park ]
W = 27, L1 = 9, L2 = 7, R1 = 14, R2 = 12 [ Bienvenue a Paris ]
W = 27, L1 = 12, L2 = 12, R1 = 13, R2 = 13 [ Twelve Place Twice - Over ]
W = 27, L1 = 11, L2 = 13, R1 = 12, R2 = 14 [ Eleven Here Thirteen Here ]
W = 27, L1 = 16, L2 = 9, R1 = 16, R2 = 10 [ Much much longer than this ]
W = 27, L1 = 1, L2 = 23, R1 = 2, R2 = 24 [ A Discourse on Inequality ]
W = 27, L1 = 22, L2 = 1, R1 = 23, R2 = 3 [ What sort of pedant am I ]
W = 27, L1 = 13, L2 = 22, R1 = 1, R2 = 1 [ What an essay busting all the limits ]
W = 28, L1 = 1, L2 = 1, R1 = 13, R2 = 14 [ A B ]
W = 28, L1 = 2, L2 = 1, R1 = 14, R2 = 13 [ AA B ]
W = 28, L1 = 1, L2 = 2, R1 = 13, R2 = 14 [ A BB ]
W = 28, L1 = 1, L2 = 3, R1 = 12, R2 = 15 [ A BBB ]
W = 28, L1 = 1, L2 = 4, R1 = 12, R2 = 15 [ A BBBB ]
W = 28, L1 = 3, L2 = 1, R1 = 14, R2 = 13 [ AAA B ]
W = 28, L1 = 5, L2 = 5, R1 = 13, R2 = 14 [ Hello World ]
W = 28, L1 = 9, L2 = 8, R1 = 14, R2 = 13 [ Middle of the road ]
W = 28, L1 = 7, L2 = 16, R1 = 9, R2 = 18 [ Welcome to Jurassic Park ]
W = 28, L1 = 9, L2 = 7, R1 = 14, R2 = 13 [ Bienvenue a Paris ]
W = 28, L1 = 12, L2 = 12, R1 = 13, R2 = 14 [ Twelve Place Twice - Over ]
W = 28, L1 = 11, L2 = 13, R1 = 12, R2 = 15 [ Eleven Here Thirteen Here ]
W = 28, L1 = 16, L2 = 9, R1 = 17, R2 = 10 [ Much much longer than this ]
W = 28, L1 = 1, L2 = 23, R1 = 2, R2 = 25 [ A Discourse on Inequality ]
W = 28, L1 = 22, L2 = 1, R1 = 24, R2 = 3 [ What sort of pedant am I ]
W = 28, L1 = 13, L2 = 22, R1 = 1, R2 = 1 [ What an essay busting all the limits ]
W = 29, L1 = 1, L2 = 1, R1 = 14, R2 = 14 [ A B ]
W = 29, L1 = 2, L2 = 1, R1 = 14, R2 = 14 [ AA B ]
W = 29, L1 = 1, L2 = 2, R1 = 13, R2 = 15 [ A BB ]
W = 29, L1 = 1, L2 = 3, R1 = 13, R2 = 15 [ A BBB ]
W = 29, L1 = 1, L2 = 4, R1 = 12, R2 = 16 [ A BBBB ]
W = 29, L1 = 3, L2 = 1, R1 = 15, R2 = 13 [ AAA B ]
W = 29, L1 = 5, L2 = 5, R1 = 14, R2 = 14 [ Hello World ]
W = 29, L1 = 9, L2 = 8, R1 = 14, R2 = 14 [ Middle of the road ]
W = 29, L1 = 7, L2 = 16, R1 = 9, R2 = 19 [ Welcome to Jurassic Park ]
W = 29, L1 = 9, L2 = 7, R1 = 15, R2 = 13 [ Bienvenue a Paris ]
W = 29, L1 = 12, L2 = 12, R1 = 14, R2 = 14 [ Twelve Place Twice - Over ]
W = 29, L1 = 11, L2 = 13, R1 = 13, R2 = 15 [ Eleven Here Thirteen Here ]
W = 29, L1 = 16, L2 = 9, R1 = 17, R2 = 11 [ Much much longer than this ]
W = 29, L1 = 1, L2 = 23, R1 = 3, R2 = 25 [ A Discourse on Inequality ]
W = 29, L1 = 22, L2 = 1, R1 = 24, R2 = 4 [ What sort of pedant am I ]
W = 29, L1 = 13, L2 = 22, R1 = 1, R2 = 1 [ What an essay busting all the limits ]
此代码似乎符合修订后的要求。
/*
** Given two words W1,W2, enclose them in square brackets "[ W1 W2]"
** Centre a pair of words in a given width without creating a single
** string to centre.
**
** Format will be "%*s[ %s %s ]%*s"; what are the values required for
** R1, R2 given the two lengths L1, L2 and width W?
**
** +----------------------------------------------------------+
** | |
** | [ XXXXXXXXXXXXXXXX YYYYYYYYYYYYYYYYYYYYYYYYY ] |
** | R1 | | L1 | | L2 | | R2 |
** +----------------------------------------------------------+
**
** W = R1 + L1 + 5 + L2 + R2
**
** for centred output, either R1 = R2 or R1 + 1 = R2
** L1 + L2 + 5 <= W (return R1 = R2 = 0 if it is bigger)
**
** Total Padding T = W - (L1 + L2 + 5)
** Hence: R1 = T / 2
** R2 = T - R1
*/
static void centre_two_lengths(int w, int l1, int l2, int *r1, int *r2)
{
int t = w - (l1 + l2 + 5);
if (t <= 0)
{
*r1 = *r2 = 0;
}
else
{
*r1 = t / 2;
*r2 = t - *r1;
}
}
#include <stdio.h>
#include <string.h>
static void test_width(int width)
{
const char *data[] =
{
"A", "B",
"AA", "B",
"A", "BB",
"A", "BBB",
"A", "BBBB",
"AAA", "B",
"Hello", "World",
"Middle of", "the road",
"Welcome", "to Jurassic Park",
"Bienvenue", "a Paris",
"Twelve Place", "Twice - Over",
"Eleven Here", "Thirteen Here",
"Much much longer", "than this",
"A", "Discourse on Inequality",
"What sort of pedant am", "I",
"What an essay", "busting all the limits",
};
int num_pairs = (sizeof(data) / sizeof(data[0])) / 2;
for (int i = 0; i < num_pairs; i++)
{
int r1;
int r2;
const char *s1 = data[2 * i + 0];
const char *s2 = data[2 * i + 1];
int l1 = strlen(s1);
int l2 = strlen(s2);
centre_two_lengths(width, l1, l2, &r1, &r2);
printf("W = %2d, L1 = %2d, L2 = %2d, R1 = %2d, R2 = %2d ", width, l1, l2, r1, r2);
printf("|%*s[ %s %s ]%*s|\n", r1, "", s1, s2, r2, "");
}
}
int main(void)
{
for (int width= 28; width < 34; width++)
test_width(width);
return(0);
}
如果你不想要尾随空格,你可以简化函数 - 它可以简单地返回前导空格所需的值,你可以从格式字符串中删除尾随%*s
和{ {1}}以及随后的r2
。简单的垂直条就在那里你可以看到数据是否正确居中(并且尾随条需要尾随空格才有意义)。
输出:
""