#c
#c
Вопрос:
Мне нужно создать функцию reverse (), которая меняет количество символов в str на обратное. Вот это прототип:
void reverse(char **str, int count = ???);
Мне нужно установить значение по умолчанию для count, чтобы строка была полностью перевернута.
Я попытался назначить это следующим образом:
void reverse(char **str, int count = strlen(*str))
Но компилятор выдал следующую ошибку:
error: local variable ‘str’ may not appear in this context
void reverse(char **str, int count = (int) strlen(*str)) {
Вот мой код:
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char **str, int count = (int) strlen(*str)) {
int i;
char temp;
for (i = 0; i < count / 2; i ) {
temp = (*str)[i];
(*str)[i] = (*str)[count - i];
(*str)[count - i] = temp;
}
}
int main() {
char buf[100];
cout << "Enter your string:n" << endl;
cin >> buf;
char *str;
str = new char(strlen(buf) 1);
strcpy(str, buf);
reverse(amp;str);
cout << "Reversed string:n" << str << endl;
return 0;
}
Как я могу с этим справиться?
Комментарии:
1.
void reverse(char **str, int count = strlen(*str))
— Честно говоря, это одно из самых неортодоксальных объявлений функции для изменения строки, которое я когда-либо видел. Это имеет больше смысла:void reverse(char *str, int count = -1)
а -1 указывает на обратное изменение всей строки. В чем причина того, чтоchar **
когдаchar *
этого достаточно?
Ответ №1:
Исходя из того, что сказал Пол Маккензи. Вам не нужен указатель на указатель, чтобы поменять местами строку. Указатель на указатель потребуется только в том случае, если вы пытаетесь изменить указатель. Но вы этого не делаете, вы пытаетесь изменить то, на что указывается, поэтому требуется простой указатель.
И значениями по умолчанию для параметров должны быть константы, а не вызовы функций.
И вы отклоняетесь на единицу в своем алгоритме, str[count - i]
когда i
равно нулю, вы индексируете str[count]
то, что находится за концом строки.
Попробуйте это
void reverse(char *str, int count = -1)
{
if (count < 0)
count = strlen(str);
for (int i = 0; i < count / 2; i )
{
char temp = str[i];
str[i] = str[count - i - 1];
str[count - i - 1] = temp;
}
}
Ответ №2:
Поскольку вы используете C , если вы используете std::string
вместо char *
обратного значения по умолчанию для всей строки (или первых count
символов, если они указаны), становится так просто, как:
std::string reverse (const std::stringamp; s, size_t count = 0)
{
if (count > s.length())
count = 0;
if (count)
count = s.length() - count;
return std::string (s.rbegin() count, s.rend());
}
Коротким примером может быть:
#include <iostream>
#include <string>
std::string reverse (const std::stringamp; s, size_t count = 0)
{
if (count > s.length())
count = 0;
if (count)
count = s.length() - count;
return std::string (s.rbegin() count, s.rend());
}
int main (void)
{
std::string s("123456789");
std::string r = reverse(s);
std::cout << "sn" << s << "nnreverse(s)n" << r
<< "nnreverse(s, 2)n";
r = reverse(s, 2);
std::cout << r << "nnreverse(s, s.length() - 1)n";
r = reverse(s, s.length() - 1);
std::cout << r << 'n';
}
(смотрите: std::basic_string::rend, std::basic_string::crend и std::basic_string::rbegin, std ::basic_string::crbegin)
Пример использования / вывода
$ ./bin/strrev
s
123456789
reverse(s)
987654321
reverse(s, 2)
21
reverse(s, s.length() - 1)
87654321
Всегда печатайте символы полной длины
Если вы хотите поменять местами только count
символы, но напечатать полную длину результирующей строки только с теми, которые перевернуты, вы можете сделать что-то похожее на:
std::string reverse (const std::stringamp; s, size_t count = 0)
{
if (count > s.length())
count = 0;
if (count) {
count = s.length() - count;
return std::string (s.rbegin() count, s.rend()) suffix;
}
return std::string (s.rbegin() count, s.rend());
}
Все символы
$ ./bin/strrev
s
123456789
reverse(s)
987654321
reverse(s, 2)
213456789
reverse(s, s.length() - 1)
876543219
Библиотека контейнеров предоставляет ряд преимуществ по сравнению с использованием основных типов.
Ответ №3:
итак, это должно работать таким образом:
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char *str) {
int count = (int)strlen(str);
char temp;
for (int i = 0; i < count / 2; i ) {
temp = str[i];
str[i] = str[count - i-1];
str[count - i-1] = temp;
}
}
int main() {
char buf[100];
cout << "Enter your string:n" << endl;
cin >> buf;
char *str;
str = new char(strlen(buf) 1);
strcpy(str, buf);
reverse(str);
cout << "Reversed string:n" << str << endl;
return 0;
}
Вам просто нужно передать функции строку, а не указатель на строку. Символ ** — это слишком много, вы можете изменить символы, потому что у вас уже есть указатель на символ *. Если вы не задаете длину строки функции, вы не сможете выполнять какие-либо исправления. Я вызываю функцию strlen в обратном порядке, это увеличивает временную сложность на один O (n), что не так уж проблематично, потому что ваша функция уже выполняется в O (n). Если вам интересно, почему я использовал str[count -i-1], то, поскольку CString завершаются 0, что означает, что строка «hallo» на самом деле является «»hallo 0» с литералом -1, убедитесь, что не меняете это ‘ 0’, которое необходимо для завершения CString.