2011-06-28 34 views
0

我想使用Mac OS X的listxattr C函数,并将它变成Python中有用的东西。手册页告诉我该函数返回一个字符串缓冲区,它是一个“简单的以NULL结尾的UTF-8字符串,并以任意顺序返回,在缓冲区名称之间不提供额外的填充。”麻烦理解如何处理C字符串

在我的C文件,我把它设置正确看来(我希望):

char buffer[size]; 
    res = listxattr("/path/to/file", buffer, size, options); 

但是,当我打印出来,我只得到只有第一个属性,这是两个字符长,即使它的大小是25.所以然后我手动设置缓冲[3] ='Z'和低,看看当我再次打印缓冲区我得到第一个TWO属性。

我想我明白发生了什么事。该缓冲区是一个以NULL结尾的字符串序列,并在它看到空字符时立即停止打印。但是,我应该如何将整个序列解压到所有的属性中呢?

我是C的新手,并用它来弄清楚用C来扩展Python的机制,并且跑到了这个很奇怪的地方。

回答

3
  1. char *p = buffer;
  2. 得到长度strlen(p)。如果长度为0,则停止。
  3. 处理第一个块。
  4. p = p + length + 1;
  5. 返回第2步。
+0

+1对于一个好的算法 – pmg

0

它看起来像listxattr返回它已经填充的缓冲区的大小,所以你可以使用它来帮助你。这里有一个想法:

for(int i=0; i<res-1; i++) 
{ 
    if(buffer[i] == 0) 
     buffer[i] = ','; 
} 

现在,而不是由空字符分隔,属性用逗号分隔。

1

所以你猜对了。

listxattr函数返回一堆以NULL结尾的字符串,它们彼此相邻。由于C中的字符串(和数组)只是内存的一部分,因此它们不会携带任何额外的信息(比如它们的长度)。 C中的约定是使用空字符('\ 0')来表示字符串的结尾。

以下是遍历列表的一种方法,在这种情况下将其更改为逗号分隔列表。

int i = 0; 
for (; i < res; i++) 
    if (buffer[i] == '\0' && i != res -1) //we're in between strings 
     buffer[i] = ','; 

当然,你会想把它们变成Python字符串,而不是用逗号代替,但这应该让你有足够的开始。

0

其实,因为我要将它发送给Python,所以我不必处理它的C风格。只需使用Py_BuildValue将格式字符s#传递给它,它就知道它是怎么做的。你还需要大小。

return Py_BuildValue("s#", buffer, size); 

您可以使用split('\ x00')将它处理为Python结尾的列表。经过反复试验后我发现了这一点,但我很高兴能够学到一些关于C的知识。