teile einer "*.ini" auslesen?



  • Hi mal wieder

    Ich habe eine ini-datei in der mehrere Sectionen sind und aus diesen habe ich jeweils eine zeile ausgelesen die dann zur auswahl in einem dropdownlist stehen.
    So sieht das aus:

    #define _MAX_AC_NAME 100
    CString strSection, strKey, strIniFile, strName;
    const int nSize = 26000;
    TCHAR ptszSections [nSize];

    CComboBox* pCBox = (CComboBox*)GetDlgItem(IDC_AIRCRAFT);

    strIniFile = _T("c:\\data.ini");

    GetPrivateProfileSectionNames(ptszSections,
    nSize,
    strIniFile);

    int nIndex = 0;
    do {

    AfxExtractSubString(strSection,
    ptszSections,
    nIndex,
    _T('\0'));
    nIndex++;
    if (!strSection.IsEmpty()){
    strKey = _T("Name");
    GetPrivateProfileString(strSection,
    strKey,
    _T(""),
    strName.GetBufferSetLength(_MAX_AC_NAME),
    _MAX_AC_NAME,
    strIniFile);
    strName.ReleaseBuffer();
    if (!strName.IsEmpty()){
    pCBox->AddString(strName);

    }
    }
    }while (!strSection.IsEmpty());

    So und nun möchte ich das wenn in der dropdownlist eine auswahl getroffen wird anhand dieser auswahl,die ja aus dem ini-file kommt,die werte die mit in der sektion stehen wo auch der name steht auslesen und mit diesen werten soll dann gerechnet werden.
    so hole ich mir die auswahl:

    CComboBox * pCB = (CComboBox 😉 GetDlgItem ( IDC_AIRCRAFT ) ;
    int aircraft_no = pCB -> GetCurSel () ;

    CString aircraft ;

    if ( aircraft_no >= 0 )
    pCB -> GetLBText( aircraft_no , aircraft ) ;

    CString strSection, strKey, strIniFile, strName;
    const int nSize = 260;
    TCHAR ptszSections [nSize];
    if (strIniFile = _T("c:\\data.ini") && GetPrivateProfileSectionNames(ptszSections,nSize,strIniFile) != aircraft)

    Ich hoffe ihr könnt mir helfen.

    MfG Nico



  • Mal abgesehen davon das der Text sehr schwer zu lesen ist (für den Quelltext helfen code Tags weiter) sehe ich da keine Frage.

    Nur irgendwelche Codefragmente die mir nichts sagen.
    Kein Aufbau der Ini Datei
    Keine Frage

    Bitte mach Dir um das problem was du hast noch einmal gedanekn das man als Problemfremder die sache nachvollziehen kann.

    thx

    Knuddlbaer



  • ok also das ini-file sieht so aus:

    [AIRCRAFT1]
    Name=ATR-72
    Wert1=6354
    Wert2=947
    Wert3=85

    [AIRCRAFT2]
    Name=B737-400
    Wert1=7546
    Wert2=820
    Wert3=25

    usw.

    So und zu den "Codefragmenten":
    Der erste Teil des Codes steht in "::OnInitDialog()" und deamit hole ich mir den Bereich "Name" aus jeder Section der "data.ini" und schreibe diese in eine Dropdownlist meines Dialoges (hoffe das jetzt besser verständlich gemacht zu haben)!
    So und nun möchte ich das wenn ich in der Dropdownlist etwas auswähle (sprich einen der eingelesenen Namen) die zu dem Name gehörenden Werte (1,2,3) einlese und diese an eine Rechenformel übergebe. Der 2. Teil des Codes den ich gepostet habe soll feststellen welche auswahl getroffen wurde und diese im ini-file suchen und nun möchte ich halt wenn er den name gefunden hat das er die 3 darunterstehenden werte einliest sodas ich damit rechnen kann.

    Hoffe das es jetzt verständlich ist.

    MfG Nico

    [ Dieser Beitrag wurde am 24.09.2002 um 13:58 Uhr von nicolaus editiert. ]



  • Aaaaaahhhhhh jetzt ja 🤡

    Du hast ja den "Namen" bereits. Also wäre mein Vorschlag in einer Schleife so lange hoch zu zählen bis kein Wert mehr gelesen wurde.

    Ich habe keine Ahnung von dem MFC und dem VC++ (totaler noob der sich damit abquälen muß) aber die STL bietet dafür etwas an.

    Als "Beispiel" einer möglichen lösung:

    // test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include <Afx.h>
    #include "stdafx.h"
    #include <vector>
    #include <sstream>
    #include <afxtempl.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    std::vector<long> werte; // Hier halte ich die Werte fest
    std::stringstream sstream; // Hilfsobject für das zusammensetzen für Zahlen
    long i = 1;             // 
    long t = 1;
    char * temp = new char[USHRT_MAX]; //  Speicher in dem GetProfileString schreiben kann (geht hier auch nen CString direckt ?
    
    unsigned short  tempsize = USHRT_MAX;
      sstream<<"Wert"; // Eventuell muß eindeutig nach char * Konvertiert werden
      sstream<<i;
    
      while(GetPrivateProfileString("AIRCRAFT1",sstream.str().c_str(),"",temp,tempsize,"t:\\IniFileName.ini") > 0)
      {
        sstream.str(""); // Den Stream löschen
        sstream.clear(); // Und eventuelle Fehlbits löschen
        sstream<<temp;   // Das eingelesene in den Stream schreiben
        sstream>>t;      // und ohne(!) prüfen in die Variable t schreiben
        werte.push_back(t); // Diese in den Vector aufnehmen für späteres berechnen
        sstream.str(""); // Stream erneut löschen
        sstream.clear(); // siehe oben
        sstream<<"Wert"; // Eventuell muß eindeutig nach char * Konvertiert werden
        sstream<<++i;    // den WertX neu erstellen
      }
      delete[] temp;     // Hilfsspeicher löschen
    
    // Als weiteres Beispiel mal alle Werte aufaddieren
        long endwert = 0;
        for(unsigned long i = 0; i < werte.size()    ; i++)
            endwert += werte[i];
    
        return 0;
    }
    

    [ Dieser Beitrag wurde am 24.09.2002 um 14:37 Uhr von Knuddlbaer editiert. ]



  • Mööp,

    man kann sich den KeyNamens-String auch mit CString bauen :

    CString KeyName;
    KeyName.Format("%s%d","Wert",i);

    Ich warte jetzt mal auf die MFC Spezies die mir den Weg zeigen wie man es unter reinem VC Code erzeugt.



  • Hallo !

    Warum schreibst du nicht "ATR-72" und "B737-400" usw. als Section ?
    Also ungefähr so:

    [ATR-72]
    Wert1=6354
    Wert2=947
    Wert3=85

    [B737-400]
    Wert1=7546
    Wert2=820
    Wert3=25

    Dann direkt mit GetPrivateProfileSectionNames(..) alle Sections auslesen und direkt in der Liste anzeigen. Und wenn etwas ausgewählt wird mit GetPrivateProfileString(...) die Werte Wert1, Wert2 und Wert3 der entsprechenden Section (=der Auswahl) auslesen.
    Also: nach einer Auswahl steht also die Section fest. Dann dreimal hintereinander GetPrivateProfileString(...) und Wert1 bis Wert3 auslesen.

    So würde ich es machen. Keine Ahnung, ob das nun eine tolle oder schlechte Lösung ist...

    Tschüss



  • Ich denke irgendwie zu Kompliziert 🤡

    Natürlich kannst Du auch, wenn Du immer nur die drei Werte hast, drei mal GetPrivateProfileString aufrufen , dann brauchst den ganzen Käse nicht da oben.

    Ich bin davon ausgegangen das es da x werte zu geben kann.



  • Den hier gibt es ja auch noch (fällt mir gerade ein):

    DWORD GetPrivateProfileSection(
      LPCTSTR lpAppName,        // address of section name
      LPTSTR lpReturnedString,  // address of return buffer
      DWORD nSize,              // size of return buffer
      LPCTSTR lpFileName        // address of initialization filename
    );
    

    Der gibt dann ALLE Schlüssel und Werte einer bestimmten Section zurück (ist wohl noch besser, als dreimal GetPrivateProfileString(...)).



  • Da muß man aber wieder Strings parsen.
    Ich als Fauler Mensch finde da copy and paste mit dem ändern von 1 - 3 komfortabler 🙂



  • @isabeau

    Da habe ich ja auch schon drann gedacht doch is das prob das der "Name" den ich habe ja in einer section steht und nicht die bezeichnung der section selber ist. Ich muß ja anhand des namens den rest der section in dem der Name ist auslesen.

    Nico



  • @isabeau

    ups hatte dein post weiter oben übersehen is natürlich ne lösung und wird wohl die einfachste sein wenn ich das ini umbaue so das ich die namen auch gleich als section habe.

    Nicc



  • Hmmm....

    Bereitet es nach den Informationen noch Probleme ?

    Wenn ja bitte noch mal erläutern wo das Problem ist.



  • ok ich versuche jetzt erst mal das einlesen und schreiben der namen so umzubauen das die section selber im dropdown dargestellt wird wobei das etwas dauern kann da ich noch nich all zu lang mit MFC arbeite.
    Ich melde mich aber sobald etwas nich ganz klar ist.

    Danke euch beiden erst mal für die hilfe (brauch sicher noch mal welche :-))

    MfG Nico



  • habe jetzt doch noch ein prob ich bekomme das jetzt nich hin das die Section direkt auslesen und in die Dropdownlist schreiben kann.
    Kann mir da mal noch einer bitte helfen?
    Danke schon mal

    MfG Nico



  • Hi !

    Wenn du willst kann ich dir meine INI Class zuschicken.
    Mail mir wenn du Interesse hast ! johannes.leimbach@gmx.de



  • Die Sektionen die Du zurück bekommst sind durch Nullzeichen getrennt.
    Das ende wird durch ein doppeltes Nullzeichen getrennt.

    Erfrage mal die Ini Klasse (wäre für alle mal interesannt). Ansonsten poste ich Dir morgen mal ne Beispielroutine für das Auslesen der Sektionen in einen CStringArray

    Micha



  • @Knuddlbaer
    Das wäre echt super da ich jetzt schon die ganze zeit versucht habe das aus zu lesen doch bekomme es nicht wirklich hin.



  • Auszug einer Klasse

    void KBIni::getSektionNames(CStringArray & t)
    {
        char * temp = new char[65535]; // Speicher allokieren wo das zeugs reinpasst
        char * ptrTemp = temp; // Hilfszeiger
        GetPrivateProfileString(NULL,NULL,NULL,temp,65535,IniName); // Alle Sektionsnamen auslesen
    
        while(*ptrTemp != '\0' && *(ptrTemp+1) != '\0') // Und solange was machen bis doppel '\0' auftritt
        {
            t.Add(ptrTemp); // Den Eintrag speichern
            while(*ptrTemp != '\0') // Bis zur \0 laufen
                ptrTemp++;
            if(*(ptrTemp+1) == '\0') // Prüfen ob das folge Zeichen auf \0
                break;           // break damit while bedin. passt
    
            ptrTemp++;               // Ansonsten hinter das \0 setzen
        }
    
        delete[] temp;                   // Hilfsspeicher Löschen
    }
    

    Frage an die MFC Freaks:
    Ich hab da immer das Problem das ich nicht weiß was in der Ini auf mich zu kommt. Und jedesmal 65k zu Reservieren is doof, vorallem was wenn die Ini riesig ist und das nicht passt ?!

    (Vermiss die Klassen vom Borland grml)

    Genauso gehts übrigens auf mit den KeyNamen. Da musst Du eine Sektion Definieren. Der Rest ist identisch.

    [ Dieser Beitrag wurde am 25.09.2002 um 10:09 Uhr von Knuddlbaer editiert. ]



  • Korrektur:

    while(*ptrTemp-1 != '\0' && *(ptrTemp) != '\0')
        {
            SectionNames.AddTail(ptrTemp);
            while(*ptrTemp != '\0')
                ptrTemp++;      
    
            ptrTemp++;
        }
    

    Sonst werden Sektionen [1] falsch behandelt und das ende zu früh "erkannt"



  • @Knuddlbaer
    Ich bin erlich und gebe zu das ich deinen Code nicht verstehe.
    Aber mal ne frage kannich das nicht auch so machen das ich das ini-file umbaue das es ungefähr so aussieht:

    [AIRCRAFT1]
    ATR-72,243,8643,375
    [AIRCRAFT2]
    B747,426,985,9874,523

    usw.
    und das dann so auslese:

    CString c;
    Cstring t;
    t = c.Mid (0,c.Find('@');

    wobei das "@" die kommas ersetzt?


Anmelden zum Antworten