首页 > 编程语言 >C#判断字符串的显示宽度

C#判断字符串的显示宽度

时间:2023-11-08 10:11:05浏览次数:48  
标签:ABCD 字符 中文 source C# 半角 全角 宽度 字符串

C#判断字符串的显示宽度

起因:

公司有一个使用项目使用HTML转换为PDF,其中有一个表格,表格的最后一列中的单元格,其字符串超长后会被丢弃,而不是换行到下一行展示(HtmlToPdf渲染引擎导致的,没办法更改)

解决方案:

根据字符串长度手动添加<br/>换行

var source = "ABCD";

if (GetLength(source)>2)
{
    source = source.Insert(2,"<br/>");
}

Console.WriteLine(source);
// 输出AB<br/>CD

int GetLength(string src)
{
    return src.Length;
}

出现了一个BUG:

当原始内容中存在中文时,中文字符的显示宽度大于英文字符的宽度,按照字符串中的字符数进行处理,并不准确

/*
* 中文:中文<br/>CD
* 英文:AB<br/>CD
*/

原因分析:

在文字的显示中,有全角和半角的区别

全角:指一个字符占用两个标准字符位置的状态。

半角:指一个字符占用一个标准字符位置的状态。

尝试解决:

字符编码:最早的字符编码为Ascii码,只考虑了英文语种使用者,后来随着计算机的普及,有了其他编码,比如GB2312、UTF8等,不止包含英文的字符编码,但是这些编码都对Ascii码进行了兼容

没有细心求证的结论:Ascii码对应的是半角,中文扩展部分是全角展示,半角显示宽度为全角的一半(这结论是我猜的,没有求证,如果不对还请提出批评指正)

通过上面猜测的结论,可以先对每个字符判断是不是Ascii字符来决定当前是全角还是半角


var source = "ABCD";
var index =InserAtDisplayWidth(2,source);
if (index!=-1)
{
    source = source.Insert(index,"<br/>");
}
// AB<br/>CD
Console.WriteLine(source);

var source2 = "中文CD"; 
var index2 =InserAtDisplayWidth(2,source2);
if (index2!=-1)
{
    source2 = source2.Insert(index2,"<br/>");
}
// 中<br/>文CD
Console.WriteLine(source2);



int InserAtDisplayWidth(int inserAtDisplayWidth, string source){
    int now =0;
    for (int i = 0; i < source.Length; i++)
    {
        if( char.IsAscii(source[i])){
            // 半角占一个显示宽度
            now +=1;
        }else{
            // 全角占两个显示宽度
            now +=2;
        };

        if (now>inserAtDisplayWidth)
        {
            return i;
        }
    }
    return -1;
}

通过对字符的判断,更加准确的匹配了分隔的位置,既避免了无效的空白区域,又避免了过长的字符串溢出导致看不到内容

/*
* AB<br/>CD
* 中<br/>文CD
*/

标签:ABCD,字符,中文,source,C#,半角,全角,宽度,字符串
From: https://www.cnblogs.com/wujuncheng/p/17816745.html

相关文章

  • 华为云CodeLab中GPU: 1*P100|CPU: 8核 64GB的显卡驱动与cuda版本
    需要加!!nvidia-smi安装torch时,cuda的版本要<=11.4......
  • 游戏评测CQ9玩家困扰:iOS 17 Bug困扰苹果,iPhone 16项目调整中
    苹果近日面临着iOS更新率的放缓问题,引发了一些不满,而苹果也对此表示了关切。最新CQ9游戏评测报道指出,苹果内部已通知员工,为了应对早期版本出现大量bug的问题,他们将推迟明年的iPhone、iPad和Mac软件更新。此次的重点任务不再是新增功能,而是修复缺陷并提高软件性能。据悉,苹果的软件工......
  • How to add an image on reportViewer (rdlc)
    OpenthereportintheDesigner.IntheToolBox,select/expandthe"ReportItems"section.Dragan"Image"field/controlontothereport.ClickontheimageandpressF4,thepropertieswindow popsup,underthegroupdatayou'llf......
  • SQL Server 2005 数据库对象命名规范 Database Naming Conventions(Guidelines)
    使用SQLServer2005命名数据库对象时可以参照微软的示例数据库AdventureWorks。其次可以参照以下内容:DatabaseNamingConventionsVersion1.1LastRevisedMay13,2004byJasonMaussThemaingoalofadoptinganamingconventionfordatabaseobjectsissothatyouand......
  • 台达PLC和昆仑通态触摸屏通讯设置
    今天,我们来一起学下下台达PLC与触摸屏之间无线通信的实现方法。其中触摸屏作为主站,台达PLC作为从站,并采用日系PLC专用无线通讯终端DTD435MC,作为实现无线通讯的硬件设备。台达PLC和触摸屏通讯关键是对于通讯参数的设置。触摸屏设置首先打开设备组态对话框如图,双击设备窗口对话框。显......
  • 阿里云认证 | 2023年ACP认证考试大揭秘
    阿里云大数据工程师ACP认证是面向大数据开发工程师的专业技术认证。它涵盖了大数据计算服务、大数据开发与治理平台、实时计算、实时数据仓库、检索分析服务、数据湖、大数据分析与可视化等多个方面的内容。通过获得这个认证,从业者将能够全面掌握大数据领域的相关知识和技能,从而更......
  • centos安装httpd发布静态网页(一)
    html网页发布到服务器上,需要安装httpd或者nginx之类。本文以apachehttpd为例。安装[root@VM-0-5-centoszjd]#yuminstallhttpdLoadedplugins:fastestmirror,langpacksDeterminingfastestmirrorsdocker-ce-stable......
  • 2023-11-08 360浏览器 new Date().getTime() 获取到的时间戳与其它浏览器(chrome、edge
    问题描述:360浏览器newDate().getTime()获取到的时间戳比chrome或者edge要多出一些时间。原因:360浏览器对newDate的兼容性与其它浏览器厂商不同。部分网友认为是在开了极速模式下的360浏览器,会采用webkit的引擎,对含有T字符的日期时间newDate的时候就会相差几个小时,详情请看:h......
  • pbootcms 后台内容列表搜索功能扩展及增加显示字段功能
    应项目要求,一个内容模型下栏目不宜分的层级过多,如新闻模块,分2022、2023、2024年度,每年度下分12个月,这样就是2层栏目,再依类别(科技、动漫、电影...)划分层级,栏目数量较多,而且不易管理,需要拓展功能,取content下author字段来区分类别,用不同的帐户添加新闻,默认author值=账户名称。记录......
  • C语言变量分类
    按照变量的定义位置分类,在函数外部定义的变量为全局变量或者外部变量;在函数内部定义的变量为局部变量。在不加修饰\(^*\)的情况下,全局变量的作用域是定义以下的整个文件,局部变量的定义域是定义以下的所在函数体。在函数内访问变量时,优先查找局部变量,所以如果局部变量与全局变......