Проблемы с пониманием того, как обрабатывать строку C - PullRequest
0 голосов
/ 28 июня 2011

Я пытаюсь использовать функцию Mac OS X listxattr C и превратить ее во что-то полезное в Python.Страница man сообщает мне, что функция возвращает строковый буфер, который представляет собой «простые строки UTF-8 с нулевым символом в конце и возвращаются в произвольном порядке. Никаких дополнительных заполнений между именами в буфере не предусмотрено». *

В моем C-файле он настроен правильно, кажется (я надеюсь):

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

Но когда я его распечатал, я получил ТОЛЬКО атрибут FIRST, который был длиной в два символа, дажехотя его размер равен 25. Итак, я вручную установил buffer [3] = 'z' и low, и вот, когда я снова печатаю буфер, я получаю первые ДВА атрибута.

Мне кажется, я понимаю, что происходит.Буфер представляет собой последовательность строк, оканчивающихся NULL, и останавливает печать, как только видит символ NULL.Но тогда как мне распаковать всю последовательность во ВСЕ атрибуты?

Я новичок в C и использую его, чтобы выяснить механизм расширения Python с помощью C, и столкнулся с этим doozy.

Ответы [ 4 ]

3 голосов
/ 28 июня 2011
  1. char *p = buffer;
  2. получить длину с strlen(p).Если длина равна 0, остановите.
  3. обработайте первый фрагмент.
  4. p = p + length + 1;
  5. обратно к шагу 2.
1 голос
/ 28 июня 2011

Значит, вы уже догадались.

Функция listxattr возвращает набор строк с нулевым символом в конце, упакованных рядом друг с другом. Поскольку строки (и массивы) в 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 голосов
/ 29 июня 2011

На самом деле, поскольку я собираюсь отправить его в Python, мне не нужно обрабатывать его в стиле C в конце концов. Просто используйте Py_BuildValue, передав ему символ формата s #, который знает, что с ним делать. Вам также понадобится размер.

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

Вы можете обработать его в список на конце Python, используя split ('\ x00'). Я нашел это после проб и ошибок, но я рад, что узнал кое-что о C.

0 голосов
/ 28 июня 2011

Похоже, listxattr возвращает размер заполненного буфера, так что вы можете использовать это, чтобы помочь вам.Вот идея:

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

Теперь, вместо разделения нулевыми символами, атрибуты разделяются запятыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...