Есть непонятная проблема по передача массива строк в функцию на языке Си.
Вызывающий код:
char str[33][40];
CreateCSV((char**)str);
Функция:
void CreateCSV(char** str)
{
char strData[]= {'"','Д','А','Т','А','"',';','\0'};
if(str[0x00] != NULL)
strcpy (str[0x00], strData);
else
Console("СтрокаЗаголовка[0x00] == NULL");
}
Почему у меня str[0x00] == NULL? Ведь я явно создал 33 строки и зарезервировал по 40 символов под каждую.
Ответ
Если в кратце - используйте одинаковый прототип для объявления переменной и для параметров в функции и для strData. Это не самый красивый вариант, но он сработает
Вот как будет выглядеть Ваша программа:
#include
void CreateCSV(char str[33][40])
{
char strData[33][40]= {"\"","D","A","T","A","\"",";","\0"};
if(str != NULL)
memcpy (str, strData, sizeof(strData));
else
printf ("error
");
}
int main (void)
{
char str[33][40] = {'\0'};
int i=0;
CreateCSV(str);
for (i=0; i<33; i++)
printf ("%s
", str[i]);
return 0;
}
Обратите внимание на сл. нюансы - я использовал функцию копирования памяти а не строк "memcpy". И проверял на NULL имя str без указания сдвига. Это связано с тем, как язык Си представляет и обрабатывает многомерные массивы. Также при заполнении strData использовал двойные кавычки, иначе компилятор соединял буквы в одну строку, а не трактовал их как ряд строк с 1 буквой в каждой строчке.
Если в деталях и особенностях физики языка Си:
Массивы объявленные как
char str[33][40];
и как
char str**;
это совершенно разные вещи.
char str[33][40]; - трактуеться как длинный одномерный массив глде все строки слеплены в одну одна-за-другой. Что-то ввиде
"строка 1 \0\0\0\0\0...\0 строка 2 \0\0\0\0\0...\0 ....... строка 33 \0\0\0\0\0...\0 " и размер такого массива будет равер 33*40*sizeof(char)=33*40*1=1320.
При объявлении такого массива, компилятор выделяет 1320 байт в стеке, и трактует переменную 'str' как указатель на эту длинную строку.
char str;** - это массив указателей на одномерные строки. Воспринимаеться компилятором как {*pointer_to_str1, *pointer_to_str2, ... *pointer_to_str33}, при этом сами строки лежат вне этого массива. Размер такого массива будет равен 33*sizeof(char*) = 33*4 = 132/
При объявлении такого массива, компилятор проводит несколько операций. Сначала компилятор выделит 33 независимых строки в стеке , затем создаст массив указателей и заполняет его указателями на эти 33 независимые строки.
Вот как будет выглядеть Ваша программа если strData объявить как char**:
#include
void CreateCSV(char str[33][40])
{
char *strData[33] = {"\"","D","A","T","A","\"",";","\0"};
if(str != NULL)
{
int i=0;
for (i=0; i<33; i++)
if (strData[i] != NULL)
strncpy (str[i], strData[i], 40);
}
else
printf ("error
");
}
int main (void)
{
char str[33][40] = {'\0'};
int i=0;
CreateCSV(str);
for (i=0; i<33; i++)
printf ("%s
", str[i]);
return 0;
}
PS
оба примера проверены на gcc
Комментариев нет:
Отправить комментарий