5

我需要在一块内存中搜索一串字符,但是其中几个字符串的每个字符都为空字符,如下所示:
“I. .am .a. .string”
,所有的 '.' 都是空的人物。我的问题实际上来自于将它记入内存。我尝试了几种方法,例如:

 char* str2; 
 str2 = (char*)malloc(sizeof(char)*40);   
 memcpy((void*)str2, "123\0567\09abc", 12);    

将以下内容放入 str2 指向的内存中: 将 str2 指向一个看起来像 的内存块123.7.9abc..
,其中 '.' 是一个空字符,',' 是一个实际的逗号。
str2 = "123456789\0abcde\054321";
123456789.abcde,321

很明显,将空字符插入 cstrings 并不像我想象的那么容易,就像插入换行符一样。我在尝试使用字符串库时也遇到了类似的困难。我可以做单独的任务,比如:

 char* str;    
 str = (char*)malloc(sizeof(char)*40);  
 strcpy(str, "123");  
 strcpy(str+4, "abc");  
 strcpy(str+8, "ABC");  

但这肯定不是可取的,我相信问题在于我对 c 样式字符串如何存储在内存中的理解。61 62 63 00 31 32 33显然“abc\0123”实际上并没有像(十六进制)那样进入内存。它是如何存储的,我如何存储我需要的东西?

(我也很抱歉没有将代码设置为块,这是我第一次发布问题,不知何故“四行间距”显然比我能处理的要困难。谢谢你,Luchian。我看到需要更多的换行符。)

4

4 回答 4

6

如果每个其他都char包含一个空值,那么几乎可以肯定你实际上有 UTF-16 编码的字符串。相应地处理它们,您的问题就会消失。

假设你在 Windows 上,UTF-16 很常见,你会使用wchar_t*而不是char*保存这样的字符串。您将使用宽字符字符串处理函数对此类数据进行操作。例如,使用wcscpy而不是strcpy等等。

于 2012-06-13T20:11:47.697 回答
3

\0是八位字节中转义字符的起始序列,它不仅仅是一个“空字符”(即使使用它自己的会导致一个)。


定义包含空字符的字符串后跟也可以视为八位字节中转义字符的一部分的字符串(例如 "\012" 1)的最简单方法是使用以下 C 功能将其拆分:

char const * p = "123456789" "\0" "abcde" "\0" "54321";

1、“\012”会产生等价十六进制值0x0A的字符,而不是三个字符;0x00、“1”和“2”。

于 2012-06-13T20:24:01.497 回答
2

首先,每个第二个字符都是 NULL 是宽字符串的明显标志 - 一个由双字节字符组成的字符串,实际上是一个unsigned shorts 数组。根据您的编译器和设置,您最好使用数据类型wchar_t而不是函数系列而char不是.wcsxxx()strxxx()

在 Windows 上,2 字节宽字符串(UTF-16,技术上)是操作系统的原生字符串格式,所以它们无处不在。

也就是说,strxxx() 函数都假定字符串是空终止的。所以相应地计划。有时 memxxx() 会来救援。

"abc\0123" 不会以您期望的方式进入内存,因为 \012 被编译器解释为单个八进制转义序列 - 八进制代码为 12 的字符(即 0a 十六进制)。为避免,请使用以下文字之一:

"abc\000123"
"abc\x00123"
"abc\0""123"

从块中生成字符串的片段大部分是正确的。只是我宁愿使用

strcpy(str+strlen(str)+1, "123");

这保证了下一个块将被写入前一个块的空字符之后。

于 2012-06-13T20:16:03.860 回答
0

我对你的问题有点困惑。但让我猜猜发生了什么。您正在查看 16 位 wchat_t 字符串,而不是普通的 c 字符串。wchar 获取 ascii 字符可能看起来像在字母之间分隔的空值,但实际上这是正常的。

简单地说 (wchar_t *)XXX 其中 XXX 是指向该内存区域的指针并查找 wchar_t 操作(如 wcscpy 等)...至于字符串之间的空值,这实际上可能是传递多个字符串构造的已知方法。您可以在读取每个字符串后简单地迭代,直到通常遇到 2 个连续的空值。

希望我已经回答了你的问题。祝你好运!

于 2012-06-13T20:17:25.220 回答