Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » String aufteilen und in int array speichern

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
17.04.2006, 17:48 Uhr
Steffen



Hallo,

ich habe folgendes Problem, an dem ich langsam verzweifel!

Also ich habe einen string, in dem immer etwas xx.xx.xx steht, immer durch Punkt getrennt.

Ich will nun diese 3 Elemente des Strings auslesen und jeweils in ein int array mit 3 Elementen speichern.

Ich hab das ganze bis jetzt folgendermaßen probiert:

C++:
void setNewDate(string new_date)
{        
    const char *new_date2 = new_date.c_str();
    
    char *tmp = new char[new_date.length()+1];
    strcpy(tmp, new_date2);
    
    char *part;
    
    part = strtok(tmp, ".");
    cout << "part: " << part << endl;
    part = strtok(tmp, ".");
    cout << "part: " << part << endl;
}



allerdings hab ich hier das Problem, dass strtok() bei jedem Durchgang immer nur das erste Element liefert (habs auch schon mit Schleifen probiert).....das umwandeln in int wäre ja dann kein Problem.

Ich wollte diesen Ansatz allerdings nicht weiter verfolgen, da ich das ganze lieber ohne C-Strings lösen würde.

Gibts da irgendwie die möglichkeit das mit C++-Strings zu lösen ?

Vielen Dank

Gruß Steffen

Dieser Post wurde am 17.04.2006 um 17:48 Uhr von Steffen editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.04.2006, 22:11 Uhr
~StarShaper
Gast



Zitat von Steffen:
Ich wollte diesen Ansatz allerdings nicht weiter verfolgen, da ich das ganze lieber ohne C-Strings lösen würde.

Gibts da irgendwie die möglichkeit das mit C++-Strings zu lösen ?


Natürlich lässt sich das ganze auch mit C++ strings lösen. Nun ist der verwendete Algorithmus davon abhängig ob die von dir genannte Zeichenfolge öfters im string vorkommt bzw. der Delimiter also der Punkt (.)?

Wenn ja, dann solltest du auf Regular Expressions zurückgreifen. Mit diesen kannst du alle Vorkommnisse dieser Zeichenfolge im String sehr leicht raussuchen lassen. Die Boost Bibliotheken besitzen eine sehr mächtige REGEX Bibliothek die an die umfangreiche Perl Regex Syntax angelehnt ist!

Wenn nein, könntest du diese Lösung verwenden.


C++:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>

// Ggf. in einen int konvertireren
template <typename T>
T ToNumber(const std::string& str)
{
    T value;

    std::stringstream ss(str);
    ss >> value;

    return value;
}

void setNewDate(std::string& new_date)
{
    int x;
    int arr[3];
    std::string::iterator i = find(new_date.begin(), new_date.end(), '.');
    
    x = i - new_date.begin();
    // Überprüfe ob das dritte nachflgende Zeichen auch ein Punkt ist
    if(new_date[(x + 3)] == '.')
    {
        std::cout << "String gefunden!" << std::endl;
        arr[0] = ToNumber<int>(new_date.substr(x - 2, x - 1));
        arr[1] = ToNumber<int>(new_date.substr(x + 1, x + 2));
        arr[2] = ToNumber<int>(new_date.substr(x + 4, x + 5));      
    }

    // Optional ausgeben
    std::cout << arr[0] << arr[1] << arr[2] << std::endl;
}

int main()
{
    std::string s = "Heute ist der 17.04.06 und blablabla";
    setNewDate(s);
}


Die Umwandlung von std::string in einen int erfordert eine etwas bessere Konvertierungsmethode. Deshalb die Templatefunktion. Bedenke auch das Ziffern mit führende 0en, also 06, nicht dargestellt werden, also nur 6 ausgegeben wird! Bei Bedarf kannst du das aber mit setw(2) und setfill('0') erzwingen.

cu
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.04.2006, 23:28 Uhr
~StarShaper
Gast


Achja, bedenke das die Funktion keine Überprüfung vornimmt! find() liefert last zurück falls kein Punkt im String enthalten ist! Wenn du deine Funktion gegen derartige Fehler absichern möchtest, würde ich den Rückgabetyp bool empfehlen.


C++:
    // Kein Delimiter gefunden
    if(i == new_date.end())
        return false;



C++:
    if(!setNewDate(s))
        std::cout << "Datum im String nicht gefunden!" << std::endl;


cu
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
18.04.2006, 00:00 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


ggf auch mal sscanf anschauen...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
18.04.2006, 11:22 Uhr
Steffen



Vielen Dank ~StartShaper

Hab mir das mit den regular Expressions einmal angeguckt und werd mich heute Abend mal etwas intensiver damit beschäftigen!

C++ ist npch relativ unerforschtes Land für mich, daher die Frage, ob ich das richtig verstanden habe:

template ist klar


C++:
void setNewDate(std::string& new_date)
{
    int x;
    int arr[3];
    std::string::iterator i = find(new_date.begin(), new_date.end(), '.');   // 1. Es wird gesucht, an welcher Stelle zuerst ein Punkt auftaucht, durchsucht wird dabei der String von begin bis ende. Richtig ?
    
    x = i - new_date.begin();   // 2. Versteh ich nicht, wieso i - new_date.begin()? Weil i sonst am Ende des Strings steht ?
    // Überprüfe ob das dritte nachflgende Zeichen auch ein Punkt ist
    if(new_date[(x + 3)] == '.')
    {
        std::cout << "String gefunden!" << std::endl;
        arr[0] = ToNumber<int>(new_date.substr(x - 2, x - 1));
        arr[1] = ToNumber<int>(new_date.substr(x + 1, x + 2));
        arr[2] = ToNumber<int>(new_date.substr(x + 4, x + 5));      
    }

    // Optional ausgeben
    std::cout << arr[0] << arr[1] << arr[2] << std::endl;
}




Sorry, für die evtl. etwas dummen Fragen, aber jeder fängt mal klein an

Wäre super wenn du mir das bei 1. und 2. erkklären könntest, hab noch nie mit iteratoren gearbeitet

Gruß Steffen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
18.04.2006, 12:12 Uhr
~StarShaper
Gast


Wie gesagt sind Regular Expressions (Reguläre Ausdrücke) geradezu ideal für derartige Aufgaben. Und die Boost Bibliotheken stellen eine mächtige Regex für C++ zur Verfügung!

Der Code ist prinzipiell einfach. C++ Iteratoren kannst du dir als ein abstraktes Gebilde vorstellen. Mithilfe von Iteratoren kann über Container und Streams iteriert werden, d.h. du kannst mit ihnen auf einzelne Elemente zugreifen. Iteratoren sind also eine Art Verallgemeinerung der klassischen Zeiger.

Zu 1: Ja. find() ist, wie anhand des Präfix std:: zu sehen ist ein Algorithmus aus der STL. Er liefert das ERSTE Vorkommnis des gesuchten Zeichens in dem angegebenen Bereich, der in unserem Fall vom string Anfang bis string ende geht, er soll ja den gesamten string durchsuchen.

Zu 2: Die Methode begin() liefert einen Iterator zurück. Sie zeigt auf das Element first im Container. Mithilfe der Subtraktion erhälst du eine gültige Position die später als Index weiterverwendet werden kann. Zudem iteriert der Iterator durch den gesamten String, es muss also der Beginn bekannt sein.

Ich würde die Funktion übrigens ein wenig abändern um einen eventuellen Fehler zu umgehen. Oder am besten gleich mit at() auf die Indexe zugreifen und somit eine Exception im Fehlerfall auslösen.


C++:
bool setNewDate(std::string& new_date)
{
    int x;
    int arr[3];
    std::string::iterator i = find(new_date.begin() + 19, new_date.end(), '.');

    x = i - new_date.begin();

    if(i == new_date.end() || (x + 5) >= new_date.length())
        return false;    

    if((new_date[(x + 3)] == '.'))
    {
        arr[0] = ToNumber<int>(new_date.substr(x - 2, x - 1));
        arr[1] = ToNumber<int>(new_date.substr(x + 1, x + 2));
        arr[2] = ToNumber<int>(new_date.substr(x + 4, x + 5));  

        std::cout << arr[0] << arr[1] << arr[2] << std::endl;
        return true;
    }
    else
        return false;
}

int main()
{
    std::string s = "Heute ist der 17.04.06";
    if(!setNewDate(s))
        std::cout << "Datum im String nicht gefunden!" << std::endl;  

}


cu
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
18.04.2006, 12:14 Uhr
~StarShaper
Gast


Uups, die "- 19" in find() gehört nicht hinein!

cu
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
18.04.2006, 21:49 Uhr
Steffen



Funktioniert jetzt alles wunderbar

Vielen Dank

probier das ganze die Tage auch nochmal mit Regular Expressions
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: