Ik probeer te controleren of een invoerring alfanumeriek of meer hoofdletters of leeg is. Als de invoerreeks een van de bovengenoemde slagen is, wil ik gewoon false / 0 retourneren, anders werkt het met de rest van het programma dat prima werkt. Het stuk van mijn programma dat een probleem wordt gegeven:
std::string myfunc(std::string input){
std::string b="";
if (!input.size()) return 0;
for (int i = 0; i < input.size(); i++){
if ( input[i] < 'a' || input[i] > 'z'|| isalpha(input[i]) || isupper(input[i]) ) return 0;
}
b = input;
//just copy the input string for now.
return b;
}
en ik noem deze functie als
int main(){
std::string input="Somthing";
std::cout << myfunc(input)<< std::endl;
return 0;
}
De onderstaande fout krijgen?
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Aborted (core dumped)
Dit programma werkt goed zonder deze twee randgevallen. Ik kan de fout niet begrijpen en een oplossing vinden? Suggesties over wat ik verkeerd doe?
Antwoord 1, Autoriteit 100%
Het probleem is de twee return 0;
verklaringen in uw functie. De functie retourneert een std::string
, die geen constructeurs heeft die een int
als invoer accepteren. Maar het heeft een constructeur die een const char *
aanwijzingen accepteert, welke 0 impliciet converteerbaar is. Het construeren van een std::string
met een NULL char *
POINTER is undefined gedrag en uw implementatie heeft ervoor gekozen om een std::logic_error
Uitzondering die u niet in uw code vangt.
In dit geval zou ik in plaats daarvan gewoon een lege string retourneren:
std::string myfunc(const std::string &input){
if (input.empty()) return "";
for (int i = 0; i < input.size(); ++i){
char ch = input[i];
if ( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) ) return "";
}
return input;
}
De beller kan vervolgens controleren of de retourwaarde leeg is, als het:
wil
if (myfunc(input).empty())
// error, do something
else
// OK, do something else
die beter zouden worden geserveerd met een functie die een bool
retourneert in plaats van een std::string
:
bool isvalid(const std::string &input){
if (input.empty()) return false;
for (int i = 0; i < input.size(); ++i){
char ch = input[i];
if ( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) ) return false;
}
return true;
}
// if you still needed this function for something...
std::string myfunc(const std::string &input){
if (!isvalid(input)) return "";
return input;
}
if (!isvalid(input))
// error, do something
else
// OK, do something else
Antwoord 2
Als u false (of true) wilt retourneren, moet u het retourtype van uw functie wijzigen in bool
bool myfunc(std::string input) {
^^^^
Ten tweede, als u false
wilt retourneren, moet u dat retourneren
if (!input.size()) return false;
^^^^^
Het retourneren van 0 vanuit een booleaanse functie is geen fout omdat 0 automatisch wordt geconverteerd naar onwaar, maar het is duidelijk stilistisch beter om te zeggen wat u bedoelt.