Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Čitanje INI datoteke

[es] :: C/C++ programiranje :: Čitanje INI datoteke

[ Pregleda: 2890 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

adnanK
Sarajevo

Član broj: 146055
Poruke: 31
*.bbone.utic.net.ba.



Profil

icon Čitanje INI datoteke14.07.2008. u 11:06 - pre 162 meseci
Dakle, imam fajle iz kojih trebam pročitati podatke. U njima su zapisane koordinate tačaka, a imaju i header koji me ne interesuje. Dva primjera:

1)

[Version]
VersionLevel=4

[Konturs]
KonturCnt=1

[Kontur0]
PtCnt=450
Pt0=672.000 2661.000
Pt1=725.000 2651.000
Pt2=775.000 2636.000
Pt3=811.000 2632.000
Pt4=817.000 2624.000


2)

[Version]
VersionLevel=4

[Konturs]
KonturCnt=1

[Kontur0]
PtCnt=494
Pt0=505.000 2716.000
Pt1=554.000 2681.000
Pt2=589.000 2664.000
Pt3=648.000 2617.000
Pt4=648.000 2557.000


Dakle, ja sad trebam pročitati prvo koji je broj poslije "PtCnt=" i to smjestiti u varijablu "count" tipa integer, a zatim čitati koordinate jedne po jedne tačke (označene sa "Pt*=") i smještati ih u varijable "X" i "Y" tipa double (u svakom prolazu vrijednost ovih varijabli će se mijenjati). Kako ovo da uradim? Hvala
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4890
*.tekostolac.co.yu.

Jabber: xfiles@elitesecurity.org


+633 Profil

icon Re: Čitanje INI datoteke14.07.2008. u 11:35 - pre 162 meseci
Fajl koji si prikazao i u kome se cuvaju podaci o koordinatama i broju tih koordinata - je klasicana INI datoteka.

Borland C++ Builder raspolaze vrlo upotrebljivom klasom TIniFile za baratanje INI datotekama i ima sve potrebne metode za iscitavanje vrednosti.

Pokusacu da ti dam i neki primer, samo moras prethodno reci da li ces koristiti TIniFile, odnosno moguce resenje u okvirima VCL biblioteke klasa (u prethodnom postu si koristio neka genericka resenja, pa nisam siguran)?
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4890
*.tekostolac.co.yu.

Jabber: xfiles@elitesecurity.org


+633 Profil

icon Re: Čitanje INI datoteke14.07.2008. u 11:56 - pre 162 meseci
Pod pretpostavkom da se INI fajl nalazi gde i EXE i da se zove config.ini

// NETESTIRANO
Code:

// ...
#include "IniFiles.hpp"
#include "StrUtils.hpp"
// ...
int count;
double x,y;
// ...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   TIniFile *pIniFile = NULL;

   try
   {
      AnsiString Fajl = ExtractFilePath( ParamStr(0) ) + "config.ini";

      if ( FileExists( Fajl ) )
      {
         pIniFile = new TIniFile( Fajl );

         count = pIniFile->ReadInteger("Kontur0", "PtCnt", 0 );
         for ( int i=0; i<count; i++ )
         {
            AnsiString Temp = pIniFile->ReadString( "Kontur0", AnsiString( "Pt" + IntToStr(i) ), "" );
            if ( Temp != "" )
            {
               int Blanko = AnsiPos( " ", Temp );
               if ( Blanko != 0 )
               {
                  AnsiString X = LeftStr( Temp, Blanko-1 );
                  AnsiString Y = RightStr( Temp, Temp.Length()-Blanko);
                  try
                  {
                     x = StrToFloat( X );
                     y = StrToFloat( Y );

                     // *************
                     // OVDE TVOJ KOD
                     // *************
                  }
                  catch ( const Exception &e )
                  {
                     ShowMessage( e.Message );
                  }
               }
            }
         }
      }
      else
      {
         ShowMessage( "Datoteka: " + Fajl + " ne postoji!");
      }
   }
   catch ( const Exception &e )
   {
      ShowMessage( e.Message );
   }
   if ( pIniFile )
      delete pIniFile;
}


Inace, na osnovu INI fajla zakljucujem da moze da bude vise KONTUR sekcija. Taj slicaj obradjujes slicno kao i ovo sto je prikazano.
 
Odgovor na temu

adnanK
Sarajevo

Član broj: 146055
Poruke: 31
*.bbone.utic.net.ba.



Profil

icon Re: Čitanje INI datoteke14.07.2008. u 13:58 - pre 162 meseci
Hvala ti sto si se potrudio, ali nazalost ne mogu koristiti compiler dependant biblioteke (stoga ni VCL), nazalost. Ja pokusavam nesto sa fscanf, ali mi bas i ne ide.

Code:

   FILE *in;
   in = fopen ("test.SAV","r");

   if(in!=NULL)
   {
      int x, y;
      int i=0;
      char str [80]=" ";

      while(strcmp(str,"Pt0")) // da preskocim header
      {
         fscanf (in, "%s", str);
         fscanf (in, "%d", &i);
      }

      while(!feof(in))
      {
         fscanf (in, "%d", &x);
         fscanf (in, "%d", &y);
         /* ovdje sad koristim x i y */

       }



Gledajuci duzinu tvog koda cini mi se da moj i ne moze raditi

Jos jedna stvar je da mi ne treba niti desetak linija na kraju fajle, pa pretpostavljam da uslov !feof(in) u drugoj while petlji nije dobar. Neki prijedlog i za ovo?
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4890
*.dynamic.sbb.rs.

Jabber: xfiles@elitesecurity.org


+633 Profil

icon Re: Čitanje INI datoteke14.07.2008. u 18:27 - pre 162 meseci
1. Da li u toj INI datoteci moze da se nadje vise KonturX sekcija, jer zamisljena struktura to dozvoljava.

Primer:

[Konturs]
KonturCnt=3

[Kontur0]
PtCnt=2
Pt0=505.000 2716.000
Pt1=554.000 2681.000

[Kontur1]
PtCnt=4
Pt0=505.000 2716.000
Pt1=554.000 2681.000
Pt2=589.000 2664.000
Pt3=648.000 2617.000

[Kontur2]
PtCnt=3
Pt0=505.000 2716.000
Pt1=554.000 2681.000
Pt2=589.000 2664.000


2. Da li smes da koristis STL biblioteku, ona nije comiler dependant? Vidim da si za pristup koristio ciste C funkcije pa zato pitam.

Parsovanje ovakve strukture nije tesko, samo da se znaju odgovori na gore postavljena pitanja. Ovde mozes pogledati kako da zapocnes citanje fajla red po red, sve to redom pakujes u vektor stingova, i kasnije biras sta ces sa redovima (brises, koristis i sl).

EDIT:

3. Da li stavke Pt0, Pt1 itd, mogu da se nadju u proizvoljnom (izmesanom) redosledu u INI fajlu, sto jeste moguce u klasicnoj INI strukturi ?

[Ovu poruku je menjao X Files dana 14.07.2008. u 20:18 GMT+1]
 
Odgovor na temu

adnanK
Sarajevo

Član broj: 146055
Poruke: 31
*.bbone.utic.net.ba.



Profil

icon Re: Čitanje INI datoteke15.07.2008. u 10:56 - pre 162 meseci
1. Moze da se nadje vise kontura u fajli
2. Mogu koristiti STL
3. Mislim da su tacke uvijek poredane

Imam neko rjesenje, iako mi se ne svidja bas pretjerano:

Code:

   FILE *in;
   in = fopen (F,"r");

   if(in!=NULL)
   {
      int i=0, u=0; // i - broj tacaka
      char str [80]=" ";

/* Ovdje sam rucno postavio da mi se petlja vrti 35 puta jer znam da imam toliko kontura,
tako da nisam rijesio kako da ih automatski citam (nigdje u fajli nije naveden broj kontura).
Dobra stvar je sto konture uvijek pocinju oznakom PtCnt=# gdje je # broj tacaka koje se
nalaze u njoj, pa se to moze iskoristiti ali nisam siguran kako :( */

      while(u!=35)
      {  
         u++ ;
         
         /* Trazim PtCnt */
         while(strncmp(str,"PtCnt",5))
         {
            fgets (str, 80, in);
         }
         sscanf(str + 6, "%d", &i);   // i - broj tacaka


      /* citamo liniju po liniju kad smo vec dosli do Pt#=, izdvajamo koordinate */
         for( int j = 0; j < i; j++)
         {
            int xf, yf;
            fgets (str, 80, in);
            string str_pravi(str);
            sscanf(str + str_pravi.find("=",0) + 1 , "%d", &xf);
            sscanf(str + str_pravi.find(" ",0) + 1, "%d", &yf);
            // koristim xf i yf            
         }
      }

      fclose(in);
   }


Problem sa ovim jeste ako se struktura fajle imalo promijeni, funkcija vise nece citati. Drugi problem je sto ne mogu ucitati sve konture.
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4890
*.tekostolac.co.yu.

Jabber: xfiles@elitesecurity.org


+633 Profil

icon Re: Čitanje INI datoteke15.07.2008. u 12:04 - pre 162 meseci
Citat:

Problem sa ovim jeste ako se struktura fajle imalo promijeni, funkcija vise nece citati.

INI struktura ima precizno definisanu formu, upravo iz razloga da bi citanje i upisivanje iz razlicitih programa bilo 100% kompatibilno. Drugim recima, potrebno je promeniti algoritam koji si koristio, a pre svega razmisliti o interfejsu za koriscenje, tj o nekoj klasi koja bi imala metode slicne TIniFile klasa.

Eto na primer, prototip jedne metode (ili eventualno samo funkcije) bi mogao biti:
string ReadString( const string SEKCIJA, const string KLJUC, const string DEFAULT_VREDNOST );

Citat:

Drugi problem je sto ne mogu ucitati sve konture.

Dakle, i ovo treba predvideti... upravo zato sam i pominjao redizajn.

(Sad sam trenutno u guzvi, ako budem imao vremena pomoci cu ti da barem zapocnes)
 
Odgovor na temu

idb
Ivan Bulic
Beograd

Član broj: 4436
Poruke: 402



Profil

icon Re: Čitanje INI datoteke15.07.2008. u 13:43 - pre 162 meseci
Mislim da ti treba nesto ovako:
1. Treba da iscitas vise izlomljenih linija cije su tacke (x0,y0), (x1,y1), (x2,y2), ..., (xi,yi), ...
- Tacku mozes da napravis kao klasu ili structuru (MyPoint)
- Izlomljenu liniju mozes da napravis kao klasu (MyPolyLine) koja ima svoj ID i niz tacaka (srd::vector)
2. Fajl citaj liniju po liniju
Napravi tokenizer f-ju (samostalno ili iskoristi http://www.rosettacode.org/wiki/Tokenizing_A_String ) kojom ces procitati tokene u liniji.
Kad naidjes na token "PtCnt" (iz naprimer linje "PtCnt=450") - ti kreiraj novu promenljuvu tipa <MyPolyLine> ciji je ID = atoi("450") (drugi token iz linije)
Citaj dalje linije i dobijas tokene npr: "Pt0", "672.000", "2661.000".
- Ako su prva dva znaka prvog tokena "Pt" dodaj novu kordinatu u vektor ...

Radio sam nesto slicno pa cu ti malo kasnije dostaviti prilagodjen kood.

idb
 
Odgovor na temu

idb
Ivan Bulic
Beograd

Član broj: 4436
Poruke: 402



Profil

icon Re: Čitanje INI datoteke15.07.2008. u 14:27 - pre 162 meseci
Code:
// file: nove_klase.h
#ifndef NOVE_KLASE_H_INCLUDED
#define NOVE_KLASE_H_INCLUDED
#include <vector>
#include <string>

// Pojednostavljene verzije klasa ....
class Point {
  //private:      // u cilju pojednostavljenja
  public:
    double x;   // moses ih kasnije staviti u private
    double y;   // ako napravis inspector i mutator member functions
    Point(const double& xx=0.0, const double& yy=0.0):x(xx), y(yy){}
    Point(const Point& p);
    ~Point(){}
};

class PolyLine {
  //private:      // opet pojednostavljenje
  public:
    int id;
    std::vector<Point> mPoint;
    PolyLine(const int& i):id(i){}
    ~PolyLine();
    void AddPoint(const double& x, const double& y);
};

// Default delimiteri su "=" i " "
int MyTokenizer(const std::string& str, std::vector<std::string>& tokens, const std::string& delims="= ");

#endif // NOVE_KLASE_H_INCLUDED
// end of file: nove_klase.h



Code:
// file: nove_klase.cpp
#include <iostream>
#include "nove_klase.h"
Point::Point(const Point& p){
    x = p.x;
    y = p.y;
}
void PolyLine::AddPoint(const double& x, const double& y){
    mPoint.push_back( Point(x,y) );
}

PolyLine::~PolyLine(){
    if (!mPoint.empty()) mPoint.clear();
}

int MyTokenizer(const std::string& str, std::vector<std::string>& tokens, const std::string& delims) {
    /*
    modifikovana verzija orginala:
    http://www.rosettacode.org/wiki/Tokenizing_A_String#C.2B.2B
    */
    using namespace std;
    string::size_type lastPos = str.find_first_not_of(delims, 0);
    string::size_type pos     = str.find_first_of(delims, lastPos);
    size_t count(0);
    while ( (string::npos != pos || string::npos != lastPos) && count<3 ) {
      tokens[count] = str.substr(lastPos, pos - lastPos);
      lastPos       = str.find_first_not_of(delims, pos);
      pos           = str.find_first_of(delims, lastPos);
      count++;
    }
    if ( tokens[0].compare("PtCnt") == 0 ) return 0;   // pocetak nove PoluLine
    else if (tokens[0].substr(0,2).compare("Pt")==0) return 1; // nova tacka u PoluLine
    else return -1;
}
// end of file: nove_klase.cpp


Nacin uptrebe:
Code:
// file: program.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include "nove_klase.h"
using namespace std;

int main() {
    int odgovor;
    vector<PolyLine> mPolyLine;
    vector<string> token(3,"");
    string line, delims = "= ";

    ifstream in_file ("test.txt");
    if (in_file.is_open()) {
        while (! in_file.eof() ) {
            getline (in_file,line);
            odgovor = MyTokenizer(line, token, delims);
            if (odgovor==0)
                mPolyLine.push_back( PolyLine( atoi(token[1].c_str()) ) );
            else if (odgovor==1)
                mPolyLine[mPolyLine.size()-1].AddPoint( atof(token[1].c_str()), atof(token[2].c_str()) );
            // Ocisti tokene
            for (size_t t=0;t<token.size(); t++) token[t].clear();
        }
        in_file.close();
    }
    // Sada kad imas Konture kao objekte - mozes sa njima raditi sta hoces!
    for (size_t p=0; p<mPolyLine.size(); p++) {
        cout << "ID Konture = " << mPolyLine[p].id << endl;
        for (size_t t=0; t<mPolyLine[p].mPoint.size(); t++) {
            cout << "  (" << mPolyLine[p].mPoint[t].x << ", " << mPolyLine[p].mPoint[t].y << ")\n";
        }
    }
    return 0;
}
// end of file: program.cpp


Test podaci (fajla "test.txt") - nije orginal, ali po tvojoj prici izgleda priblizno ovako:
Code:

[Version]
VersionLevel=4

[Konturs]
KonturCnt=1

[Kontur0]
PtCnt=450
Pt0=672.000 2661.000
Pt1=725.000 2651.000
Pt2=775.000 2636.000
Pt3=811.000 2632.000
Pt4=817.000 2624.000

[Version]
VersionLevel=4

[Konturs]
KonturCnt=1

[Kontur0]
PtCnt=494
Pt0=505.000 2716.000
Pt1=554.000 2681.000
Pt2=589.000 2664.000
Pt3=648.000 2617.000
Pt4=648.000 2557.000


idb
 
Odgovor na temu

adnanK
Sarajevo

Član broj: 146055
Poruke: 31
*.bbone.utic.net.ba.



Profil

icon Re: Čitanje INI datoteke17.07.2008. u 10:47 - pre 162 meseci
Extra. Hvala svima na odgovorima. Gotovo je sve rijeseno sa onim kodom sto sam poslao u proslom postu. Imam jos jedno pitanjce. Imam ovaj kod koji mi nadje liniju koja pocinje sa "PtCnt":

Code:

         while(strncmp(str,"PtCnt",5))
         {
            fgets (str, 80, in);
         }
         sscanf(str + 6, "%d", &i);


Interesuje me mogu li se sad "vratiti" jednu liniju unazad jer mi treba i jedan podatak iz prethodne linije?
 
Odgovor na temu

[es] :: C/C++ programiranje :: Čitanje INI datoteke

[ Pregleda: 2890 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.