Discuz!NT官方社区

首页 » Discuz!NT交流与讨论 » BUG 反馈 » 个人空间首页乱码(更新:乱码和正常文字同时显示)(再更新:...)(再再更新:对GetSubString函数的改进)
Brandon - 2008-3-10 8:49:00
a 论坛版本: 2.1 net框架版本:2.0  Windows版本: 服务器未知,本地主机WINDOWS2003

b 出现问题描述: 全新安装2.1,其他一切显示正常,但个人空间首页的文章标题全是乱码,其他页面目前还没发现乱码,此问题在我的本地测试机器上正常,但我的机器是中文环境,出现问题的是租用的主机,主机在美国,机器环境应该是英文的,我已经让管理员把后台数据库改成中文编码了。

c 出现问题前做的修改是: 全新安装2.1版

d 问题截图
戏水 - 2008-3-10 10:26:00
请在建立数据库的时候 排序规则设置为 Chinese_PRC_CI_AS
Brandon - 2008-3-10 10:54:00
为什么所有其他的页显示正常,只有个人空间首页显示有问题?
排序规则已经修改过了,修改过之后我还把我本地的数据库发布到服务器上,都不能正常显示。
Brandon - 2008-3-10 11:17:00
OK,再补充一点:
我用本机的程序(localhost),数据库用远程服务器上的,显示是正常的。
所以应该和数据库服务器的设置没关系吧。
Brandon - 2008-3-10 15:08:00
再贴一张图,乱码和正常文字同时显示
chenxi621 - 2008-3-11 11:56:00
怎么发表新帖
Brandon - 2008-3-12 12:25:00
今天用2.0版的src不做任何修改重新编译后上传到服务器,发生如下错误:


如何对Discuz.Common下的Utils.cs文件做了如下修改:
将public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)函数中的内容全部删除,只保留如下内容:
return p_SrcString.Substring(p_StartIndex,((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length);
即不考虑中日韩编码的问题,直接截取字符串返回,结果显示正常,如下:


经过如下测试,我认为Utils.cs下的GetSubString函数还是存在问题的。这只是我的临时解决方法,不知道2.1版是否对此文件做了修改。
建议官方能再仔细测试一下这个函数,尽快给出解决方案。
Brandon - 2008-3-13 11:11:00
今天花了点时间研究了一下2.0代码里的Discuz.Common.Utils.GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)函数
这段代码在英文系统下是存在问题的。

首先对于以下这两段测试字符串:
1. 加拿大安大略Algonquin Park游记
2. 用一个位元组表示,超出ASCII码的范围就用位元组表示
程序走的路径是不一样的,对于第2段测试代码,程序认为是日文或韩文

其次,在英文系统下,用Encoding.Default.GetBytes(p_SrcString),是不会返回正确编码的,而且返回字符串的长度并不是确切指定的长度。在中文环境下是没有问题的。
经过研究,写了一个GetSubString函数,代码和说明如下,可以用summary上面的字符做测试。

由于时间仓储,可能代码还有不完善的地方,希望和大家一起探讨。


        //////////////////////////////////////////////////////////////////////////       
        ///
        ///
        /// 加拿大安大略Algonquin Park游记
        /// 用一个位元组表示,超出ASCII码的范围就用位元组表示
        /// 当要截取的长度在字符串的有效长度范围内
        /// αβγδεζηθικλμνξοπρΣτυφχψω
        /// 後に生まれたものでもある。今日でも現代ギリシア語の表記に用いられ
        /// 장나라 아시아통합음반의 의의
        ///
        ///
        /// <summary>
        /// 取指定长度的字符串
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_StartIndex">起始位置</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <param name="p_DoubleByte">一个非英文字符是否按一个字符计算,不包括重音文字、希腊字母或西里尔字母</param>
        /// <returns></returns>
        public string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString, bool p_DoubleByte)
        {
            string myResult = "";
            int nUTF8Length = 0;       
            int nUTF8StartIndex = 0;   
            int iSrcLength = 0;       
            int iSrcStartIndex = 0;   
            if (p_StartIndex % 2 > 0)
                p_StartIndex--;
            if (p_Length % 2 > 0)
                p_Length--;
            byte[] bsSrcString = Encoding.UTF8.GetBytes(p_SrcString);
            for (int iUTF8 = 0; iUTF8 < bsSrcString.Length; iUTF8++)
            {
               
                if (iSrcStartIndex == p_StartIndex)
                    nUTF8StartIndex = iUTF8;               
                if (iSrcLength == p_Length)
                    nUTF8Length = iUTF8 - nUTF8StartIndex;
                int extendLength = 0;
                if (bsSrcString[iUTF8] >= 0xFD)        //1111110x
                    extendLength = 5;
                else if (bsSrcString[iUTF8] >= 0xF9)    //111110xx
                    extendLength = 4;
                else if (bsSrcString[iUTF8] >= 0xF1)    //11110xxx
                    extendLength = 3;
                else if (bsSrcString[iUTF8] >= 0xE1)    //1110xxxx
                    extendLength = 2;
                else if (bsSrcString[iUTF8] >= 0xC1)    //110xxxxx
                    extendLength = 1;
                else                                    //0xxxxxxx
                    extendLength = 0;
                if (p_DoubleByte && bsSrcString[iUTF8] >= 0xE1)
                {
                    iSrcLength += 2;
                    iSrcStartIndex += 2;
                }
                else
                {
                    iSrcLength++;
                    iSrcStartIndex++;
                }
                iUTF8 += extendLength;
            }
            if (nUTF8Length == 0)
                nUTF8Length = bsSrcString.Length;
            byte[] bsResult = new byte[nUTF8Length];
            Array.Copy(bsSrcString, nUTF8StartIndex, bsResult, 0, nUTF8Length);
            myResult = Encoding.UTF8.GetString(bsResult);
            myResult = myResult + p_TailString;
            return myResult;           
        }
xzs - 2008-3-20 12:44:00

2.1版问题还在。肯定是Bug. 不知道什么时候有补丁出来?

请看:http://www.quanyuan.org  (SQL Server 2000 English Version)
Brandon - 2008-3-29 0:15:00


引用:
原帖由 Brandon 于 2008-3-13 11:11:00 发表
今天花了点时间研究了一下2.0代码里的Discuz.Common.Utils.GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)函数
这段代码在英文系统下是存在问题的。

首先对于以下这两段测试字符串:
1. 加拿大安大略Algonquin Park游记
2. 用一个位


做了一点点修改:
        //////////////////////////////////////////////////////////////////////////       
        ///
        ///
        /// 加拿大安大略Algonquin Park游记
        /// 用一个位元组表示,超出ASCII码的范围就用位元组表示
        /// 当要截取的长度在字符串的有效长度范围内
        /// αβγδεζηθικλμνξοπρΣτυφχψω
        /// 後に生まれたものでもある。今日でも現代ギリシア語の表記に用いられ
        /// 장나라 아시아통합음반의 의의
        ///
        ///
        /// <summary>
        /// 取指定长度的字符串
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_StartIndex">起始位置</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <param name="p_MultiByte">一个非英文字符是否按多字节计算,不包括重音文字、希腊字母或西里尔字母</param>
        /// <returns></returns>
        public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString, bool p_MultiByte)
        {
            string myResult = "";
            int nUTF8Length = 0;       
            int nUTF8StartIndex = 0;   
            int iSrcLength = 0;       
            int iSrcStartIndex = 0;   
            bool bHasUTF8StartIndex = false;
            bool bHasUTF8Length = false;

            if (p_StartIndex % 2 > 0)
                p_StartIndex--;
            if (p_Length % 2 > 0)
                p_Length--;

            byte[] bsSrcString = Encoding.UTF8.GetBytes(p_SrcString);

            for (int iUTF8 = 0; iUTF8 < bsSrcString.Length; iUTF8++)
            {
                if (iSrcStartIndex >= p_StartIndex && !bHasUTF8StartIndex)
                {
                    bHasUTF8StartIndex = true;
                    nUTF8StartIndex = iUTF8;
                }
                if (iSrcLength - p_StartIndex >= p_Length && !bHasUTF8Length)
                {
                    bHasUTF8Length = true;
                    nUTF8Length = iUTF8 - nUTF8StartIndex;
                }

                if (bHasUTF8Length && bHasUTF8StartIndex)
                    break;

                int extendLength = 0;
                if (bsSrcString[iUTF8] >= 0xFD)        //1111110x
                    extendLength = 5;
                else if (bsSrcString[iUTF8] >= 0xF9)    //111110xx
                    extendLength = 4;
                else if (bsSrcString[iUTF8] >= 0xF1)    //11110xxx
                    extendLength = 3;
                else if (bsSrcString[iUTF8] >= 0xE1)    //1110xxxx
                    extendLength = 2;
                else if (bsSrcString[iUTF8] >= 0xC1)    //110xxxxx
                    extendLength = 1;
                else                                    //0xxxxxxx
                    extendLength = 0;

                if (p_MultiByte && bsSrcString[iUTF8] >= 0xE1)
                {
                    iSrcLength += extendLength;
                    iSrcStartIndex += extendLength;
                }
                else
                {
                    iSrcLength++;
                    iSrcStartIndex++;
                }
                iUTF8 += extendLength;
            }

            if (!bHasUTF8Length)
            {
                nUTF8Length = bsSrcString.Length - nUTF8StartIndex;
                p_TailString = "";
            }

            byte[] bsResult = new byte[nUTF8Length];

            Array.Copy(bsSrcString, nUTF8StartIndex, bsResult, 0, nUTF8Length);

            myResult = Encoding.UTF8.GetString(bsResult);

            myResult = myResult + p_TailString;

            return myResult;
        }
平安数据 - 2008-4-5 18:13:00
我知道我的乱码是怎么回事了,多谢!
1
查看完整版本: 个人空间首页乱码(更新:乱码和正常文字同时显示)(再更新:...)(再再更新:对GetSubString函数的改进)