Обратный String С++ с использованием массива char
Я написал простую программу на С++ для изменения строки. Я храню строку в массиве символов. Чтобы изменить строку, я использую тот же массив символов и временную переменную, чтобы поменять символы массива.
#include<iostream>
#include<string>
using namespace std;
void reverseChar(char* str);
char str[50],rstr[50];
int i,n;
int main()
{
cout<<"Please Enter the String: ";
cin.getline(str,50);
reverseChar(str);
cout<<str;
return 0;
}
void reverseChar(char* str)
{
for(i=0;i<sizeof(str)/2;i++)
{
char temp=str[i];
str[i]=str[sizeof(str)-i-1];
str[sizeof(str)-i-1]=temp;
}
}
Теперь этот метод не работает, и я получаю NULL String в результате выполнения программы.
Итак, я хочу знать, почему я не могу приравнивать массив символов, почему эта программа не работает. И каково решение или трюк, которые я могу использовать для работы одной и той же программы?
Ответы
Ответ 1
sizeof(str)
не выполняет то, что вы ожидаете.
Учитывая char *str
, sizeof(str)
не даст вам длину этой строки. Вместо этого он даст вам количество байтов, которые занимает указатель. Вероятно, вы ищете strlen()
.
Если бы мы зафиксировали это, мы бы имели:
for(i=0;i<strlen(str)/2;i++)
{
char temp=str[i];
str[i]=str[strlen(str)-i-1];
str[strlen(str)-i-1]=temp;
}
В С++, если вы хотите поменять содержимое двух переменных, используйте std::swap
вместо временной переменной.
Итак, вместо:
char temp=str[i];
str[i]=str[strlen(str)-i-1];
str[strlen(str)-i-1]=temp;
Вы просто напишете:
swap(str[i], str[sizeof(str) - i - 1]);
Заметьте, насколько понятнее.
Вы используете С++, просто используйте std::reverse()
std::reverse(str, str + strlen(str));
Глобальные переменные
Крайне плохая практика превращения переменных в глобальную, если им не нужно. В частности, я имею в виду i
об этом.
Резюме
Если бы я должен был написать эту функцию, она выглядела бы как одна из двух следующих реализаций:
void reverseChar(char* str) {
const size_t len = strlen(str);
for(size_t i=0; i<len/2; i++)
swap(str[i], str[len-i-1]);
}
void reverseChar(char* str) {
std::reverse(str, str + strlen(str));
}
При тестировании оба из них производят dlrow olleh
на входе hello world
.
Ответ 2
Проблема в том, что внутри вашей функции str
не является массивом, а указателем. Таким образом, sizeof
получит размер указателя, а не длину массива, на который он указывает. Кроме того, даже если он дал вам размер массива, это не длина строки. Для этого лучше используйте strlen
.
Чтобы избежать множественных вызовов strlen
, дайте функции другому параметру, который указывает длину:
void reverseChar(char* str, int len)
{
for(i=0; i<len/2; i++)
{
char temp=str[i];
str[i]=str[len-i-1];
str[len-i-1]=temp;
}
}
и назовите его
reverseChar(str, strlen(str))
Еще одно улучшение, как упоминалось в комментариях, заключается в использовании std::swap
в теле цикла:
void reverseChar(char* str, int len)
{
for(i=0; i<len/2; i++)
{
std::swap(str[i], str[len-i-1]);
}
}
Кроме того, есть std::reverse
, который делает почти что.
Ответ 3
//reverse a string
#include<iostream>
using namespace std;
int strlen(char * str) {
int len = 0;
while (*str != '\0') {
len++;
str++;
}
return len;
}
void reverse(char* str, int len) {
for(int i=0; i<len/2; i++) {
char temp=str[i];
str[i]=str[len-i-1];
str[len-i-1]=temp;
}
}
int main() {
char str[100];
cin.getline(str,100);
reverse(str, strlen(str));
cout<<str<<endl;
getchar();
return 0;
}
Ответ 4
Если бы я был вами, я бы просто написал его так:
int main()
{
string str;
cout << "Enter a string: " << endl;
getline(cin, str);
for (int x = str.length() - 1; x > -1; x--)
{
cout << str[x];
}
return 0;
}
Это очень простой способ сделать это и отлично работает.
Ответ 5
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char str[80];
cout << "Enter a string bro: \n";
gets_s(str);
for (int i = strlen(str) - 1; i > -1; i--)
{
cout << str[i];
}
}