Inversarea șirului de caractere C++ utilizând matrice de caractere (Programare, C++, Array-Uri, String)

StackPointer a intrebat.

Am scris un program simplu în C++ pentru a inversa un șir de caractere. Am stocat un șir de caractere în character array. Pentru a inversa un șir de caractere, folosesc aceeași matrice de caractere și o variabilă temporară pentru a schimba caracterele dintr-o matrice.

#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;
    }
}

Acum, această metodă nu funcționează și, după executarea programului, primesc ca rezultat șirul NULL.

Așadar, vreau să știu de ce nu pot echivala matrice de caractere, de ce nu ar funcționa acest program. Și care este soluția sau trucul pe care îl pot folosi pentru a face același program să funcționeze?

Comentarii

  • În loc de linia trei cu variabila temporară, ați putea folosi std::swap(str[i], str[sizeof(str)-i-1]); –  > Por leemes.
  • BTW c++ != c, aceasta are using namespace std așa că îl schimb în c++ –  > Por yizzlez.
  • Chiar și cu o matrice de caractere, std::reverse. –  > Por chris.
  • sizeof(str) –> strlen(str) –  > Por chux – Reînscrieți-o pe Monica.
  • Ce este ip în sizeof(ip)? –  > Por poy.
5 răspunsuri
Bill Lynch

sizeof(str) nu face ceea ce vă așteptați.

Având în vedere un char *str, sizeof(str) nu vă va da lungimea șirului respectiv. În schimb, vă va da numărul de octeți pe care îl ocupă un pointer. Probabil căutați strlen() în schimb.

Dacă am remedia această problemă, am avea:

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;
}

Acesta este C++, utilizați std::swap()

În C++, dacă doriți să schimbați conținutul a două variabile, utilizați std::swap în locul variabilei temporare.

Deci, în loc de:

char temp=str[i];
str[i]=str[strlen(str)-i-1];
str[strlen(str)-i-1]=temp;

Ați scrie doar:

swap(str[i], str[sizeof(str) - i - 1]);

Observați cât de clar este acest lucru.

Dacă folosiți C++, utilizați doar std::reverse()

std::reverse(str, str + strlen(str));

Variabile globale

Este o practică extrem de proastă să faci variabilele globale dacă nu este nevoie să fie. În special, mă refer la i la acest aspect.

Rezumat executiv

Dacă ar fi să scriu această funcție, ea ar arăta ca una dintre cele două implementări următoare:

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));
}

Atunci când sunt testate, ambele produc dlrow olleh la o intrare de hello world.

Comentarii

  • În exemplul dvs. sizeof din nou? –  > Por poitroae.
  • @aoeu: Da. Nu eram sigur dacă ar trebui să am atât remedierea privind utilizarea std::swap, cât și bug-ul privind sizeof acolo, sau să le las separate. Am adăugat ceva mai mult conținut pentru ca remedierile să fie mai lizibile. –  > Por Bill Lynch.
  • Vă mulțumim! A funcționat! Deci sizeof este doar pentru scopul pointerilor? Sau pot să folosesc și pentru matrice? –  > Por StackPointer.
  • @StackPointer: Citiți acestea: stackoverflow.com/questions/3203162/what-does-sizeof-do ro.cppreference.com/w/cpp/language/sizeof –  > Por Bill Lynch.
leemes

Problema este că în cadrul funcției dvs, str nu este o matrice, ci un pointer. Deci, sizeof îți va obține dimensiunea pointerului, nu lungimea array-ului la care acesta indică. De asemenea, chiar dacă ți-a dat dimensiunea array-ului, aceasta nu este lungimea șirului. Pentru aceasta, este mai bine să folosiți strlen.

Pentru a evita apelurile multiple la strlen, dați funcției un alt parametru, care să spună lungimea:

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;
    }
}

și apelați-o cu

reverseChar(str, strlen(str))

O altă îmbunătățire, așa cum s-a menționat în comentarii, este să folosiți std::swap în corpul buclei:

void reverseChar(char* str, int len)
{
    for(i=0; i<len/2; i++)
    {
        std::swap(str[i], str[len-i-1]);
    }
}

De asemenea, există std::reverse care face aproape exact acest lucru.

Kartik
//reverse a string
#include<iostream>
using namespace std;

int strlen(char * str) {
  int len = 0; 
  while (*str != '') {
    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;
}

Comentarii

  • ați putea adăuga o scurtă descriere la răspunsul dvs. care să explice de ce codul dvs. este diferit de ceilalți? Este neclar fără să-l încerci sau fără să te joci de-a compilatorul uman. –  > Por Bart.
Cjolsen06

Dacă aș fi în locul tău, l-aș scrie așa:

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;
}

Acesta este un mod foarte simplu de a face acest lucru și funcționează foarte bine.

Comentarii

  • Întrebarea a fost adresată cu privire la utilizarea unui char array, nu std::string. –  > Por Toți lucrătorii sunt esențiali.
Imalrightatthisstuff
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    char str[80];
    cout << "Enter a string bro: 
";
    gets_s(str);

    for (int i = strlen(str) - 1; i > -1; i--)
    {
        cout << str[i];
    }
}

user6655984