NSData *torrent = [BEncoding objectFromEncodedData:rawdata];
Когда я NSLog торрент я получаю следующее:
{
⋮
}
Тогда это будет NSDictionary, а не NSData.
unsigned char aBuffer[[name length]];
[name getBytes:aBuffer length:[name length]];
NSLog(@"File name: %s", aBuffer);
.., который извлекает данные, но, кажется, после них появляется дополнительный мусор в Юникоде:
File name: ubuntu-8.10-desktop-i386.iso)
Нет, он получил имя файла просто отлично; Вы просто напечатали это неправильно. %s
принимает строку C, которая заканчивается нулем; байты объекта данных не заканчиваются нулем (они являются просто байтами, не обязательно символами в любой кодировке, а 0 - который является нулем как символ - является абсолютно допустимым байтом). Вам нужно было бы выделить еще один символ и установить последний в массиве на 0:
size_t length = [name length] + 1;
unsigned char aBuffer[length];
[name getBytes:aBuffer length:length];
aBuffer[length - 1] = 0;
NSLog(@"File name: %s", aBuffer);
Но завершение нулями данных в объекте NSData неверно (за исключением случаев, когда действительно нужна строка C). Я сейчас доберусь до нужного пути.
Я также пытался […] ..
NSString *secondtry = [NSString stringWithCharacters:[name bytes] length:[name length] / sizeof(unichar)];
.. но это, кажется, возвращает случайные китайские символы:
扵湵畴㠭ㄮⴰ敤歳潴⵰㍩㘸椮潳
Это потому, что ваши байты имеют формат UTF-8, который кодирует один символ (обычно) в один байт.
unichar
есть, а stringWithCharacters:length:
принимает UTF-16. В этой кодировке один символ (обычно) составляет два байта. (Отсюда деление на sizeof(unichar)
: оно делит количество байтов на 2, чтобы получить количество символов.)
Итак, вы сказали «вот некоторые данные UTF-16», и они пошли и сделали символы из каждых двух байтов; каждая пара байтов должна была состоять из двух символов, а не одного, поэтому вы получили мусор (который оказался в основном идеографами CJK).
Вы ответили на свой вопрос довольно хорошо, за исключением того, что stringWithUTF8String:
проще, чем stringWithCString:encoding:
для строк в кодировке UTF-8.
Однако, когда у вас есть длина (как у вас, когда у вас есть NSData), еще проще - и правильнее - использовать initWithBytes:length:encoding:
. Это проще, потому что не требует данных с нулевым символом в конце; он просто использует длину, которая у вас уже есть. (Не забудьте выпустить или автоматически выпустить его.)