Необходимо заменить использование strcpy_s в коде C, используемом в проекте iPhone - PullRequest
0 голосов
/ 17 февраля 2011

У меня есть C SDK, который мне нужно использовать в проекте iPhone, и пример кода был написан для использования с Visual Studio.Он включает в себя использование strcpy_s, который является строковой функцией только для Microsoft.

file_header.header_size = FIT_FILE_HDR_SIZE;
strcpy_s((FIT_UINT8 *)&file_header.data_type, sizeof(".FIT"), ".FIT");  << problem!

Я пытался перейти на strcpy и strncpy, например,

strncpy((FIT_UINT8 *)&file_header.data_type, ".FIT", sizeof(".FIT"));

Но я получаю это предупреждение:

предупреждение: цели указателя при передаче аргумента 1 в ' встроенный _strncpy_chk' отличаются по знаку

предупреждение: цели указателя при передаче аргумента 1 из __inline_strncpy_chk отличаются по знаку

предупреждение: вызов встроенный _strncpy_chk всегда будет переполнять целевой буфер

Структура file_header выглядит так:

typedef struct
{
   FIT_UINT8 header_size; // FIT_FILE_HDR_SIZE (size of this structure)
   FIT_UINT8 protocol_version; // FIT_PROTOCOL_VERSION
   FIT_UINT16 profile_version; // FIT_PROFILE_VERSION
   FIT_UINT32 data_size; // Does not include file header or crc.  Little endian format.
   FIT_UINT8 data_type[4]; // ".FIT"
} FIT_FILE_HDR;

FIT_UINT8 is typedef Беззнаковый символ.

Итак, мы можем видеть, что ему дано значение 4 в typedef, и strcpy_s берет data_type по ссылке и копирует в него ".FIT".Где я не так с strncpy?Если вы еще не догадались, я не большой программист на C:)

Edit: это не дает мне ошибки, но это правильно?

strncpy((void *)&file_header.data_type, ".FIT", sizeof(file_header.data_type));

Ответы [ 2 ]

1 голос
/ 17 февраля 2011

С любыми операциями "безопасной строки" размер почти всегда должен быть размером буфера destination ;если вы используете размер исходной строки, вы можете также вызвать memcpy.

Если вы хотите соответствие C99:

strncpy(file_header.data_type, ".FIT", sizeof file_header.data_type);

Однако, strlcpy (доступен BSDismв iOS) предпочитают многие, потому что это гарантирует, что пункт назначения будет оканчиваться нулем:

strlcpy(file_header.data_type, ".FIT", sizeof file_header.data_type);

Обратите внимание, однако, что строка «.FIT» с нулевым окончанием фактически не помещается в выделенноепробел, так как для этого требуется 5 символов (1 для конечного нуля).Если вы используете strlcpy, вы увидите, что результирующая строка - просто ".FI", потому что strlcpy гарантирует нулевое завершение и при необходимости обрезает вашу строку.

Если вам требуется нулевое завершение,вы, вероятно, хотите увеличить размер массива data_type до 5. Как правильно указывает caf , это похоже на заголовок файла, и в этом случае nul-terminating, вероятно, не требуется;в этом случае strncpy является предпочтительным;Я мог бы даже использовать memcpy и не давать будущему разработчику идеи, что поле является строкой.

1 голос
/ 17 февраля 2011

Не использовать

sizeof(".FIT")

использовать

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