как использовать char * как char [] - PullRequest
2 голосов
/ 17 апреля 2010

У меня есть такая структура

typedef struct bookStruct
{
   char title[80];
   char author[80];
} BookType;

И у меня есть две строки, как это

char *title = "A Book on C";
char *author = "A. Kelly";

Теперь я не могу создать BookType, как это

BookType book = {title, author};

Может кто-нибудь сказать мне, что не так? Как я могу это сделать?

Ответы [ 5 ]

6 голосов
/ 17 апреля 2010

Есть два возможных решения вашей проблемы. Первый из которых использует строковые литералы в месте строительства:

BookType book = { "A book on C", "A. Kelly" };

В этом случае компилятор скопирует литералы в соответствующие переменные. Если вы не можете использовать литералы при инициализации, вы должны скопировать элементы самостоятельно:

BookType book = { 0 }; // 0 initalize
strncpy( book.title, title, sizeof(book.title)-1 );   
strncpy( book.author, author, sizeof(book.author)-1 );
3 голосов
/ 17 апреля 2010
void InitBookStruct(BookType *book, const char *title, const char *author){
   size_t title_length = sizeof book->title;
   size_t author_length = sizeof book->author;

   strncpy(book->title, title, title_length - 1); //-1, make way for null byte
   strncpy(book->author, author, author_length - 1);

   book->title[title_length - 1] = 0;
   book->author[author_length - 1] = 0;
}

Много способов сделать, выше один из них.


Из справочных страниц,

char * strncpy (char * dest, const char * src, size_t n);

Если длина src меньше n, strncpy () дополняет оставшуюся часть dest с нулевыми байтами.

Итак, достаточно указать (на единицу меньше) размер dest.

2 голосов
/ 17 апреля 2010

Если вы измените свою структуру на это, она должна работать

typedef struct bookStruct
{
   char* title;
   char* author;
} BookType;
2 голосов
/ 17 апреля 2010

Вместо этого вы должны использовать strcpy (если вы знаете длину ввода) или безопасную функцию.

Многие другие ответы совершили ту же ошибку, оставив незавершенные строки основным источником уязвимостей в безопасности.

Правильный способ - использовать безопасную функцию копирования строк, например StringCbCopy, или свернуть свою собственную (хотя и не настолько надежную):

// Copy at most n-1 characters to dst, truncating if strlen(src) > n-1
// and guaranteeing NUL-termination.
void safe_strcpy(char *dst, const char *src, size_t n) {
  strncpy(dst, src, n-1);
  dst[n-1] = 0;  // Guarantee NUL-termination.
}

Тогда вы можете использовать его следующим образом

void f(const char *title, const char *author) {
  BookType book;
  safe_strcpy(book.title, title, sizeof book.title);
  safe_strcpy(book.author, author, sizeof book.author);
}
1 голос
/ 17 апреля 2010

Насколько я знаю, в Си нет способа сделать это. Лучше всего использовать макрос:

#define TITLE "A Book On C"
#define AUTHOR "A. Kelley"

BookType book {TITLE, AUTHOR};

хотя это, конечно, не имеет точно такой же эффект.

...