Невозможно преобразовать const char * в char * - PullRequest
4 голосов
/ 09 марта 2010

Visual Studio c ++ 2005

Я получаю сообщение об ошибке в последней строке этого кода.

int Utils::GetLengthDiff ( const char * input, int & num_subst ) 
{
    int num_wide = 0, diff = 0 ; 
    const char * start_ptr = input ; 

    num_subst = 0 ; 
    while ( ( start_ptr = strstr ( start_ptr, enc_start ) ) != NULL ) 
    {
        char * end_ptr = strstr ( start_ptr, enc_end ); // Error

Так что я изменил строку на это, и она работала нормально

const char * end_ptr = strstr ( start_ptr, enc_end ); 

Так зачем мне также объявлять end_ptr как const?

Большое спасибо,

Ответы [ 3 ]

13 голосов
/ 09 марта 2010

C ++ имеет две перегруженные версии этой функции. http://www.cplusplus.com/reference/clibrary/cstring/strstr/

const char * strstr ( const char * str1, const char * str2 );
      char * strstr (       char * str1, const char * str2 );

Поскольку ваш start_ptr равен const char *, компилятор C ++ разрешает вызывать версию, которая принимает const char * в качестве первого параметра, эта версия также возвращает a const char *, поэтому вы должны измените ваше возвращаемое значение, чтобы соответствовать.

2 голосов
/ 09 марта 2010

Так зачем мне также объявлять end_ptr как const?

По той же причине, по которой start_ptr должно быть const char*: strstr возвращает тип const char* (= char const*), потому что он ищет внутри постоянной строки (параметр, который вы передаете в strstr также const char*). В частности, это , а не указатель, который является const, это память, на которую он указывает. Думайте об этом как о указателе на неизменяемую (т.е. постоянную) строку. Вы можете изменить то, на что оно указывает, но не отдельные символы в строке.

Это отличается от неизменяемого указателя, который указывает на изменяемую строку, то есть строку, в которой вы можете изменять отдельные символы.

1 голос
/ 09 марта 2010

Предположим, что возвращаемое значение из strstr было char*, с первым параметром const char*, как в C. Тогда вы могли бы написать:

const char *s = "hello, world";
strstr(s, "hello")[0] = 'j';

Код компилируется и запускается (с неопределенным поведением), но это ошибка, которую const специально разработал, чтобы избежать. Вы конвертировали const char* в char* без приведения.

C на самом деле ничего не может с этим поделать: если strstr вернул const char*, то вам пришлось бы явно привести к неконстантному типу в случае, когда ввод неконстантный, и вы хотите изменить строку. Поскольку C ++ имеет перегрузку функций, он может (и делает) заглушить лазейку и заставить оба случая работать правильно. Следовательно, в C ++ вышеприведенный код не компилируется, как и ваш пример кода.

...