Frage

Es war ein vorübergehender Kommentar in einem Buch von mir über Menschen Kommas in ganzen Zahlen und vermasseln Ihr Programm eingegeben hat, aber es hat nicht zu erarbeiten. Das hat mir denken, also versuchte ich ein wenig Algorithmus schreiben eine std :: string zu nehmen und alle nicht-ganzzahligen Zeichen entfernen. Dieser Code kompiliert, sondern überspringt ausgegeben. Warum wird nichts newstring zugewiesen? Hat if (isdigit (FString [i])) bewerten, um wahr der Adresse es zeigt eine Ziffer zu halten?

//little algorithm to take the non-integers out of a string
//no idea on efficiency

#include <iostream>
#include <string>

int main()
{
    std::cout << "Enter a number with non-integer characters: ";

    std::string fstring; 
    getline(std::cin, fstring);

    std::string newstring;

    int i = 0, x = 0;

    while (i != fstring.length())
    {
        if (isdigit(fstring[i]))
        {
            newstring[x] = fstring[i];
            i++;
            x++;
        }
        else
        {
           i++;
        }
    }

    std::cout << std::endl;
    std::cout << newstring;
    system("PAUSE");
}

Secondary Frage, die vielleicht an anderer Stelle gehört: Wie konvertieren Sie einen String in einen int (oder eine Fließkommazahl)

War es hilfreich?

Lösung

newstring ist mit einer Länge von 0, so newstring [x], wobei x = 0 tatsächlich illegal ist. Sie sollten auf den String anhängen mit: newstring.append (1, FString [i])

Für die sekundäre Frage, suchen Sie nach atoi (), atof (), strtol (0, strtof () Funktionen.

Andere Tipps

Strings sind wie Arrays, aber das Standard-Konstruktor für eine Zeichenfolge erstellt eine leere Zeichenkette. Warum sollte es mehr Speicher zuzuteilen, als es braucht? Auch wenn es der Fall ist, gibt es keine zu sagen, wie viel, oder wenn es groß genug für eine gefilterte Kopie von FString sein wird. Ich bin beeindruckt, es stürzt nicht ab.

Eine einfache Änderung wäre zu ändern:

std::string newstring;

zu:

 std::string newstring(fstring.length(), '\0')

Und nach der Schleife hinzugefügt werden:

 newstring.resize(x);

Dadurch wird sichergestellt, dass newstring zumindest genügend Platz haben wird (wahrscheinlich) während der Filtration und wird auf die entsprechende Größe wird getrimmt, wenn Sie fertig sind Filterung. Sie können auch in der std::remove_copy_if Funktion in <algorithm> interessiert sein.

z.

struct isnotdigit { bool operator()(char c) { return !isdigit(c); } };

std::string newstring(fstring.length(), '\0');
std::string::iterator i = std::remove_copy_if(fstring.begin(), 
  fstring.end(), newstring.begin(), isnotdigit());
newstring.erase(i, newstring.end());

Wie für einen String in einem integer / float, zusätzlich Umwandlung atoi, strtol, atof, strtof usw. Funktionen bereits erwähnt, können Sie auch mit der iostream-Bibliothek machen:

 #include <sstream>
 std::string integer("23");
 std::istringstream iss(integer);
 int result;
 iss >> result;

 std::string floatingpoint("3.14");
 std::istringstream iss2(floatingpoint);
 double result2;
 iss2 >> result2;

Auch wenn Sie mit der printf Familie von Funktionen vertraut sind, können Sie in scanf interessiert sein, sscanf

 const char *s = "23";
 int result;
 sscanf(s, "%d", &result);

Expansion auf Shing Yip Antwort:

Nicht-Ziffern entfernen:

#include <iostream>
#include <functional>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    string fstring;
    getline(cin, fstring);
    fstring.erase(
        remove_if(fstring.begin(), fstring.end(),
            not1(ptr_fun(static_cast<int(*)(int)>(isdigit)))
        ),
        fstring.end()
    );

    cout << fstring << "\n";
}

Ich bin mir nicht sicher, warum das static_cast benötigt wird, though. Ich denke, dass ist etwas zweideutig über isdigit ohne sie. [Edit:. Wenn Sie nicht „using namespace std“ tun, dann müssen Sie es nicht, so ist es meine Schuld für faul Beispiel das Schreiben von Code]

Es ist fraglich, ob dies ist einfacher als Sie Ihre eigene Schleife rollen:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string fstring, ins;
    getline(cin, ins);
    for (string::iterator it = ins.begin(); it != ins.end(); ++it) {
        if (isdigit(*it)) fstring.push_back(*it);
    }
    cout << fstring << "\n";
}

Und C ++ 0x haben copy_if, die durch Unfall grundsätzlich weggelassen wurde, und ist trivial zu implementieren:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

int main() {
    std::string fstring, ins;
    std::getline(std::cin, ins);
    std::copy_if(ins.begin(), ins.end(), 
        std::back_inserter(fstring), isdigit);
    std::cout << fstring << "\n";
}

Zur Umrechnung in int (oder float):

int i = boost::lexical_cast<int>(fstring);

Oder wenn Sie nicht boost haben:

#include <sstream>

int i = 0;
std::stringstream(fstring) >> i;

Beachten Sie, dass ich initialisieren müssen, sonst wird es nicht gesetzt werden, wenn FString leer ist.

Stellen entfernen:

fstring.erase(
      std::remove_if(fstring.begin(), fstring.end(), &isdigit), 
      fstring.end());

Zeichenfolge konvertieren int / float /...:

int n1 = boost::lexical_cast<int>("123");
float n2 = boost::lexical_cast<float>("123.456");
  • string zu Gleitkommazahl:

Sie müssen #include <cstdlib>

float strtof(const char *nptr, char **endptr);

Zum Beispiel:

 float f = strtof("3.4",NULL);
  • string to integer

Sie müssen #include <cstdlib>

int atoi(const char *numPtr);

Beachten Sie, dass diese C - Funktionen, nicht C ++, so dass Sie den c_str () -Methode auf std :: string verwenden müssen das C-String zu erhalten

.
const char* c_str ( ) const;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top