[c++] String manipulatie

Pagina: 1
Acties:

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Ik heb een probleempje met het verwerken van een string die uit een file word gelezen (is niet 1 regel maar kunnen er meerdere zijn).

Nu moet ik daar getallenreeksen uit halen (hier kunnen tabs, spaties en eindregels tussen zitten) . Dus bijv.
code:
1
2
12  23 
34


In java heb je daar dus mooi een stringtokenizer voor maar c++ dus blijkbaar niet (net begonnen == newbie). Anyway nu wil ik dus weten hoe je dit dus wel kan doen en/of heeft er iemand toevallig een stringtokenizer method ooit gevonden/gemaakt.

Ik hoop dat iemand me hier mee kan helpen want zit nu dus vast 8)7

Verwijderd

goed 't is geen c++ maar kijk es naar strtok?

  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

code:
1
2
3
4
int getal;
std::cin >> getal;
std::cin >> getal;
std::cin >> getal;

Dat was niet zo moeilijk ;) Hij skipt whitespace automatisch.

FireFox - neem het web in eigen hand


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Uit de extreem losse pols (dwz niet gecompiled of zo, ingetypt hier op het forum):

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int GetNextNumber(char* &p_String, bool &p_EndOfString)
{
int      l_Value = 0;

// Skip leading whitespace
while(*p_String)
  {
  // Check for numeric character
  if(*p_String >= '0' && *p_String <= '9')
    {
    // Extract full value
    do
      l_Value = l_Value * 10 + (*p_String - '0');     
    while(*++p_String >= '0' && *p_String <= '9');

    // Return extracted value and notify that there might be more
    p_EndOfString = false;
    return l_Value;
    }
  // Skip uninteresting character
  p_String++;
  }
// Return end-of-string indicator with 0 value
p_EndOfString = true;
return 0;
}

Eventuele signed int support kun je hier zo inbakken trouwens.

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

PommeFritz schreef op 02 december 2002 @ 01:56:
code:
1
2
3
4
int getal;
std::cin >> getal;
std::cin >> getal;
std::cin >> getal;

Dat was niet zo moeilijk ;) Hij skipt whitespace automatisch.
Hehe misschien ben ik wel te old school :) Maja had zin om botte chop-code te kloppen (en die van mij is hopelijk sneller).

Wat doet ie trouwens als je niet weet hoeveel getallen er zijn? Exception is niet echt netjes :P

Professionele website nodig?


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Verwijderd schreef op 02 december 2002 @ 01:34:
goed 't is geen c++ maar kijk es naar strtok?
Heb net ff wat gezocht en dit gebakken

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
    char input[] = "3\n5  \n 12  17  33 44 45 73 74 76 88\t98 126";
    char *token;
    String temp;

    token = strtok(input, "  \n\t");

    while (token != NULL)
    {
        temp += String(token) +"\t";
        token = strtok(NULL," \n\t");
    }

    textFile3->Text = temp;


Alleen ik weer dus niet hoe je een string input kan omzetten naar die char hiero. Dus een input string die uit file gehaald is moet toegekend worden aan char input[100] . En dan zit ik eigenlijk nog met het probleem van de groote van de char toekennen. Dat is nooit 100% proof dat die dan alles erin kan zetten

edit:
Code iets geweizgd. Geeft nu alle tokens gescheiden met een tab weer

[ Voor 26% gewijzigd door GF op 02-12-2002 12:53 ]


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
PommeFritz schreef op 02 december 2002 @ 01:56:
code:
1
2
3
4
int getal;
std::cin >> getal;
std::cin >> getal;
std::cin >> getal;

Dat was niet zo moeilijk ;) Hij skipt whitespace automatisch.
Heb ik niks aan in een WINAPI

edit:

Dit werk anders nooit bij mij

[ Voor 13% gewijzigd door GF op 02-12-2002 12:58 ]


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

-->curry684:
Als je blijft lezen van standard input, blockt ie natuurlijk als je nog een getal wilt lezen.
Als de input ophoudt (EOF) dan geeft ie geen exception (dat doet de iostream lib niet).
Je moet dan testen met std::cin.bad() of std::cin.eof() of er iets fout is gegaan of dat EOF bereikt is.
Oh enne.... ik waag te betwijfelen of mijn stukkie code trager is dan het stuk hierboven, als het gaat om inlezen van files.

[ Voor 2% gewijzigd door PommeFritz op 02-12-2002 02:18 . Reden: antwoord op curry684 ]

FireFox - neem het web in eigen hand


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

GF schreef op 02 December 2002 @ 02:12:
[...]

Heb ik niks aan in een WINAPI
Hoezo!??? :? Waarom zou je geen C++ standard library spul kunnen gebruiken in een windows app?

Als je al de beschikking hebt over een string waarin de inhoud van de file staat, dan kun je daaruit ook via ">>getal" de integers lezen, je moet er dan eerst een string stream van maken. Zie #include <strstream>

[ Voor 33% gewijzigd door PommeFritz op 02-12-2002 02:40 . Reden: strstream ]

FireFox - neem het web in eigen hand


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
PommeFritz schreef op 02 december 2002 @ 02:17:
Als je al de beschikking hebt over een string waarin de inhoud van de file staat, dan kun je daaruit ook via ">>getal" de integers lezen, je moet er dan eerst een string stream van maken. Zie #include <strstream>
Dat moet <sstream> zijn, voor std::istringstream.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Kom er niet uit hoe ik mijn input variabele die ik eerst al had opgegeven had kan binden aan de inhoud van een file. Dit had ik eerst:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
    char input[] = "3\n5  \n 12  17  33 44 45 73 74 76 88\t98 126";
    char *token;
    String temp;

    token = strtok(input, "  \n\t");

    while (token != NULL)
    {
        temp += String(token) +"\t";
        token = strtok(NULL," \n\t");
    }

    textFile3->Text = temp;


En nu heb ik er dit van gemaakt (ifstream e.d. staan ergens anders gedeclareerd)

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void __fastcall TForm1::merge(TObject *Sender)
{
    //opent 2 files en geeft terug of ze geopend zijn
    if(openFile(1) && openFile(2))
    {
        char tmp;
        char *contentFile1;

        //zet inhoud file in variabele
        while(inputFile1.get(tmp))
        {
            strcat(contentFile1, tmp);
        }

        int arrayLengthFile1, arrayLengthFile2;

        String temp;

        int countArrayLength(char *);
       
        /*tijdelijk test output. Moet komen te staan hoeveel tokens 
        zijn gevonden. Daar een array van maken met die lengte en dan 
        daarna word elke token in array gestopt. Dit voor beide files en 
        dan moet getal vergeleken worden etc...*/

        temp += String(countArrayLength(contentFile1));
        textFile3->Text = temp;
    }
    else
        error(0);
}

int countArrayLength(char *input)
{
    char *token = strtok(input, " \n\t");
    int count = 0;

    while(token != NULL)
    {
        count++;
        token = strtok(NULL," \n\t");
    }

    return count;
}


Alleen nu krijg ik de volgende error:

code:
1
2
Cannot convert 'int' to 'const char *'
mismatch in parameter '__src' (wanted 'const char *', got 'char')


Slaan beide op regel 10 en het is de bodoeling daar dat die elk nieuw character achteraan toevoegt aan een char "string".

Iemand een idee hoe dit wel kan??

[ Voor 40% gewijzigd door GF op 02-12-2002 15:01 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Volgens mij slaat het op regel 26, waar je een int aan die string constructor geeft. Verder valt het me op dat er zo veel rare/vage dingen gebeuren dat ik me afvraag of je uberhaupt enig idee hebt waar je mee bezig bent...:P Sorry bedoel het niet zo bot, maar...

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Op regel 26 is alleen een temp output of die wel goed aantal tokens telt. Dit is dus niet de fout! En kan mischien voor pro programmeur vaag zijn maar ben pas newbie. En als je iets vaag noemt zegt er dan ook bij wat.

Verwijderd

GF>> Als je nu eens de tips volgt en eens niet mensen gaan liggen dissen als jij het niet snapt?

PommeFritz heeft al duidelijk aangegeven hoe je integers inleest met whitespace-skipping, en die methode moet werken want je gebruikt een std::ifstream. Als het niet werkt ligt dat dus helemaal aan jou en niet aan iemand anders. Vervolgens helpen mensen je toch verder hoewel je al flink eigenwijs bent op dat moment en oplossingen verzint die compleet overbodig zijn; met als gevolg dat jij nog ontevredener/ongeduldiger wordt.

Dus: gebruik operator >> want die werkt gewoon. Als je niet weet hoe die werkt, kun je dat (liefst) opzoeken in een manual of anders hier vragen.

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Verwijderd schreef op 02 december 2002 @ 16:04:
GF>> Als je nu eens de tips volgt en eens niet mensen gaan liggen dissen als jij het niet snapt?
Ik zit dus niet te dissen. Dus als het zo overkomt mijn excuses. Wil alleen maar een goed werkende oplossing en ik kreeg dat dus niet werkend.

Verder kreeg ik die oplossing niet werkend net als ik nu heb omdat ik dat uitlezen en opslaan in een variabele niet wil werken.


Als ik btw een stringstream aanmaak krijg ik de error dat het een ongeldige structuur heeft. Heb ik alleen nog maar stringstream variabele; gedaan :? (en <strstream> is geinclude).

[ Voor 18% gewijzigd door GF op 02-12-2002 16:34 ]


Verwijderd

Voorbeeld
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <fstream>

const char *FNAME= "test.txt";

int main()
{
    std::ifstream s(FNAME);
    if(!s) return 1; // Stream error
    int getal;
    while(s >> getal) {
        std::cout << getal << std::endl;
    }
    return 0;
}

Dit leest alle getallen uit de file test.txt; ongeacht de whitespace die er tussen staat.

[ Voor 8% gewijzigd door Verwijderd op 02-12-2002 16:38 ]


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Als ik gewoon kant en klaar jouw code in een lege project gooi in cbuilder krijg ik dit als error:

code:
1
2
Build
  [C++ Error] Unit1.cpp(13): E2316 'cout' is not a member of 'std'


Dat krijg ik dus ook als ik die cout omwissel met aan variabele wat ik dus eerst met het voorbeeld van PommeFritz heb gedaan.

Verwijderd

Laat dan overal std:: weg. Dit betekent overigens wel dat je met een verouderde compiler aan het werken bent (streams horen in namespace std volgens de standaard).

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Heb compiler die bij borland 6 zit maar ik heb borland ff opnieuw geinstalled want ik had wel vaker probs met iostreams. En aangezien dat volgens jullie gewoon goed werkt :)

Anyway na opnieuw installen werkt het wel zodra ik de code verander in:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <fstream>
#include <iostream>

const char *FNAME= "file1.txt";
using namespace std;

int main()
{
    ifstream s(FNAME);
    if(!s) return 1; // Stream error
    int getal;
    while(s >> getal) {
        cout << getal << endl;
    }

     cin.get();

    return 0;
}


Dus 1 include meer, namespace std en cin.get() anders vliegt window meteen eruit :p

Zal eens ff wat proberen te bouwen met dit. Thnx!

Verwijderd

Mijn fout, op mijn systeem heb je die #include <iostream> niet nodig (omdat die al in fstream gedaan wordt).

Als je using namespace std; eruit sloopt moet mijn oorspronkelijke code weer werken (wel die include doen), het wordt algemeen als "niet netjes" gezien om de hele std namespace te usen (omdat het name-clashes kan opleveren).

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Heb nu alles werkend alleen toch niet helemaal zoals ik wil

Ik heb namelijk die cout vervangen door een ofstream. Schrijft dus alles weg in file. Als ie klaar is met het een en andere (vergelijking, sortering, merging etc.) dan sluit die de file en leest m'n memo veld alles uit die text veld. Dit vind ik nie zo erg netjes en weet zeker dat het ook zonder die file kan. Wat ik dus wil is dat alles in een string word opgeslagen en daarna in memo word gedropped. Alleen dat lukt me niet. Hoe moet ik dat doen? (en nee niet temp file maken, uitlezen en daarna deleten :D)

Thnx voor de moeite en bedankt voor zover!

[ Voor 6% gewijzigd door GF op 02-12-2002 21:52 ]


Verwijderd

Je kunt een stringstream net zo gebruiken als een stream, maar ook als een string
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <fstream>
#include <sstream> // Oudere compilers hebben strstream

const char *FNAME= "file1.txt";

int main()
{
    std::ostringstream str;
    std::ifstream s(FNAME);
    if(!s) return 1; // Stream error
    int getal;
    while(s >> getal) {
        str << getal << std::endl;
    }
    std::cout << str.str(); // Gebruik de stringrepresentatie
    return 0;
}

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Ik d8 altijd dat het stringstream ipv ostringstream was |(. Geen wonder dat die liep te zeuren over de waarde. Ga toch maar eens in help file snuffelen

Bedankt iig

Kan slotje op nu!

Verwijderd

Wacht nog ff ;)

Als je je eenmaal in de STL verdiept hoef je dit soort dingen niet meer te schrijven, het wordt simpelweg generics aanroepen:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <sstream> // Oudere compilers hebben strstream
#include <algorithm>
#include <iterator>

const char *FNAME= "file1.txt";

typedef int getal_type;

int main()
{
    std::ostringstream str;
    std::ifstream s(FNAME);
    if(!s) return 1; // Stream error

    std::copy(std::istream_iterator<getal_type>(s),
              std::istream_iterator<getal_type>(),
              std::ostream_iterator<getal_type>(str, "\n"));

    std::cout << str.str(); // Gebruik de stringrepresentatie
    return 0;
}

Dit doet exact het zelfde als de vorige versie...

[ Voor 8% gewijzigd door Verwijderd op 03-12-2002 00:13 . Reden: typo ]


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
vond 1e wat beter te begrijpen :D

Verwijderd

Maar als je constructies als die 2e eenmaal begrijpt is geen huis meer te hoog. Op de zelfde manier kun je getallen of wat dan ook in vectoren of ander collections inlezen; vervolgens sorteren, waardes verwijderen en noem maar op, en dat alles in een paar regels code (die er wel nogal ingewikkeld uitzien). Als je de STL eenmaal redelijk kent ga je op een hele andere manier denken over programmeren.

[ Voor 1% gewijzigd door Verwijderd op 03-12-2002 00:33 . Reden: damn typos :) ]


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
voorlopig ben ik igg nog niet zover. Ben net op school pas begonnen en daar hebben ze het alleen over console apps dus ben met winapi al wat verder bezig. Moet ook nog keer goed c++ boek kopen voor borland. Is ook wel handig ipv met dictaten werken |(

  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

Boek=goed. Maar ik zou dan geen Borland specifiek boek kopen. Zonde als je een andere compiler gaat gebruiken. Is het niet handiger om een compiler onafhankelijk boek te kopen die puur over de C++ taal of de STL gaat? Compilers komen wel met hun eigen manuals....

FireFox - neem het web in eigen hand


  • AaroN
  • Registratie: Februari 2001
  • Laatst online: 16-08-2023

AaroN

JayGTeam (213177)

Voor boeken zie hier:[rml][ RFC FAQ] Boeken in de FAQ[/rml]
Zelf vind ik het boek van Stroustrup erg goed, "The C++ Programming Language".

JayGTeam (213177)


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
GF schreef op 02 December 2002 @ 23:38:
Ik d8 altijd dat het stringstream ipv ostringstream was |(. Geen wonder dat die liep te zeuren over de waarde. Ga toch maar eens in help file snuffelen
stringstream is een combinatie van istringstream (input) en ostringstream (output), maar omdat je alleen tokens leest heb je geen output nodig, vandaar de i-variant.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

PommeFritz schreef op 03 december 2002 @ 17:44:
Boek=goed. Maar ik zou dan geen Borland specifiek boek kopen. Zonde als je een andere compiler gaat gebruiken. Is het niet handiger om een compiler onafhankelijk boek te kopen die puur over de C++ taal of de STL gaat? Compilers komen wel met hun eigen manuals....
Depends wat je met Borland doet... als je aan VCL wil zou ik wel een Borland specifiek boek pakken want daar leer je net zo goed C++ uit (Kent Reisdorph legt C++ knap goed en beknopt uit in z'n BCB-boeken).

Professionele website nodig?


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 00:27

mulder

ik spuug op het trottoir

oogjes open, snaveltjes dicht


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Ik denk dat ik The C++ Programming Language ga nemen. Schijnt erg goed boek te zijn. Daarnaast kan ik altijd nog borland boek er bij pakken :0

Thnx voor de tips iig!

  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
MSalters schreef op 03 december 2002 @ 19:24:
[...]
stringstream is een combinatie van istringstream (input) en ostringstream (output), maar omdat je alleen tokens leest heb je geen output nodig, vandaar de i-variant.
Omdat ik tokens lees en in een output variabele opsla is dit ostringstream en dus niet "de i-variant" (istringstream ) zoals jij zegt. Je hebt het omgedraaid

  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

GF schreef op 03 December 2002 @ 22:08:
Ik denk dat ik The C++ Programming Language ga nemen. Schijnt erg goed boek te zijn.
Goeie keus. Ik heb m ook.
Als je dan C++ geleerd hebt, en echt aan de slag wilt, is eigenlijk het boek The C++ Standard Library van Nicolai M. Josuttis ook een aanrader.
Daarin vind je alles wat je wilt weten over de C++ STL.

Op Amazon staan ze als "great buy" saampjes.... :P Kost een paar centen ($123) maar dan heb je ook wat. Beide zijn hardcovers trw.

FireFox - neem het web in eigen hand


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 12:58
PommeFritz schreef op 04 December 2002 @ 00:39:
Op Amazon staan ze als "great buy" saampjes.... :P Kost een paar centen ($123) maar dan heb je ook wat. Beide zijn hardcovers trw.
Even kort en off-topic over Amazon: voor zover ik heb gemerkt zijn die 'great buy's gewoon een combinatie van het gezochte boek met een willekeurig ander gerelateerd boek (waarschijnlijk op basis van wat andere kochten). Je krijgt er verder geen extra korting voor, noch is het een kwalificatie van de twee boeken in kwestie (het kunnen dus prima twee waardeloze boeken zijn; dit is trouwens ook persoonsafhankelijk). Het is maar dat je 't even weet. Denk dus goed na voordat je een extra boek bestelt dat Amazon toevallig bij 'best buy' weergeeft. Doe dat alleen als je dat boek toch al wilde bestellen (en niet een ander boek liever had) want er is geen enkel voordeel te behalven bij het bestellen van dat tweede boek ten opzichte van een ander.

Bedenk ook dat je bij het bestellen van hogere bedragen aan boeken (de grens ligt ergens tussen $100 en $200 vermoed ik, maar waar precies weet ik niet) opeens invoerbelasting over de gehele aanschaf moet betalen, waardoor het wellicht uit kan om in twee keer te bestellen (ipv 1 doosje met 2 boeken in een boot, krijg je dan 2 doosjes met elk 1 boek in dezelfde boot, en dat is dan netto goedkoper).

[ Voor 44% gewijzigd door Soultaker op 04-12-2002 02:10 ]


  • GF
  • Registratie: April 2002
  • Laatst online: 22-12-2025
Ik ga ze toch halen bij bruna denk ik of bestel ze bij bol.com. Net zo makkelijk ;)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
PommeFritz schreef op 04 December 2002 @ 00:39:
[...]
Goeie keus. Ik heb m ook.
Als je dan C++ geleerd hebt, en echt aan de slag wilt, is eigenlijk het boek The C++ Standard Library van Nicolai M. Josuttis ook een aanrader.
Daarin vind je alles wat je wilt weten over de C++ STL.
Niet dat dat boek slecht is, maar het is niet het STL boek, dat is Matt Austern's "Generic Programming and the STL".
drm, had je die al?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

MSalters--> dat boek ken ik niet... leg eens uit wat dat voor boek is dan?

FireFox - neem het web in eigen hand


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Matt Austern is de voorzitter van de Library Working Group van de ISO C++ commissie, en heeft bij SGI aan de STL gewerkt samen met Stepanov (bedenker van STL). Bij SGI heeft hij toen ook een complete STL website opgezet ( http://www.sgi.com/tech/stl/ ).
Uit die site heeft hij vervolgens een boek gehaald. Alleen beperkt hij zich in het boek niet tot de functies en types. Hij legt eerst de fundamentele concepten iterators, ranges, algortimes en containers uit, en hoe de STL met concepten omgaat.
Zelf heb ik de STL leren gebruiken uit een ander boek (naam alweer vergeten), maar door dit boek ben ik de STL echt gaan snappen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1