2010-02-23 4 views
2

Я новичок в C89 и не понимаю, как работают строки. Я разрабатываю на Windows, 7.C: Trouble with Strings

Вот что я пытаюсь сделать, в Java:

Вот моя неуклюжая попытка сделать это в C89:

// well formed url ensured 
void get(char *url) { 
    int hostnameLength; 
    char *firstSlash; 
    char *hostname; 

    firstSlash = strchr(url + 7, '/'); 
    hostnameLength = strlen(url) - strlen(firstSlash) - 7; 
    hostname = malloc(sizeof(*hostname) * (hostnameLength + 1)); 
    strncpy(hostname, url + 7, hostnameLength); 
    hostname[hostnameLength] = 0; // null terminate 
} 

Update чтобы отразить ответы

для hostnameLength 14, hostname является malloc() «d 31 символа. Почему это происходит?

+0

@ Rosarch, этот код не должен выделять 31, он должен выделить 15 ... вы уверены, что код, который вы показываете, - это то, что вы используете? Как вы проверяете выделенный размер? Я просто проверил и проверил, что у вас здесь, и я получаю ожидаемый результат. –

ответ

2

// now what? является strncpy():

hostname = malloc(hostnameLength + 1); 
strncpy(hostname, url + 7, hostnameLength); 
hostname[hostnameLength] = '\0'; // don't forget to null terminate! 
+0

Я бы использовал 'memcpy' лично. Труднее испортить и ничего неожиданного. Но код OP нуждается в проверке возвращаемого значения 'strchr', о котором никто еще не упомянул. –

+0

@Chris, это зависит от того, гарантировал ли он корректный URL-адрес в другом месте кода. –

+0

Я хочу использовать ваш 'malloc()' или 'malloc()', описанный в ответе Рида? Разве ты не слишком маленький? –

0

После этого, вам нужно сделать:

hostname = malloc(sizeof(char) * (hostnameLength+1)); 
strncpy(hostname, url + 7, hostnameLength); 
hostname[hostnameLength] = 0; 

См strncpy подробную информацию о копировании. Это требует, чтобы указатель назначения был назначен заранее (следовательно, malloc), и будет копировать только столько символов ...

+0

Можете ли вы объяснить значение 'hostname [hostnameLength] = 0;'? –

+0

Да - вам нужно обнулить имя хоста - strncpy скопирует символы «hostnameLength», но не добавит символ нулевого окончания. Добавление 0 (или '\ 0') приведет к правильному завершению строки. –

+0

Строки C требуют нулевого байта в конце, и это охватывает случай, когда копируемая строка не вписывается в буфер, поэтому strncpy не поместил нуль. Если вы этого не сделаете, некоторые строковые операции позже будут запущены в случайную память, и программа может делать всевозможные странные вещи (хотя, по общему признанию, она, вероятно, просто сбой с ошибкой сегментации). –