Если мы ищем числа и простые слова, много корректных ответов были даны.
Однако, если мы ищем то, что мы обычно рассматриваем как палиндромы на письменном языке (например, "Собака, паника, в пагоде!"), корректный ответ должен был бы выполнить итерации запуска с обоих концов предложения, неалфавитно-цифровые символы пропуска индивидуально , и возвращение false, если какие-либо несоответствия найдены.
i = 0; j = length-1;
while( true ) {
while( i < j && !is_alphanumeric( str[i] ) ) i++;
while( i < j && !is_alphanumeric( str[j] ) ) j--;
if( i >= j ) return true;
if( tolower(string[i]) != tolower(string[j]) ) return false;
i++; j--;
}
, Конечно, снимая недопустимые символы, инвертируя получившую строку и сравнивая его с исходным также работает. Это сводится, какой язык Вы продолжаете работать.
Безопаснее использовать std :: string
, потому что вам не нужно беспокоиться о выделении / освобождении памяти для строки. Класс C ++ std :: string
, скорее всего, внутренне использует массив char *
. Однако класс будет управлять выделением, перераспределением и освобождением внутреннего массива за вас. Это устраняет все обычные риски, связанные с использованием необработанных указателей, такие как утечки памяти, переполнение буфера и т. Д.
Кроме того, это также невероятно удобно. Вы можете копировать строки, добавлять к строке и т. Д. Без необходимости вручную предоставлять буферное пространство или использовать такие функции, как strcpy / strcat. С std :: string это так же просто, как использование операторов =
или +
.
По сути, это:
std::string s1 = "Hello ";
std::string s2 = s1 + "World";
по сравнению с ...
const char* s1 = "Hello";
char s2[1024]; // How much should I really even allocate here?
strcpy(s2, s1);
strcat(s2, " World ");
Изменить:
В ответ на ваше изменение, касающееся использования char *
в C ++: Многие программисты на C ++ утверждают, что вы не должны никогда использовать char *
, если только вы не работа с некоторыми API / устаревшими функциями, которые требуют этого, и в этом случае вы можете использовать функцию std :: string :: c_str ()
для преобразования std :: string
в ] const char *
.
Тем не менее, я бы сказал, что в C ++ есть несколько законных применений C-массивов. Например, если производительность абсолютно критична, небольшой C-массив в стеке может быть лучшим решением, чем std :: string
. Вы также можете писать программу, в которой вам нужен полный контроль над распределением / освобождением памяти, и в этом случае вы должны использовать char *
. Кроме того, как было указано в разделе комментариев, std :: string
не гарантирует предоставление непрерывного буфера с возможностью записи *, поэтому вы не можете напрямую писать из файла в std :: string
, если вам нужно, чтобы ваша программа была полностью переносимой. . Однако, если вам нужно это сделать, std :: vector
, вероятно, будет предпочтительнее, чем использование необработанного C-массива.
* Хотя в C ++ 11 это изменилось, так что std :: string
предоставляет вам непрерывный буфер
Хорошо, с тех пор, как я впервые ответил, вопрос сильно изменился.
Нативные массивы символов - это кошмар управления памятью и переполнения буфера по сравнению с std :: string. Я всегда предпочитаю использовать std :: string.
Тем не менее, массив char может быть лучшим выбором в некоторых случаях из-за ограничений производительности (хотя std :: string в некоторых случаях может быть быстрее - сначала измерьте!) Или запрет на использование динамической памяти во встроенной среде и т. д.
Строки C char * не могут содержать символы '\ 0'. Строка C ++ может без проблем обрабатывать нулевые символы. Если пользователи вводят строки, содержащие \ 0, а вы используете строки C, ваш код может выйти из строя. С этим также связаны проблемы безопасности.
В общем, std :: string - более чистый и безопасный способ, поскольку он снимает с программиста бремя управления памятью. Основная причина, по которой он может быть быстрее, чем char *, заключается в том, что std :: string хранит длину строки. Таким образом, вам не нужно выполнять итерацию по всему массиву символов, ища завершающий символ NULL каждый раз, когда вы хотите выполнить копирование, добавление и т. Д.
При этом вы все равно найдете много программ на C ++, которые используют смесь std :: string и char *, или даже написали свои собственные строковые классы с нуля. В старых компиляторах std :: string потреблял много памяти и не обязательно был настолько быстрым, насколько мог бы. Со временем ситуация улучшилась, но некоторые высокопроизводительные приложения (например, игры и серверы) могут по-прежнему извлекать выгоду из настраиваемых вручную манипуляций со строками и управления памятью.
Я бы рекомендовал начать с std :: string или, возможно, создать для него оболочку с дополнительными служебными функциями (например, start_with (), split (), format () и т. д.). Если при тестировании кода вы обнаружите, что манипуляции со строками являются узким местом или используют слишком много памяти, вы можете решить, хотите ли вы принять дополнительные риски и тестирование, которые требует настраиваемая строковая библиотека.
СОВЕТ: Один из способов получить вокруг проблем с памятью и по-прежнему использовать std :: string - это использовать встроенную базу данных, такую как SQLite . Это особенно полезно при создании и управлении очень большими списками строк, а производительность выше, чем вы могли ожидать.
Реализации std :: string
скрывают от вас использование памяти. Если вы пишете код, критичный к производительности, или вам действительно нужно беспокоиться о фрагментации памяти, то использование char * может сэкономить вам много головной боли.
Что касается всего остального, то тот факт, что std :: string
скрывает все это от вас, делает его гораздо более удобным.
Строка может быть лучше с точки зрения производительности. И бесчисленное множество других причин - безопасность, управление памятью, удобные строковые функции, делают std :: string бесконечно лучшим выбором.
Редактировать: Чтобы понять, почему строка может быть более эффективной, прочитайте книги Херба Саттера - он обсуждает способ внутренней реализации строка для использования отложенной инициализации в сочетании со ссылками.
Используйте std :: string
из-за его невероятного удобства - автоматической обработки памяти и методов / операторов. С некоторыми строковыми манипуляциями большинство реализаций будут иметь оптимизацию (например, отложенную оценку нескольких последующих манипуляций - экономит копирование памяти).
Если вам нужно полагаться на конкретный макет char в памяти для других оптимизаций, попробуйте std :: vector
вместо этого. Если у вас есть непустой вектор vec
, вы можете получить указатель char *
, используя & vec [0]
(вектор не должен быть пустым).
Короткий ответ, не знаю. Исключение составляют случаи, когда я использую сторонние библиотеки, которым они необходимы. В этих случаях я стараюсь придерживаться std :: string :: c_str ().
За всю свою профессиональную карьеру я имел возможность использовать std :: string только в двух проектах. У всех остальных были свои собственные строковые классы :)
Сказав, что для нового кода я обычно использую std :: string, когда могу, за исключением границ модуля (функции, экспортируемые dll / разделяемыми библиотеками), где я обычно раскрываю интерфейс C и держитесь подальше от типов C ++ и проблем с двоичной несовместимостью между компиляторами и реализациями библиотеки std.
std::string is almost always preferred. Even for speed, it uses small array on the stack before dynamically allocating more for larger strings.
However, char* pointers are still needed in many situations for writing strings/data into a raw buffer (e.g. network I/O), which can't be done with std::string.
Сравните и сопоставьте следующие примеры C и C ++:
strlen(infinitelengthstring)
по сравнению с
string.length()
Единственный раз, когда я недавно использовал стиль C. Строка char в программе на C ++ была в проекте, который должен был использовать две библиотеки C, которые (конечно) использовали исключительно строки C. Преобразование туда и обратно между двумя типами строк сделало код действительно запутанным.
Мне также пришлось проделать некоторые манипуляции со строками, которые на самом деле довольно неудобны при использовании std :: string, но я бы не подумал, что веская причина использовать строки C при отсутствии вышеуказанного ограничения.