C Noob: Определить размер массива char при копировании в него содержимого char * - PullRequest
0 голосов
/ 13 апреля 2011

У меня есть основной вопрос на языке C.

Мне нужно напечатать содержимое указателя на символ.Содержимое является двоичным, и поэтому я использую шестнадцатеричный формат для просмотра содержимого.

Будет ли работать определение нуля?

unsigned char *input = "������";
printf("input =");
int count = 0;
while(*input != '\0'){
    printf("%02x", *input);
            input++;
}
printf("\n");

Что теперь произойдет, если мне придется скопировать указатель на символмассив?Как я могу назначить размер массива символов?Я понимаю, что sizeof возвращает только размер типа данных, на который указывает char.Но есть ли способ?

unsigned char copyInput[size??];
strcpy(copyInput, input);
for (i=0, i <size?, i++)
{
printf("copyInput[%d]= %02x", i, copyInput[i]);
}

Заранее спасибо!

Ответы [ 3 ]

1 голос
/ 13 апреля 2011

1) Если в C вообще есть строки, они определяются как «произвольная непрерывная последовательность ненулевых байтов, оканчивающаяся нулевым байтом». Следовательно, если ваши двоичные данные гарантированно никогда не будут содержать байтов , значение которых равно нулю, вы можете безопасно обрабатывать их как строку C (используйте с ней функции str* и т. Д.). Но если ваши двоичные данные могут иметь нулевые байты где-то посередине, вам нужно отслеживать длину отдельно и работать с ней вместо функций mem*.

2) Вы используете strlen, чтобы найти длину строки (без завершающего нулевого байта). Однако в стандартном C89 вы не можете использовать результат strlen, чтобы установить размер переменной char[], потому что размер должен быть известен во время компиляции. Если вы используете расширения C99 или GNU, вы можете определить размер массива во время выполнения:

size_t n = strlen(s1);
char s2[n+1];
memcpy(s2, s1, n);

n+1 необходим, иначе у вас не будет места для завершающего NUL. Если вы не можете использовать ни C99, ни расширения GNU, единственный вариант - выделить место в куче:

size_t n = strlen(s1);
char *s2 = malloc(n+1);
memcpy(s2, s1, n);

или, с общим расширением библиотеки, просто

char *s2 = strdup(s1);

В любом случае, не забудьте free(s2) позже. Кстати, это тот случай, когда было бы безопасно использовать strcpy, потому что по построению вы знаете, что буфер назначения достаточно велик. Я использовал memcpy, потому что он может быть немного более эффективным и означает, что читатели не увидят "strcpy" и не начнут беспокоиться.

0 голосов
/ 13 апреля 2011

У вас будут проблемы, если любой из входных байтов равен 0. В этом случае цикл остановится на этом символе. В противном случае вы можете рассматривать его как строку.

Обрабатывая его как строку, вы можете использовать strlen(), чтобы получить размер ввода, а затем динамически выделять память для вашей копии. Копия может быть сделана с strcpy, как вы сделали, но безопаснее использовать strncpy.

char *input = "input binary array";
int count = strlen(input)+1; // plus '\0'
char *copy = (char *) malloc(count*sizeof(char));
strncpy(copy, input, count+1);
0 голосов
/ 13 апреля 2011

Если это набор char s, оканчивающихся на 0, просто используйте strlen(), так как это определение C для строки. Неважно, что некоторые (или большинство) символов могут быть непечатными, если 0 - терминатор.

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