Как скопировать несколько символов из char [] в char * в C? - PullRequest
3 голосов
/ 07 января 2009

Yo!

Я пытаюсь скопировать несколько символов из символа [] в символ *. Я просто хочу символы из индекса 6 в (длина сообщения - 9).

Может быть, пример кода объяснит мою проблему подробнее:

char buffer[512] = "GET /testfile.htm HTTP/1.0";
char* filename; // I want *filename to hold only "/testfile.htm"

msgLen = recv(connecting_socket, buffer, 512, 0);
strncpy(filename, buffer+5, msgLen-9);

Любой ответ очень поможет!

Ответы [ 5 ]

10 голосов
/ 07 января 2009

Полагаю, вы имели в виду ...

strncpy(filename, buffer+5, msgLen-9);

Проблема в том, что вы не выделили память для хранения копируемых символов. «filename» - это указатель, но он ни на что не указывает.

Либо просто объявите

char filename[512];

или malloc немного памяти для нового имени (и не забудьте освободить () его ...)

Есть несколько проблем с использованием strncpy () в вашем коде.

  • буфер + 5 указывает на шестой символ в строке («Т»), в то время как вы сказали, что хотите обратную косую черту.
  • Последний параметр - это максимальное количество байтов для копирования, поэтому, вероятно, должно быть msglen-13.
  • strncpy () не завершит копирование строки нулем, поэтому вам нужно сделать это вручную.
  • Кроме того, с точки зрения читабельности, Я предпочитаю

    strncpy (имя файла и буфер [4], msgLen- (9 + 4));

& buffer [5] - это адрес символа на пятой позиции в массиве. Хотя это личное дело.

Также стоит отметить, что результатом "recv" может быть один байт или 512 байт. Это не будет просто читать строку. Вы должны действительно зацикливаться на вызове recv, пока не получите полную строку для работы.

5 голосов
/ 07 января 2009

Прежде всего вы должны выделить буфер для filename. Следующая проблема - ваше смещение.

char buffer[512] = "GET /testfile.htm HTTP/1.0";
char filename[512]; // I want *filename to hold only "/testfile.htm"

msgLen = recv(connecting_socket, buffer, 512, 0);
strncpy(filename, buffer+4, msgLen-4-9); 
//the first parameter should be buffer+4, not 5. Indexes are zero based.
//the second parameter is count, not the end pointer. You should subtract
//the first 4 chars too.

Также вы должны убедиться, что вы добавили ноль в конце строки, так как strncpy этого не делает.

filename[msgLen-4-9] = 0;

Вы также можете использовать memcpy вместо strncpy, так как вы хотите просто скопировать несколько байтов:

memcpy(filename, buffer+4, msgLen-4-9);
fileName[msgLen-4-9] = 0;

В любом случае, убедитесь, что вы подтвердили свой ввод. Возможно, вы получили неверный ввод из сокета.

1 голос
/ 07 января 2009

Вы не выделили места для имени файла

Либо замените объявление имени файла чем-то вроде

char filename[512]

или (возможно, лучше) оставить достаточно места для имени файла

filename = (char *)malloc(msgLen - 9  - 6 + 1 ); /* + 1 for the terminating null */
1 голос
/ 07 января 2009

В вашем примере кода есть строка:

char* filename;

Это неинициализированный указатель - он никуда не указывает и не поддерживается никаким хранилищем. Вы должны выделить немного памяти для этого, например, используя malloc() (и не забудьте free(), когда закончите), или, в этом случае, вы можете просто объявить его как массив символов, например

char filename[SOME_BUFFER_SIZE];

Объявление массива в стеке имеет то преимущество, что вам не нужно явно освобождать его, когда вы закончите с ним.

По сути, массивы в C - это просто синтаксический сахар, который скрывает указатели, поэтому вы можете (обычно) трактовать char[] как char*.

0 голосов
/ 07 января 2009

Вы еще не распределили пространство памяти для имени файла. Это указатель ... но до инициализации он указывает на некоторую случайную область памяти.

Вам необходимо выделить память для имени файла. Как сказал Родди, вы можете объявить имя файла равным 512 байтам. Или вы могли бы:

filename = (char*)malloc(512*sizeof(char)); 

(примечание: sizeof (char) строго не требуется, но я думаю, что помогает уточнить, что именно выделяется).

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

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