Advertentie:

Auteur Topic: tekstbestand inlezen  (gelezen 196 keer)

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
tekstbestand inlezen
« Gepost op: januari 09, 2012, 20:00:23 pm »
En weer eens een vraagje, (ik ga m'n record verbreken in een week tijd :P)

Ik wil dus weer eens een bestand inlezen, tekstbestand of niet maakt niet zo veel uit denk ik. Maar ik heb het volgende probleem:

Sommige dingen staan erin geschreven met spaties tussen, en daartussen nog eens tabs en veel spaties om er onderscheid in te kunnen maken. Dus het ziet er ongeveer zo uit:
test lol               test                   test 1234              12/13/12   

Hierbij is de bedoeling dat later test lol in één string komt, net zoals test 1234 in het programma één string moet voorstellen. Het probleem is dat dat doormiddel van deze code niet gaat omwille van de spaties tussen bijvoorbeeld test en 1234...
Code: C++
  1. ifstream file("test.txt)"
  2. while( ! file.eof())
  3. {
  4.     string temp;
  5.     file>>temp;
  6. }
  7.  

Hierbij worden dus test en 1234 in 2 aparte strings in gelezen. Dit moet één string worden, maar wanneer er meer dan 1 spatie staat moet er dus wel degelijk onderscheid tussen de strings gemaakt worden.

Bestaat er nog een andere mogelijkheid dit te doen zonder alles karakter per karakter in te lezen en te checken?

- Jonas.

Offline Divendo

  • Administrator
  • Zeer gerespecteerd lid
  • ********
  • Berichten: 2309
  • Voer in op google maps: 37.971458,23.726706
    • Divendo Webs
Re: tekstbestand inlezen
« Reactie #1 Gepost op: januari 09, 2012, 20:44:07 pm »
Je kan op tabs scheiden.
Code: C++
  1. list<string> strings;
  2. ifstream file("test.txt");
  3. string tmp;
  4. size_t pos;
  5.  
  6. while(file.good())
  7. {
  8.     getline(file, tmp, '\t');
  9.     // Aangenomen dat je bij newlines ook de strings wilt scheiden
  10.     if((pos = tmp.find('\n')) != string::npos)
  11.     {
  12.         strings.push_back(tmp.substr(0, pos));
  13.         strings.push_back(tmp.substr(pos + 1));
  14.     }
  15.     else
  16.         strings.push_back(tmp);
  17. }

Anders zul je inderdaad karakter per karakter uit moeten lezen!
Admin - http://divendo-webs.com
[C++][PHP][JavaScript][HTML][XML][CSS][SQL][Bash][GML][Nederlands][Engels][Latijn]

"Leren is proberen."

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #2 Gepost op: januari 09, 2012, 20:58:15 pm »
Het probleem is dat het ook niet een vast aantal tabs of spaties na elkaar is...Dus het kunnen ook tabs en spaties na elkaar zijn vrees ik. Enig idee hoe ik ook karakter per karakter kan uitlezen en controleren?

En ik probeer het wel even met de tabs hoor, ik weet gewoon niet zeker of het wel zal werken, daarom vraag ik het al. :)

edit:

ik ben even begonnen met het tekstbestand char per char in te lezen, maar blijkbaar worden spaties overgeslagen?
Ik heb dit even geschreven om te zien of spaties worden weergegeven als er wordt ingelezen:
Code: C++
  1.  
  2. #include <iostream>
  3. #include <string>
  4. #include <fstream>
  5.  
  6. using namespace std;
  7.  
  8. int main()
  9. {
  10.     ifstream file( "/Users/Jonas/Documents/test.txt");
  11.     if( file.is_open())
  12.     {
  13.         char ch;
  14.         cout<<endl<<"the file is open!";
  15.         while( ! file.eof())
  16.         {
  17.             file>>ch;
  18.             cout<<endl<<ch;
  19.         }
  20.  
  21.  
  22.     }
  23.     else if( ! file.is_open())
  24.     {
  25.         cout<<endl<<"the file isn't open...";
  26.     }
  27. }
  28.  

Hierbij worden alle karakters onder elkaar weergegeven, maar spaties staan er niet bij.

Hoe kan ik dan ooit controleren waar er spaties staan?
« Laatst bewerkt op: januari 11, 2012, 19:06:08 pm door jonas »

Offline Divendo

  • Administrator
  • Zeer gerespecteerd lid
  • ********
  • Berichten: 2309
  • Voer in op google maps: 37.971458,23.726706
    • Divendo Webs
Re: tekstbestand inlezen
« Reactie #3 Gepost op: januari 12, 2012, 15:20:09 pm »
Als je met de operator >> leest kan deze de invoer manipuleren.
Zoals bijvoorbeeld het omzetten naar een int.
Met de functie get() verkrijg je gewoon het volgende karakter, ongeacht wat dat is:
Code: C++
  1. char chr;
  2. file.get(chr);
Admin - http://divendo-webs.com
[C++][PHP][JavaScript][HTML][XML][CSS][SQL][Bash][GML][Nederlands][Engels][Latijn]

"Leren is proberen."

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #4 Gepost op: januari 12, 2012, 19:09:18 pm »
bedankt! :D

[opgelost]

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #5 Gepost op: januari 13, 2012, 17:03:45 pm »
Ik heb hier nu even mee zitten experimenteren, maar het lukt niet echt...

Ik weet wel hoe ik het wil aanpakken, maar de code lukt niet echt. Dit is hoe ik het zou willen aanpakken:
• Open file
• kijk naar een karakter
   - als dit een spatie is, begin dan opnieuw
       - is dit weer een spatie, begin dan een nieuwe string en steek de oude in een string vector
       - als het een karakter is, steek de spatie en de string dan in de string vector en begin opnieuw
   - als dit een ander karakter is buiten een spatie, put dit karakter dan in een string
• wanneer het file.eof() is, steek dan ook de laatste string in de vector.

Alleen weet ik niet zo goed hoe ik dit in C++ moet omzetten, ongetwijfeld zijn er een paar loops nodig, maar welke precies weet ik niet. Misschien zouden jullie me een eindje op weg kunnen helpen? :)

- Jonas

edit: Misschien handig om te zien wat ik al had;

Code: C++
  1. if( file.is_open())
  2.     {
  3.         char ch;
  4.         cout<<endl<<"the file is open!";
  5.         while( ! file.eof())
  6.         {
  7.             file.get(ch);
  8.  
  9.             if( ch == ' ')
  10.             {
  11.                 file.get(ch);
  12.                 if( ch == ' ')
  13.                 {
  14.                     strings.push_back( temp);
  15.                     temp.clear();
  16.                 }
  17.                 else
  18.                 {
  19.                     temp += ' ';
  20.                     temp += ch;
  21.                 }
  22.             }
  23.             else
  24.             {
  25.                 temp += ch;
  26.             }
  27.  
  28.         }

ch is hierbij een char die de karakters één voor één uit de file haalt, strings is de vector waarin de strings worden weggeschreven, en voor de rest lijkt me alles duidelijk. Als dat niet zo is mag je het altijd zeggen natuurlijk! :)
« Laatst bewerkt op: januari 13, 2012, 17:13:50 pm door jonas »

Offline Divendo

  • Administrator
  • Zeer gerespecteerd lid
  • ********
  • Berichten: 2309
  • Voer in op google maps: 37.971458,23.726706
    • Divendo Webs
Re: tekstbestand inlezen
« Reactie #6 Gepost op: januari 13, 2012, 17:38:50 pm »
Uit m'n hoofd, ik kan dus niet garanderen dat hij syntaxfout-loos is...
Code: C++
  1. //Ergens bovenin de code
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <cctype>
  6.  
  7. // Variabelen voor het verwerken v/d strings
  8. vector<string> strings;
  9. string buffer = "";
  10. char chr;
  11.  
  12. // Bestand openen
  13. ifstream file("bestand.txt");
  14. if(!file.good())
  15.     cerr<<"Fout bij het openen van het bestand!\n";
  16.  
  17. // Bestand uitlezen
  18. while(file.get(chr))
  19. {
  20.     if(chr == '\n' || (isspace(chr) && isspace(file.peek())) )  // Volgens mij ging het niet alleen om spaties maar om elk whitespace karakter (dus tabs e.d.)
  21.     {                                                           // Verder willen we altijd stoppen met de string als we een enter tegenkomen (ook dat dacht ik uit je post op te maken)
  22.         if(buffer != "")                                        // We willen alleen de uitgelezen string toevoegen als de buffer leeg is
  23.         {                                                       // Op die manier zorgen we dat als er meer dan 2 whitespaces achter elkaar staan ze allemaal overgeslagen worden
  24.             strings.push_back(buffer);
  25.             buffer = "";
  26.         }
  27.     }
  28.     else                                                        // Als het huidige karakter geen whitespace is, of het huidige karakter wel (een ander dan een newline) maar het volgende niet
  29.         buffer += chr;                                          // Dan voegen we het gewoon toe aan de buffer
  30. }
  31.  
  32. // Als de laatste string nog niet toegevoegd was doen we dat nu nog even
  33. if(buffer != "")
  34.     strings.push_back(buffer);
  35.  
  36. // Controleer of we wel gestopt zijn met lezen vanwege een legitieme reden
  37. if(file.bad() || file.fail())
  38.     cerr<<"Er ging iets fout tijdens het uitlezen van het bestand!\n";
  39.  
  40. // Sluit het bestand
  41. file.close();
Admin - http://divendo-webs.com
[C++][PHP][JavaScript][HTML][XML][CSS][SQL][Bash][GML][Nederlands][Engels][Latijn]

"Leren is proberen."

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #7 Gepost op: januari 13, 2012, 17:54:21 pm »
Ik heb even moeten zoeken waarvoor peek en isspace (tamelijk logisch xD ) stonden, maar nu ik weet hoe het werkt lijkt het me wel duidelijk.

Ik probeer het zometeen :).

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #8 Gepost op: januari 25, 2012, 18:24:10 pm »
Ik ben er eindelijk eens aan toe gekomen om het te proberen, en het werkt! Grotendeels toch, alleen wordt bij het bestand alleen de eerste string goed ingelezen, de volgende strings staan met een spatie ervoor...

Vermoedelijk doordat er nog een spatie in buffer zit voordat die opgeslagen wordt in de vector...Alleen, hoe kan ik dit oplossen?

Dit is de code die ik nu heb: Grotendeels "ge-copy-paste" xD
Code: C++
  1. #include <fstream>
  2. #include <string>
  3. #include <vector>
  4. #include <cctype>
  5. #include <iostream>
  6.  
  7. using namespace std;
  8.  
  9.  
  10. int main()
  11. {
  12.     // Variabelen voor het verwerken v/d strings
  13.     vector<string> strings;
  14.     string buffer = "";
  15.     char chr;
  16.  
  17.     // Bestand openen
  18.     ifstream file("/Users/Jonas/Documents/test.txt");
  19.     if(!file.good())
  20.     {
  21.         cerr<<"Fout bij het openen van het bestand!\n";
  22.     }
  23.     // Bestand uitlezen
  24.     while(file.get(chr))
  25.     {
  26.         if(chr == '\n' || (isspace(chr) && isspace(file.peek())) )  // Volgens mij ging het niet alleen om spaties maar om elk whitespace karakter (dus tabs e.d.)
  27.         {                                                           // Verder willen we altijd stoppen met de string als we een enter tegenkomen (ook dat dacht ik uit je post op te maken)
  28.             if(buffer != "")                                        // We willen alleen de uitgelezen string toevoegen als de buffer leeg is
  29.             {                                                       // Op die manier zorgen we dat als er meer dan 2 whitespaces achter elkaar staan ze allemaal overgeslagen worden
  30.                 strings.push_back(buffer);
  31.                 buffer = "";
  32.             }
  33.         }
  34.         else                                                        // Als het huidige karakter geen whitespace is, of het huidige karakter wel (een ander dan een newline) maar het volgende niet
  35.             buffer += chr;                                          // Dan voegen we het gewoon toe aan de buffer
  36.     }
  37.  
  38.     // Als de laatste string nog niet toegevoegd was doen we dat nu nog even
  39.     if(buffer != "")
  40.         strings.push_back(buffer);
  41.  
  42.     // Controleer of we wel gestopt zijn met lezen vanwege een legitieme reden
  43.     if(file.bad() || file.fail())
  44.         cerr<<"Er ging iets fout tijdens het uitlezen van het bestand!\n";
  45.  
  46.     // Sluit het bestand
  47.     file.close();
  48.  
  49.     for( vector<string>::iterator it = strings.begin() ; it != strings.end() ; ++it)
  50.     {
  51.         cout<<endl<<*it;
  52.     }
  53. }
  54.  

Maar er wordt toch al gecontroleerd op spaties in buffer?

- Jonas

Offline Divendo

  • Administrator
  • Zeer gerespecteerd lid
  • ********
  • Berichten: 2309
  • Voer in op google maps: 37.971458,23.726706
    • Divendo Webs
Re: tekstbestand inlezen
« Reactie #9 Gepost op: januari 26, 2012, 15:04:54 pm »
Oeps, ik zie de fout al. Zat inderdaad in mijn code.
Het was dan ook even snel uit m'n hoofd en niet getest :P

Ik zal je de fout geven, dan kun je zelf kijken of je met een oplossing kan komen.
Wat er fout gaat is dat als hij een whitespace vindt, en het volgende karakter is geen whitespace dan voegt hij het karakter toe.
Dit is om te voorkomen dat enkele spaties weg gegooid worden.
Nou is het probleem dat als hij een spatie vindt en daarna een nieuwe string start, hij dus ziet dat er na de spatie geen whitespace staat en dus het karakter toevoegt.

De oplossing is vrij simpel, maar als oefening wilde ik eerst even kijken of je er zelf op kan komen ;)
Er is ook niks aan als al je code je voorgekauwd wordt.
Admin - http://divendo-webs.com
[C++][PHP][JavaScript][HTML][XML][CSS][SQL][Bash][GML][Nederlands][Engels][Latijn]

"Leren is proberen."

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #10 Gepost op: januari 26, 2012, 17:05:32 pm »
Volgens mij zit de fout op regel 35. Daar wordt - als de buffer niet leeg is - chr in de buffer gestoken. Maar als die buffer nu alleen een spatie bevat, dan zal die de volgende keer (als de loop wordt herhaald) gewoon de buffer in de vector stoppen, en daardoor zal er ook een spatie voor de string staan.

Alleen weet ik zo niet direct wat ik eraan kan doen...Ik zou het eerste karakter uit de strings kunnen verwijderen, maar bij de eerste string wordt er geen spatie getoond, dus dat is niet echt een optie...

Offline Divendo

  • Administrator
  • Zeer gerespecteerd lid
  • ********
  • Berichten: 2309
  • Voer in op google maps: 37.971458,23.726706
    • Divendo Webs
Re: tekstbestand inlezen
« Reactie #11 Gepost op: januari 27, 2012, 15:12:06 pm »
Alleen weet ik zo niet direct wat ik eraan kan doen...Ik zou het eerste karakter uit de strings kunnen verwijderen, maar bij de eerste string wordt er geen spatie getoond, dus dat is niet echt een optie...
Don't see the problem?
Code: C++
  1. if(isspace(buffer[0]))
  2.     buffer = buffer.substr(1);
Admin - http://divendo-webs.com
[C++][PHP][JavaScript][HTML][XML][CSS][SQL][Bash][GML][Nederlands][Engels][Latijn]

"Leren is proberen."

Online jonas

  • Ervaren lid
  • ******
  • Berichten: 726
Re: tekstbestand inlezen
« Reactie #12 Gepost op: januari 27, 2012, 17:56:32 pm »
Even helemaal vergeten dat je een string ook kunt gebruiken op de manier dat je de elementen uit een array wil halen...Je ziet het eraan dat ik al een tijdje niet actief bezig ben met C++...

Toch bedankt!

Advertentie: