2013-02-26 2 views
0

Как бы вы получите длину (Давать или брать нуль-терминатор) строк буквальной без использования cstdlib что-то вроде этого:Начала длина символа строки буквального

char* foo = "foobar"; 
cout << sizeof(foo) << endl; //Always outputs 4 
cout << sizeof(*foo) << endl; //Always outputs 1 

Я должна перегрузке оператор + в строке, которая может/не содержать строковые литералы в конкатенации. У меня нет возможности выделить память для строки, не зная длины передаваемого символа char * (или char []).

+1

вы пробовали StrLen? – billz

+0

В последний раз 'sizeof' возвращает размер в байтах переменной _type_. Таким образом, 'sizeof (foo)' - это количество байтов 'char *', а 'sizeof (* foo)' - это количество байтов в символе. – ApproachingDarknessFish

ответ

3
#include <cstring> 
std::size_t length = std::strlen(foo); 

Редактировать если вы не можете использовать какие-либо библиотеки, по каким-либо причинам, то раскатывать свой собственный StrLen. Например

// simple recursion 
size_t mystrlen1(const char* str) 
{ 
    return (*str) ? 1 + mystrlen1(++str) : 0; 
} 

или

// iteration 
size_t mystrlen_iteration(const char* str) 
{ 
    size_t counter = 0; 
    for (;*str!=0; ++str) ++counter; 
    return counter; 
} 
+0

Проблема в том, что я не могу использовать ни одну из существующих библиотек для реализации решения –

+2

@TaylorBishop: как получилось? –

+0

@TaylorBishop интересное требование. Ты умеешь пользоваться компьютером? Во всяком случае, я добавил простую функцию для этого. – juanchopanza

3

Foo является указателем на строку. Да, это постоянная строка, но она по-прежнему остается char* в конце дня.

В частности, размер указателя полукокса (foo) составляет 4 байта (на 32-битной системы [а, система с 4 байта указателей]), а также размер полукокса (*foo) составляет 1 байт.

Существует нет (стандартного) способа узнать длину строки, когда вы используете указатель на строковый литерал.

Однако вы можете знать размер, когда вы используете массив:

char foo[] = "some string"; 
size_t len = sizeof(foo) - 1; 
0

Причина вы видите значения вы получаете очевидны:

foo является указателем, а также указатели чаще всего 4 байта в длину. *foo - это символ, и один байт длинный. Если вы не можете использовать встроенный в библиотеке, вы можете свернуть свой собственный:

function myStrlen(char* foo) { 
    int ii=0; 
    while(foo[ii]!='\0') ii++; 
    return ii; 
} 

У меня есть эта забавная мысль, что большинство компиляторов записи размер блока выделяемой памяти, сохраняя значение в (указатель - 1) - это то, как free() знает, сколько памяти выпустить. Я не знаю, является ли это общепринятым, и верно ли это для строковых констант, но я использовал это успешно в прошлом. Да, я хакер ... В вашем случае, я бы внимательно взглянуть на

*(((unsigned long int*)foo) - 1) 

Я не удивлюсь, если вы нашли длину строки там.

+0

Почему бы не использовать петлю? По крайней мере, ваша ошибка будет очевидна. – Slava

+0

Slava - made edit. Ответ начался как 'for'; Я передумал, но не вернулся к инициализации ii. Теперь нормально? – Floris

-1

Использование std::string:

#include <string> 

int main() 
{ 
    std::string str("Hello World"); 

    std::cout << str.length(); // 11 
} 
0

SizeOf (Char *) является размер указателя на строку. вы можете попробовать

char foo[] = "foobar"; 

SizeOf (Foo) = 7 (becuase это "Foobar \ 0" - завершающим нулем строка)

Смежные вопросы