2012-04-07 3 views
0

Als Teil eines größeren Programms muss ich eine Zeichenfolge von Zahlen in eine ganze Zahl (eventuell ein Float) konvertieren. Leider darf ich Casting oder Atoi nicht verwenden.Konvertieren einer Zeichenfolge von Zahlen in eine beliebige Form eines int

Ich dachte, eine einfache Bedienung entlang der Linien von dieser:

void power10combiner(string deciValue){ 
    int result; 
    int MaxIndex=strlen(deciValue); 
     for(int i=0; MaxIndex>i;i++) 
     { 
      result+=(deciValue[i] * 10**(MaxIndex-i)); 
     }  
} 

funktionieren würde. Wie konvertiere ich ein char in ein int? Ich nehme an, dass ich ASCII-Konvertierungen verwenden könnte, aber ich könnte keine Zeichen zu Ints hinzufügen (vorausgesetzt, dass die Konvertierungsmethode eine enorme if-Anweisung haben soll, die den unterschiedlichen numerischen Wert hinter jeder ASCII-Zahl zurückgibt).

+4

Willkommen bei StackOverflow! Du sagst "nicht erlaubt". Ist es dein Chef, dein Compiler oder dein Professor, der dich einschränkt? Wenn es Ihr Professor ist, fügen Sie bitte "Hausaufgaben" -Tag zu Ihrer Frage hinzu. –

+0

Es gibt ein paar kleinere Probleme mit Ihrem Code. Zuerst gibt es keinen '**' Operator für die Potenzierung in C++.Zweitens kann 'std :: string' nicht als Parameter für' strlen() 'verwendet werden; Sie könnten stattdessen 'decivalue.size()' verwenden. –

Antwort

0

EDITED durch Vorschlag, und fügte ein bisschen Erklärung hinzu.

int base = 1; 
int len = strlen(deciValue); 
int result = 0; 
for (int i = (len-1); i >= 0; i--) { // Loop right to left. Is this off by one? Too tired to check. 
    result += (int(deciValue[i] - '0') * base); // '0' means "where 0 is" in the character set. We are doing the conversion int() because it will try to multiply it as a character value otherwise; we must cast it to int. 
    base *= 10; // This raises the base...it's exponential but simple and uses no outside means 
} 

Dies setzt voraus, dass die Zeichenfolge nur Zahlen ist. Bitte kommentieren Sie, wenn Sie weitere Erläuterungen benötigen.

+0

Was ist mit der Magie '0x30'? Sicherlich ist das nicht tragbar. –

+0

@KerrekSB strlen() arbeitet an ASCII-Strings. ASCII ist enorm portabel. 0x30 ist, wo die Ziffern 0-9 beginnen; subtrahiere 0x30 und du bekommst die Zahlen 0-9. Wenn sich der Einreicher Sorgen macht, ist es eine andere Geschichte, aber er hat auch atoi erwähnt, das auch an ASCII-Strings arbeitet. Ich habe nur Mathe gemacht ... verstanden? –

+0

Das OP ist wahrscheinlich noch mehr verwirrt über Kodierungen, aber es gibt absolut keinen Grund für Sie, diese Werte hart zu kodieren - ''0'' wird vollkommen gut gehen. –

2

Es gibt viele Möglichkeiten, dies zu tun, und es gibt einige Optimierungen und Korrekturen, die an Ihrer Funktion vorgenommen werden können.

1) Sie geben keinen Wert von Ihrer Funktion zurück, so dass der Rückgabetyp nun int ist.

2) Sie können diese Funktion optimieren, indem Sie eine Konstante const übergeben.

Jetzt für die Beispiele.

Verwenden Sie std::stringstream, um die Konvertierung durchzuführen.

int power10combiner(const string& deciValue) 
{ 
    int result; 

    std::stringstream ss; 
    ss << deciValue.c_str(); 

    ss >> result; 

    return result; 
} 

Ohne Verwendung std :: string die Konvertierung zu tun.

int power10combiner(const string& deciValue) 
{ 
    int result = 0; 
    for (int pos = 0; deciValue[pos] != '\0'; pos++) 
     result = result*10 + (deciValue[pos] - '0'); 

    return result; 
} 
+0

Ich denke, es ist sicher zu sagen, dass, wenn sein Professor ihm sagt, atoi nicht zu verwenden, std :: stringstream auch draußen ist ... aber das ist eine Annahme, die ich mache. Es scheint eine Übung zu sein, mit einem Algorithmus anstelle einer eingebauten Funktion zu arbeiten. –

+0

@OrgnlDave: Ich dachte, dass das der Fall sein könnte, aber er war nicht spezifisch, also dachte ich, dass ich versuchen würde, andernfalls zu antworten. – josephthomas

+0

Nun, egal welche Antwort er sucht, er hat es jetzt. Du oder ich - C++ eingebaut oder mich aus der Klemme müde. :-D –

0

Sie einfach die Umsetzung des Stellenwertsystem, für eine beliebige Anzahl Basis einen String iterativ in eine ganze Zahl analysieren. Ihren String Unter der Annahme, nullterminierten und die Zahl unsigned:

unsigned int parse(const char * s, unsigned int base) 
{ 
    unsigned int result = 0; 
    for (; *s; ++s) 
    { 
     result *= base; 
     result += *s - '0'; // see note 
    } 
    return result; 
} 

Wie geschrieben, funktioniert dies nur für Zahlenbasen bis zu 10 mit den Ziffern 0, ..., 9, die angeordnet sind, um zu gewährleisten in Ihrem Ausführungszeichensatz. Wenn Sie größere Zahlenbasen oder liberalere Symbole benötigen, müssen Sie *s - '0' in der angegebenen Zeile durch einen geeigneten Suchmechanismus ersetzen, der den Ziffernwert Ihres Eingabezeichens bestimmt.

+0

Ich denke du meinst während (* s). –

+0

Sie inkrementieren auch einen const Char-Zeiger ... –

+0

Graw, ich fühle mich schlecht nitpicking anderen meist gültigen Code. Ich sollte stattdessen ein paar Reps verdienen. :-D –

0

Ich würde std :: stringstream verwenden, aber niemand hat noch eine Lösung mit strtol gepostet, also hier ist einer. Beachten Sie, dass keine Fehler außerhalb des zulässigen Bereichs ausgeführt werden. Unter Unix/Linux können Sie die errno Variable verwenden, um solche Fehler zu erkennen (durch Vergleich mit ERANGE).

BTW, es gibt strtod/strtof/strtold Funktionen für Fließkommazahlen.

#include <iostream> 
#include <cstdlib> 
#include <string> 


int power10combiner(const std::string& deciValue){ 
    const char* str = deciValue.c_str(); 
    char* end; // the pointer to the first incorrect character if there is such 
    // strtol/strtoll accept the desired base as their third argument 
    long int res = strtol(str, &end, 10); 

    if (deciValue.empty() || *end != '\0') { 
     // handle error somehow, for example by throwing an exception 
    } 
    return res; 
} 

int main() 
{ 
    std::string s = "100"; 

    std::cout << power10combiner(s) << std::endl; 
} 
Verwandte Themen