2016-04-27 7 views
0

Ich habe das folgende Problem - Ich schrieb eine Funktion, die eine Zeichenfolge und konvertiert es in ein int, aber ich weiß nicht, wie überprüft werden, ob ein Überlauf auftritt. Ich möchte den letzten möglichen Wert der Ganzzahl zurückgeben, bevor der Überlauf aufgetreten ist. Zum Beispiel: wenn ich eine String-Repräsentation von "2147483648" habe, möchte ich 214748364 als int zurückgeben, weil in der nächsten Iteration ein Überlauf auftreten wird. Hast du irgendwelche Ideen, wie du das lösen kannst?Zeichenkette manuell in int umwandeln und prüfen, ob in C/C++ ein Überlauf aufgetreten ist?

Mein Code ist:

int main() { 
    string s = "2147483647"; 
    int num = 0, i = 0, buff = 0; 
    bool isNegative = false; 

    if (s[0] == '-') { 
      isNegative = true; 
      i++; 
     } 
    while (i < s.length()) { 
     if (num < (INT_MAX/10)) { 
      num *= 10; 
     } 

     if (num < INT_MAX - 10) 
      num += s[i++] - '0'; 
     else 
      break; 

    } 

    if (isNegative) 
     num = -num; 

    cout << "\nthe number is: " << num; 

    getch(); 
    return 0; 
} 
+0

Können Sie mir zeigen mehrere Ein- und Ausgänge, die gewünscht werden, und oder erklären, was Sie näher wollen. Es scheint einen einfacheren Weg zu geben, dies zu tun. – stackoverfloweth

+1

Sie können den Wert von 'num' * vor * mit 10 multiplizieren. Fangen Sie das Überlaufereignis, bevor es passiert. –

+0

Dürfen wir annehmen, dass die Verwendung bereits existierender Funktionen wie 'std :: stoi' und' strtol' nicht erlaubt ist? – user4581301

Antwort

1

mit int Überlauf zu bewältigen, Code muss es verhindern.
Einfacher Test, wenn num und digit zu groß sind, bevor num*10 + digit

(num >= INT_MAX/10) && ((num > INT_MAX/10) || (digit > INT_MAX%10)) 

Nutzungs

overflow = false; 
while (i < s.length()) { 
    int digit = s[i++] - '0'; 

    // Will num*10 + digit overflow? 
    if ((num >= INT_MAX/10) && ((num > INT_MAX/10) || (digit > INT_MAX%10))) { 
    // or break per OP's coding goal 
    num = INT_MAX; 
    overflow = true; 
    } else { 
    num *= 10; 
    num += digit; 
    } 
} 

OP Code hat auch Probleme mit der Textversion von INT_MIN versucht.

Sample my_atoi(), die korrekt zurückgibt [INT_MIN ... INT_MAX]

1

Ich sehe zwei mögliche Lösungen:

1) Überprüfen Sie, ob num < (INT_MAX/10), bevor sie mit 10 num Multiplikation und prüfen Sie, dass num < INT_MAX - 10 vor Hinzufügen von s [i ++]. Sie müssen hierfür limits.h angeben.

2) Nachdem Sie Ihre Zeichenfolge in einen int konvertiert haben, verwenden Sie snprintf, um Ihr int zurück in eine Zeichenfolge zu drucken, und verwenden Sie strcmp, um festzustellen, ob Ihre Zeichenfolgen identisch sind.

+0

denke, du meinst 'INT_MAX/10' hier' INT_MAX - 10' – user4581301

+0

@ user4581301 die Antwort hat beides, aber nur die 'num <(INT_MAX/10)' ist notwendig. Das Hinzufügen von 9 kann nicht zu einem Überlauf von 'INT_MAX' führen. –

+0

Ich habe versucht, 'if (num <(INT_MAX/10)) num * = 10; if (num Calihog

1

Ihre beste Wette ist stoi anstelle von Hand-Crafting eine minderwertige Lösung.

try { 
    i = stoi(s); 
} catch(const out_of_range& /*e*/) { 
    i = numeric_limits<int>::max(); 
} 

Live Example

+0

Es gibt "Manuell" aus einem bestimmten Grund. Ich möchte keine Funktionen für diese Lösung verwenden. Danke trotzdem. – Calihog

+0

@Calihog Ich bin mir nicht sicher, warum du das sagst? Warum sollten Sie versuchen, das, was der Standard bereits bietet, neu zu erfinden? Es sei denn ... Ist das Hausaufgaben? –

Verwandte Themen