如何为等宽输出填充CJK/ASCII混合内容?技术实现问询
Unreal控制台混排文本对齐方案
一、字体选择(核心前提)
- 优先选Sarasa Gothic:专为中日英混排设计的等宽字体,ASCII字符与CJK字符宽度完全一致,用普通空格就能轻松实现对齐,是最优解。
- 可选GNU Unifont:全字符等宽,支持所有Unicode字符,但字体风格偏像素化,视觉效果一般,对齐逻辑和Sarasa一致。
- 绝对排除Fira Code+非等宽DroidSans组合:CJK字符宽度约为ASCII的2倍,无论怎么调整空格都无法实现相对整齐的对齐,直接放弃。
二、填充量计算(基于等宽字体)
对齐逻辑(以你的右对齐示例为准)
- 确定第一列最大字符数:遍历所有第一列文本,统计每个文本的字符数(等宽字体下,ASCII、符号、CJK都算1个单位长度),取最大值作为基准长度。
比如你的示例中,「追不到我别生气」是7个CJK字符,为第一列最长内容,基准长度即为7。 - 计算单条目的填充空格数:对每个第一列文本,用
基准长度 - 当前文本的字符数,得到需要前置的空格数量。
比如「ABC-花海」的字符数是3(ASCII)+1(符号)+2(CJK)=6,填充空格数就是7-6=1;若要追求示例中更宽松的视觉间距,可手动把基准长度设为更大值(比如12)。 - 拼接输出文本:把计算好的空格填充在第一列文本前,再拼接后面的
| 数字 | 数字部分,输出到控制台。
Unreal C++代码示例
// 模拟待输出的数据 TArray<FString> TargetNames = {TEXT("ABC-花海"), TEXT("JustSomeAnsi"), TEXT("花花花花花花"), TEXT("追不到我别生气")}; TArray<int32> NumGroup1 = {123, 123, 123, 123}; TArray<int32> NumGroup2 = {456789, 456789, 456789, 456789}; // 计算第一列的最大字符长度 int32 MaxNameWidth = 0; for (const FString& Name : TargetNames) { MaxNameWidth = FMath::Max(MaxNameWidth, Name.Len()); } // 生成格式化文本并输出到控制台 for (int32 Index = 0; Index < TargetNames.Num(); ++Index) { const FString& CurrName = TargetNames[Index]; int32 PaddingCount = MaxNameWidth - CurrName.Len(); FString OutputLine = FString::ChrN(PaddingCount, TEXT(' ')) + CurrName + TEXT(" | ") + FString::FromInt(NumGroup1[Index]) + TEXT(" | ") + FString::FromInt(NumGroup2[Index]); UE_LOG(LogTemp, Log, TEXT("%s"), *OutputLine); }
三、非等宽字体的妥协方案(不推荐)
如果必须使用非等宽CJK字体,只能近似估算:把每个CJK字符按2个ASCII字符宽度计算,ASCII按1个单位计算,统计每条文本的总宽度,再用最大总宽度减去当前宽度,得到需要填充的ASCII空格数。但这种方式误差极大,对齐效果无法保证,仅作为最后备选。
内容的提问来源于stack exchange,提问作者Digika
相关产品推荐
相关产品推荐

