Функция char* strrchr(const char *str, int ch)
возвращает указатель (char*
) в str
(const char *
) где последнее вхождение ch
расположен.
Таким образом, мы можем написать следующий код без приведения:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *ptr = strrchr (CONSTSTR, '/');
*ptr++ = 'B';
*ptr++ = 'A';
*ptr++ = 'D';
}
В чем преимущество возвращения char*
вместо const char*
?
РЕДАКТИРОВАТЬ:
Как Шафик Ягмур указал, что есть очень хорошие ответы на Как работает реализация strchr?
Поскольку мой код на C ++, я буду использовать <cstring>
вместо <string.h>
, Спасибо за ваши ответы 😉
Тем не менее Ответ Майка Сеймура лучше всего подходит вопрос. Я даже добавил более подробный ответ ниже четко сказать, как strrchr()
является функцией C (перегрузка не разрешена), объявление соответствует Const а также неконстантная строки. Так как strrchr()
можно вызвать с неконстантная строка, возвращаемая строка также должна быть неконстантная.
В Си функция должна быть такой, или заставлять пользователя использовать хитрые приведения во многих ситуациях:
const
указатель, вы не можете найти const
строка;const
указатель, вы не можете использовать его для измененияconst
строка.В C ++ вы должны включить <cstring>
а не устаревший C-only заголовок. Это даст вам две const-правильные перегрузки, которые не могут быть выполнены в C:
const char* strchr(const char* s, int c);
char* strchr( char* s, int c);
Вы смотрите на устаревшую функцию из стандартной библиотеки C (<string.h>
). Библиотека C ++ (<cstring>
) вводит подходящее const
и неconst
перегрузки, поэтому вы должны использовать это везде, где это возможно.
const char *str
средства strrchr
гарантирует не изменять str
,
возврате const char *
средства strrchr
запрещает вам изменять возвращаемое значение.
strrchr()
от <string.h>
является функцией C. Поскольку C не разрешает перегрузку функций, strrchr()
был разработан, чтобы соответствовать как Const а также неконстантная строки.
char* strrchr( const char *str, int ch );
strrchr()
может быть вызван с неконстантная строка, и поэтому возвращаемая строка также должна быть неконстантная как объяснено в следующих примерах.
Const контекст без ошибки компиляции:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"}
неконстантная контекст без ошибки компиляции:
#include <string.h>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"}
Неправильное использование также без ошибки компиляции:
#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = strrchr (CONSTSTR, '/');
*nonconst++ = 'B';
*nonconst++ = 'A'; // drawback of the unique declaration:
*nonconst++ = 'D'; // no compilation error
}
const char* strrchr( const char* str, int ch ); //1st
char* strrchr( char* str, int ch ); //2nd
Const контекст использует 1-й:
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = std::strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"}
неконстантная контекст использует 2-й:
#include <cstring>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = std::strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"}
Неправильное использование должно привести к ошибке компиляции:
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = std::strrchr (CONSTSTR, '/');
// Visual C++ v10 (2010)
// error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}
Но этот последний пример не приводит к ошибке компиляции, используя g++ -Wall file.cpp
, Протестировано с использованием версий GCC 4.1.2 (RedHat) а также 4.7.2 (MinGW).
Почему вы запрещаете коду изменять возвращаемую переменную? Имейте в виду, что const char *
не является char * const
, вам будет разрешено изменить символ в любом случае, но вы не сможете контролировать само возвращаемое значение, что не имеет особого смысла, так как вы можете изменить его и отредактировать базовую строку в другой позиции для твоя цель.