Hoe te repareren ‘Std :: Logic_Error’ Wat (): Basic_string :: _ M_Construct NULL NIET GELDIG FOUT?

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 intals invoer accepteren. Maar het heeft een constructeur die een const char *aanwijzingen accepteert, welke 0 impliciet converteerbaar is. Het construeren van een std::stringmet een NULL char *POINTER is undefined gedrag en uw implementatie heeft ervoor gekozen om een ​​std::logic_errorUitzondering 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 boolretourneert 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 falsewilt 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.

Other episodes