在内存中处理多个空字符的C字符串

时间:2012-06-13 20:09:10

标签: c

我需要在一块内存中搜索一串字符,但是这些字符串中的一些字符串将每个字符分隔为空,如下所示:
    “I.a.m .a .s.t.r.i.n.g” 所有'。'都是空字符。我的问题来自实际上将其记入内存。我尝试了几种方法,例如:

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

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

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

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

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

(我也为没有设置代码的代码道歉,这是我第一次发帖提问,不知何故“四个间隔”比我能处理得更困难。谢谢你,Luchian。我看到更多的换行符了需要的。)

4 个答案:

答案 0 :(得分:6)

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

假设您使用的是UTF-16常见的Windows,您可以使用wchar_t*而不是char*来保存此类字符串。并且您将使用宽字符串处理函数来操作此类数据。例如,使用wcscpy而不是strcpy等等。

答案 1 :(得分:3)

\0是八位位组中转义字符的起始序列,它不仅仅是一个“空字符”(即使使用它本身也会产生一个)。


定义包含 null-character 的字符串的最简单方法,后面还可以将某些字符串视为八位字节中转义字符集的一部分(例如“\ 012” < strong> 1 )是使用C:

的以下功能将其拆分
char const * p = "123456789" "\0" "abcde" "\0" "54321";

1。“\ 012”将导致字符的等效十六进制值为0x0A,三个字符; 0x00,'1'和'2'。

答案 2 :(得分:2)

首先,每隔一个字符为NULL就是宽字符串的明显标志 - 一个由双字节字符组成的字符串,实际上是unsigned short的数组。根据您的编译器和设置,您可能最好使用数据类型wchar_t而不是charwcsxxx()系列函数而不是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");

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

答案 3 :(得分:0)

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

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

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