Ik begin net met c++ en heb moeite met het begrijpen van const char*
. Ik probeer de invoer in de methode om te zetten in string
en verander vervolgens de strings om koppeltekens toe te voegen waar ik wil en neem uiteindelijk die string en converteer deze terug naar char*
terug te keren. Als ik dit tot nu toe probeer, krijg ik busfout 10.
char* getHyphen(const char* input){
string vowels [12] = {"A","E","I","O","U","Y","a","e","i","o","u","y"};
//convert char* to string
string a;
int i = 0;
while(input != '\0'){
a += input[i];
input++;
i++;
}
//convert a string to char*
return NULL;
}
Antwoord 1, autoriteit 100%
A: De klasse std::string
heeft een constructor die een char const*
nodig heeft, dus je maakt gewoon een instantie om je conversie uit te voeren.
B: Instances van std::string
hebben een c_str()
lidfunctie die een char const*
retourneert die u kunt gebruiken om terug converteren naar char const*
.
auto my_cstr = "Hello"; // A
std::string s(my_cstr); // A
// ... modify 's' ...
auto back_to_cstr = s.c_str(); // B
Antwoord 2, autoriteit 22%
Allereerst heb je niet al die code nodig om een std::string
van de invoer te construeren. Je kunt gewoon het volgende gebruiken:
string a(input);
Voor het retourneren van een nieuwe char*
kun je het volgende gebruiken:
return strdup(a.c_str()); // strdup is a non-standard function but it
// can be easily implemented if necessary.
Zorg ervoor dat u de toewijzing van de geretourneerde waarde ongedaan maakt.
Het is beter om gewoon een std::string
te retourneren, zodat de gebruikers van uw functie zich geen zorgen hoeven te maken over geheugentoewijzing/deallocatie.
std::string getHyphen(const char* input){
Antwoord 3, autoriteit 6%
Gebruik char*
niet. Gebruik std::string
, zoals alle anderen je hier vertellen. Dit zal al dergelijke problemen elimineren.
Voor de volledigheid en omdat je de achtergrond wilt begrijpen, laten we analyseren wat er aan de hand is.
while(input != '\0'){
Je bedoelt waarschijnlijk:
while(*input != '\0') {
Uw code vergelijkt de input
-aanwijzer zelf met \0
, dwz er wordt gecontroleerd op een null-aanwijzer, wat te wijten is aan de ongelukkige automatische conversie van een \0
char
. Als je probeerde te vergelijken met bijvoorbeeld 'x'
of 'a'
, zou je een compilatiefout krijgen in plaats van runtime-crashes.
U wilt de aanwijzer derefererenvia *input
om bij de char
te komen waarnaar wordt verwezen.
a += input[i]; input++; i++;
Dit werkt ook niet. U verhoogt de input
-aanwijzer, maar met [i]
gaat u zelfs verder. Als bijvoorbeeld input
drie keer is opgehoogd, dan is input[3]
het zevende teken van de oorspronkelijke array die aan de functie is doorgegeven, niet het vierde. Dit resulteert uiteindelijk in ongedefinieerd gedrag wanneer u de grenzen van de array verlaat. Ongedefinieerd gedrag kan ook de “busfout 10”zijn die u noemt.
Vervangen door:
a += *input;
input++;
i++;
(Eigenlijk, nu i
niet meer wordt gebruikt, kun je het helemaal verwijderen.)
En laat me het nog een keer herhalen: gebruik char*
niet. Gebruik std::string
.
Antwoord 4
Wijzig uw functiedeclaratie van
char* getHyphen(const char* input)
naar
auto hyphenated( string const& input )
-> string
en vermijd alle problemen van conversie naar char const*
en terug.
Dat gezegd hebbende, je kunt als volgt een std::string
maken van een char_const*
:
string( "Blah" )
en je krijgt een tijdelijke char const*
terug door de c_str
methode te gebruiken.
Houd er rekening mee dat het resultaat van c_str
alleen geldig is zolang de originele string
-instantie bestaat en niet is gewijzigd. Bijvoorbeeld, het toepassen van c_str
op een lokale string
en het retourneren van dat resultaat, levert Undefined Behavior op en is geen goed idee. Als u absoluut een char*
of char const*
moet retourneren, wijs dan een array toe met new
en kopieer de stringgegevens met strcpy
, zoals dit: return strcpy( new char[s.length()+1], s.c_str() )
, waar de +1
is geschikt voor een afsluitende zero-byte.