为什么dll通过缓冲区返回的字符串后面多了不相干的字符

c++dll int Funs(char* a){ string s = "23454624,5523465,256347354,25637256237,516662562"; memcpy(a,s.c_str(),strlen(s.c_str() )); return 0;} c#调用[DllImport("ts.dll")] public static extern string Funs(StringBuilder a); c#main() StringBuilder strRet = new StringBuilder("",1000); ReadSectorInfo(strRet); Console.WriteLine(strRet); 输出结果应该为最后一个字应该为2,为什么多了一位不相干的字母字符?
比如我想将string s = "23454624,5523465,256347354,25637256237,516662562,256666663,9887866"; 的s字符串输出,可是结果输出为23454624,5523465,256347354,25637256237,516662562,256666663,98878661,最后多了一个“1”,改变这个字符串的长度最后一位也会改变,比如变为“m”等。除了最后一位,前面的都是正确的,这是为什么?

第1个回答  2013-02-01
CString是一个有用的数据类型。他们极大地简化了许多操作在做字符串操作时,MFC,MFC方便。总之,有很多特殊的技能,使用CString有点难以学习,特别是在黎明的背景为纯C + +程序员。这篇文章是讨论这些技术。
使用CString可以让你更简单的串。这篇文章是不是CString的完全手册,但最常见的基本问题。
文章包括以下内容:
CString对象
格式字符串(int类型转换到CString)
CString的连接转换成int类型
CString的,相互转化的类型是char *类型
的char *到CString的
CString的成char *之一:使用LPCTSTR强制转换
CString的成char *第二:使用CString对象的GetBuffer方法
CString的成char *之三:和控制接口
CString的类型转换成BSTR类型的
BSTR类型转换成CString的类型;
VARIANT类型转换成CString的类型;的
加载的字符串表资源; CString的临时对象;
CString的效率;
总结
我在下面讨论。
[编辑本段]的CString对象连接
能反映CString类型的便利功能连接字符串CString的类型,你可以很容易地连接两个字符串,如下面的示例:
CString的灰色( “灰色”);
CString的猫(“猫”);
CString的graycat =灰+猫;
比下面的方法好得多:
字符灰色[] = “灰色”;
字符猫[] =“猫”;

字符* graycat =的malloc(strlen的(灰色)+ strlen的(猫)+ 1);
STRCPY( graycat,灰色);
strcat的(graycat,猫);
[编辑本段] 2,格式字符串
的sprintf()函数或wsprintf()函数来格式化字符串,而不是CString对象格式()方法:
CString的;
s.Format(_T(“总为%d”),总);
这种方法的好处是,你不必担心缓冲区是否足够大,存储格式的数据,为你做这些工作由CString类。
格式是一个字符串类型的CString类型的数据转换成最常用的技术,例如,一个整数转换为一个CString,可以使用如下:
CString的;
。的格式(_T(“%d”),总);
我总是用我的字符串_T()宏来我的代码至少有Unicode的意识,当然,主题的范围是不是在文章中对Unicode 。 _T()宏在八个字环境的定义如下:
定义_T(x)x / /非Unicode版本(非Unicode版本)
Unicode环境的定义如下:...... />#_T(X)L##X / / Unicode的版本(Unicode版本)
Unicode环境,其效果相当于:
s.Format(L%D“,总);
如果你认为你的程序可以运行在Unicode环境,然后开始关心使用Unicode编码。例如,不使用sizeof()运算符来获得字符串的长度,因为会有2倍的错误在Unicode环境中,我们可以使用一些方法来隐藏一些细节的Unicode编码,当我需要的字符长度,例如,我将使用一个所谓的DIM宏,这个宏定义在我的dim.h文件,我会写我的程序包含此文件:

定义DIM(x)的(如sizeof((X))/大小((X)[0])) />这个宏可以不仅用来解决的Unicode的字符串的长度的问题,也可以在编译时定义的形式使用,可以得到在表中的项目的数目,如下所示: BR />类无论{...};
无论数据[] = {
{...}

{...}, />};
为(int i = 0; I <DIM(数据),我+ +)/ /扫描表中找到一个匹配。
这里要提醒大家,我们一定要注意那些需要真正的API函数调用的参数中的字节数,如果你传递给它的字符数,它不会正常工作。具体情况如下:TCHAR数据[20];
lstrcpyn(数据longstring大小(数据) - 1)/ /错误!
lstrcpyn(数据longstring DIM(数据) - 1)/ / RIGHT
WriteFile的(F,数据,DIM(数据),与bytesWritten, NULL); / /错误!
WriteFile的(F,数据大小(数据)的,与bytesWritten,NULL); / / RIGHT
造成上述原因是因为lstrcpyn的字符数作为参数,但WriteFile的所需的字节数作为参数。还需要注意的是,有时需要写的所有的数据内容,如果你只是想写的数据的真实长度,你可能会我想你应该这样做:
的WriteFile(F数据lstrlen(数据),与bytesWritten,NULL); / /错误
但在Unicode环境,它没有正常工作。正确的方法是这样的
WriteFile的(F,数据,lstrlen()* sizeof(TCHAR)的,与bytesWritten,NULL); / / RIGHT
WriteFile的需要以字节为单位的长度。(有可能有些人会想在非Unicode的环境下运行这行代码意味着永远做一个额外的客运业务,这将不会减少的有效性的程序?“我们的想法是多余的,你必须了解编译器实际上做任何事情,其中??C C + +编译器在Unicode环境中运行时,会出现这样的无聊的操作逗留在代码中,你不必担心2操作会降低程序的运行效率,记住,这仅仅是一个左一个操作肫饕餮端口傅钟馕领带耶稣庵痔母狗弧#?BR>使用_T宏并不意味着你必须创建一个Unicode程序,你只需要创建一个具有Unicode意识的程序只编译,如果你默认情况下,8位模式下,编译程序,然后得到一个常规的8位字节的应用程序(这里是指8位只有8位的字符编码??,并不意味着有八个计算机系统),当你编译你的程序中在Unicode环境中,你会得到一个Unicode的程序。记住,CString的,它包含了所有16个字符在Unicode环境,哦

[编辑本段] 3,CString的类型转换成int类型
CString的类型的数据转换为整数类型最简单的方法是使用标准的字符串到整数转换例程。
尽管您通常涉嫌使用_atoi()函数是一个不错的选择,它很少是正确的选择,如果你准备好使用的Unicode字符,你应该使用_ttoi的(),ANSI编码系统被编译成_atoi()在Unicode编码系统编译成_wtoi(),你也可以考虑使用_tcstoul()或_tcstol(),就可以字符串转换成任意的十六进制长整数(如二进制,八进制,十进制或十六进制),所不同的是,前者的数据转换为无符号(无符号),而后者则是相反的。在下面的例子所示:
CString的十六进制= _T( “FAB”);
CString的(十进制)= _T(“4011”);
ASSERT(_tcstoul(十六进制,0,16)== _ttoi(十进制)的帮助);
[编辑本段4的CString和char *类型的相互转化
这是初学者CString的最常见的问题与C + +,你并不需要大量的问题进行深入考虑直接用就行了,但如果可以的话在深入了解其运行机制,将有很多为你感到困惑的问题,尤其是一些看起来没有问题的代码,却偏偏不能正常工作。
例如,你可能会问,为什么不写下面的代码:
CString的graycat =“灰色”+“猫”;

CString的graycat(灰色“+”猫“);
事实上,编译器会抱怨,这些尝试。为什么呢?CString和LPCTSTR数据类型的多种组合,“+”操作??符被定义为重载运算符,而不是两个LPCTSTR数据类型,它是基本数据类型,你不能基本数据(如整型,字符或char *)类型重载C + +操作符,你可以象下面这样做:
CString的graycat = CString的(“灰色”)+ CString的(“猫”);
或者这样:
CString的graycat = CString的(“灰色”)+“猫”;
研究有些人会觉得:“+”总是使用至少一个CString对象,LPCSTR的场合。
>注意写代码的Unicode意识始终是一件好事,如:
CString的graycat的CString(_T(“灰色”))+ _T(“猫”);
这会让你的代码可以直接移植。
的char *转换CString的
你有一个char *类型的数据,或者一个字符串如何创建一个CString对象?下面是一些例子:
的char * p =“这是测试“;
这样多个Unicode意识:
TCHAR * p = _T(”这是一个测试“)

LPTSTR p = _T(”这是在测试“);
您可以使用以下任何一种写法:
CString的S =”这是一个测试; / / 8位
CString的S = _T(“这是一个测试“); / / Unicode感知
CString的(”这是一个测试“); / / 8位
的CString(_T(”这是一个测试“)) ; / / Unicode感知
CString的S = P
CString的S(P);
这些方法可以很容易地转换的CString的注意分配的字符常量字符串或指针总是复制到CString对象,所以你可以像以下操作:
TCHAR * p = _T(“灰色”),
CString的S(P);
P = _T(“猫”)

+ = P;的
生成的字符串当然是GrayCat的。
CString类有几个构造函数,但在这里我们不考虑它,如果你有兴趣的话,可以查看文件。
在事实上,比我表现出更多的复杂,比如:CString类的构造函数
CString的S =“这是一个测试”;
这是非常草率的编码,但事实上,它可以在Unicode环境称为MultiByteToWideChar操作在运行时构造函数的字符串转换成一个16字符串。无论如何,char *指针是8位数据传输在网络上被编译,这种转换是
CString型为一体的char *转换为LPCTSTR;
这是一个稍微刚性转换,“正确”的方法,理解有很多混乱的,正确的使用方法有很多,但使用的错误尽可能地用正确的方式使用。
我们首先要了解CString是一个非常特殊的C + +对象,它包含三个值:一个指向数据缓冲区的指针,缓冲区的字符数,以及有效的字符数可以任意数量从0到最大长度的缓冲值减1之间(因为一个NULL字符结束的字符串)。字符数的大小的缓冲区的长度和的缓冲区长度被巧妙地隐藏。
除非你做一些特殊的操作,否则,你可以不知道CString对象分配的缓冲区的长度,即使你得到的0缓冲的地址,你可以不改变其中的内容不能被截断的字符串,是绝对没有办法延长其内容,否则,你会看到溢出的第一次。
LPCTSTR操作符(或者更具体地说,是TCHAR *操作符)的CString运营商定义的类被重载,返回地址的缓冲区,因此,如果你需要一个CString的字符串指针的指针,你可以这样做:
CString的(“GrayCat);
LPCTSTR P = S;

它可以正常运行,这是从C语言的强制类型转换规则。需要强制类型转换,C + +仪表允许这样的选择。例如,你可以将(浮点数)被定义为一的复数(一对浮点数)蒙上只返回一个复杂的持股量(即,事实上,该署)。像下面这样:
复杂的C(1.2F ,4.8f);
浮动,realpart = C;
(浮点)操作符定义正确的话,那么真正的价值应为1.2。
等强制转化适合所有这种情况下,功能,例如,任何一个LPCTSTR类型的参数将强制执行这种转换,所以你可能有这样的功能(也许你买了一个DLL):
BOOL DoSomethingCool(LPCTSTR);
你怎么称呼它是这样的:
CString的文件(“C:\ \ myfiles文件\ \的Coolstuff”)
BOOL结果DoSomethingCool(文件);
可以正常运行。DoSomethingCool功能已经描述需要一个LPCTSTR参数LPCTSTR,因此,在MFC返回的参数字符串的地址。
如果你要格式化字符串怎么办呢?
的CString graycat(“GrayCat)的; <BR / CString的;
s.Format(Mew!我爱%“,graycat);
注意由于可变参数列表(在功能描述的基础上的价值......”表示)并不意味着转换运算符,你什么样的结果呢?
一个令人惊讶的结果,我们得到的实际结果字符串为:
“喵!我爱GrayCat”。
因为MFC设计师在设计CString的数据类型非常谨慎,指向一个字符串的CString类型表达式求值,请参阅没有像Format或sprintf转换转换,你仍然可以得到正确的行为。描述CString的附加数据实际上是在CString的名义地址之后。 BR />你不能这样做的一件事是字符串,例如,你可以尝试使用“,”而不是“(不这样做,如果你关心国际问题,你应该使用十进制转换的国家语言支持功能),下面是一个简单的例子:
的CString v(1.00“); / /货币量,到小数点后两位
LPCTSTR P = V;
p [lstrlen (P) - 3] =;
时,编译器会抱怨,因为
第2个回答  2013-02-02
楼主您好!个人觉得这是您在memcpy的时候漏掉了源串的结束符,也就是说copy的长度不该恰好是源串的长而应该是源串的长度+1,话说为什么不直接用strcpy或者strcpy_s呢?
第3个回答  2013-01-25
我也遇到过
相似回答