Gnu*_*bie 5 c bash printf justify text-justify
在C或Bash shell中使用printf,如何将两个字符串(字符数组)左右对齐到给定长度?
例如,如果字符串是"堆栈"和"溢出",并且长度是20个字符,我希望打印
stack-------overflow
Run Code Online (Sandbox Code Playgroud)
(为清楚起见,每个空间都显示为破折号).
字符串长度未知.如果总长度+ 1超过给定的长度,是否可以从给定方向截断一个或两个字符串并在它们之间留一个空格?例如,如果长度为10,我们可以得到这些吗?
stack-over
stack-flow
s-overflow
k-overflow
Run Code Online (Sandbox Code Playgroud)
我知道的printf("%10秒",字符串)证明一个字符串的权利和printf("% - 10秒",字符串)证明一个字符串的左边,但不能找到一种方法来证明2串,或截断他们.
这比电池长,但恕我直言,它可以更好地分割琴弦。它还在可能的情况下使用 printf 进行截断,仅在第二个参数的左侧截断时回退到其他机制。
重击:
truncat () {
local len=$1 a=$2 b=$3 len_a=${#2} len_b=${#3}
if ((len <= 0)); then return
elif ((${len_b} == 0)); then
printf %-${len}.${len}s "$a"
elif ((${len_a} == 0)); then
printf %${len}.${len}s "${b: -$((len<len_b?len:len_b))}"
elif ((len <= 2)); then
printf %.${len}s "${a::1}${b: -1}"
else
local adj_a=$(((len_a*len+len_b-len_a)/(len_a+len_b)))
local adj_b=$(((len_b*len+len_a-len_b-1)/(len_a+len_b)))
printf "%-${adj_a}.${adj_a}s %${adj_b}.${adj_b}s" \
"$a" \
"${b: -$((len_b<adj_b?len_b:adj_b))}"
fi
}
Run Code Online (Sandbox Code Playgroud)
C:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void truncat(long len, const char* a, const char* b) {
if (len <= 0) return;
unsigned long long len_a = strlen(a);
unsigned long long len_b = strlen(b);
if (!len_b)
printf("%-*.*s", (int)len, (int)len, a);
else if (!len_a)
printf("%*s", (int)len, b + (len < len_b ? len_b - len : 0));
else if (len <= 2)
printf("%.1s%.*s", a, (int)(len - 1), b + len_b - 1);
else {
unsigned long long adj_a = (len_a * len + len_b - len_a) / (len_a + len_b);
unsigned long long adj_b = (len_b * len + len_a - len_b - 1) / (len_a + len_b);
printf("%-*.*s %*s",
(int)adj_a, (int)adj_a, a,
(int)adj_b, b + (adj_b < len_b ? len_b - adj_b : 0));
}
}
int main(int argc, char** argv) {
truncat(atol(argv[1]), argv[2], argv[3]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
示例输出:
$ for i in {0..20}; do printf "%2d '%s'\n" $i "$(./truncat $i stack overflow)"; done
0 ''
1 's'
2 'sw'
3 's w'
4 's ow'
5 'st ow'
6 'st low'
7 'st flow'
8 'sta flow'
9 'sta rflow'
10 'stac rflow'
11 'stac erflow'
12 'stac verflow'
13 'stack verflow'
14 'stack overflow'
15 'stack overflow'
16 'stack overflow'
17 'stack overflow'
18 'stack overflow'
19 'stack overflow'
20 'stack overflow'
Run Code Online (Sandbox Code Playgroud)
免责声明:算术可能会溢出,在这种情况下,输出将是错误的(或者,如果您可以将 strlen(a)+strlen(b) 安排为恰好 2^64 字节,则程序将 SIG_FPE)。如果有人关心的话,我可以为 adj_a 和 adj_b 计算提供解释。
| 归档时间: |
|
| 查看次数: |
10591 次 |
| 最近记录: |