如何从 C++ 中删除字符串中的 \0当用 C# 读取时
我有点被困在这里了。我正在为 Commerce Server 2009 开发一个自定义 Pipeline 组件,但这与我的问题无关。
在管道的设置中,我为用户提供了一个窗口窗体来输入一些配置值。这些值之一是 SharePoint 网站的 URL。 Commerce Server 在所有这些管道内容背后使用 C++ 组件,因此输入的值被放入 IDictionary 中,并最终通过 Microsoft 的 C++ 组件持久保存到数据库。
当我在管道执行期间读取字符串时,它会通过 C++ 的 IDictionary 对象传递给我。我的 C# 代码发现该 URL 后缀为 \0\0。我不确定它们来自哪里,但我的代码崩溃了,因为它不是有效的 URI。我在保存之前修剪字符串,并在阅读时修剪它,但仍然无法摆脱它们。
有什么想法导致这个问题以及我如何摆脱它吗?我不喜欢像子字符串那样进行黑客攻击,而是要找到根本原因。
谢谢, 科里
I'm kind of stuck here. I'm developing a custom Pipleline component for Commerce Server 2009, but that has little to do with my problem.
In the setup of the pipe, I give the user a windows form to enter some values for configuration. One of those values is a URL for a SharePoint site. Commerce Server uses C++ components behind all this pipeline stuff, so the entered values are put into an IDictionary and eventually persisted to the DB via the C++ component from Microsoft.
When I read the string in during pipeline execution, it is handed to me in an IDictionary object from C++. My C# code sees that URL suffixed with \0\0. I'm not sure where those are coming from, but my code blows up because it's not a valid URI. I am trimming the string before I save it and trimming it when I read it and still can't get rid of those.
Any ideas what is causing this and how I can get rid of it? I prefer not to have a hack like substring it, but something that gets at the root cause.
Thanks,
Corey
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这会有所帮助吗:
Would this help:
正如其他人的帖子所解释的,C 中的字符串是以 null 结尾的。 (但是请注意,C++ 已经提供了一个不依赖于此的字符串类型。)
您的情况略有不同,因为您得到的是双空终止字符串。我不是这方面的专家,所以如果我错了,任何人都应该随时纠正我。但这看起来像是 Windows 中使用宽字符的 unicode/i18n 感知应用程序的典型字符串表示形式。请查看此。
一种猜测是,将字符串持久保存到数据库中的应用程序没有使用“可移植”策略。例如,它可能会考虑字符串缓冲区的大小(以原始字节为单位)而不是其实际长度。前者最终会计算额外的两个零(因此,也会保留它们),而后者会丢弃它们。
As the others' posts explained, strings in C are null-terminated. (Notice that C++, however, already provides a string type which doesn't depend on that.)
Your case is just a bit different because you're getting double-null-terminated string. I'm not an expert here, so anyone should feel free to correct me if I'm wrong. But this looks like a typical string representation for unicode/i18n aware applications in Windows which use wide characters. Please, take a look at this.
One guess is that the application which is persisting the string into the database is not using a "portable" strategy. For example, it might be persisting the string buffer considering its size in raw bytes instead of its actual length. The former would be counting the extra two zeros in the end (and, consequently, persisting them too) while the latter would discard them.
来自此站点:
C 中的字符串只是一个字符数组,最后一个字符集为 NUL 字符(ascii/unicode 点 0)。这个空终止符是必需的;如果字符串不存在,则该字符串格式错误。 C/C++ 中的字符串文字标记(“string”)保证了这一点。
与相同 因此
,一旦 C++ 组件获取您的 IDictionary,它就会将以 null 结尾的字符串添加到末尾。如果要删除它,则必须在发回字典之前删除末尾的空终止字符。请参阅这篇文章了解如何删除空终止字符。基本上,您需要知道确切的尺寸并将其修剪掉。
From this site:
A string in C is simply an array of characters, with the final character set to the NUL character (ascii/unicode point 0). This null-terminator is required; a string is ill-formed if it isn't there. The string literal token in C/C++ ("string") guarantees this.
is the same as
So as soon as the C++ component gets your IDictionary, it will add the null-terminated string to the end. If you want to remove it, you will have to remove the null terminated char from the end before sending back the dictionary. See this post on how to remove a null terminated character. Basically you need to know the exact size and trim it off.
您可以使用的另一种技术是字符数组和数组的长度。字符数组不需要终止空字符。
当您传递此数据结构时,您还必须传递长度。 C 样式字符串的约定是通过搜索“\0”(或在 Unicode 中为“\0\0”)来确定字符串的结尾。由于数组没有终止字符,因此始终需要长度。
更好的解决方案是使用
std::string
。它不附加空字符。当您需要兼容性或 C 风格格式时,请使用c_str()
方法。我必须在我的程序中使用这种技术,因为 GUI 框架有自己的字符串数据类型,与std::string
不兼容。Another technique you can use is an array of characters and the length of the array. An array of characters does not need a terminating null character.
When you pass this data structure, you must pass the length also. The convention for the C-style strings is to determine the end of the string by searching for a '\0' (or in Unicode, '\0\0'). Since the array doesn't have the terminating characters, the length is always needed.
A much better solution is to use the
std::string
. It doesn't append null characters. When you need compatibility, or the C-style format, use thec_str()
method. I have to use this technique with my program because the GUI framework has its own string data type that is incompatible withstd::string
.