none
Funktion GetPrivateProfileString / Groß- und Kleinbuchstaben im Schlüssel RRS feed

  • Frage

  • Hallo,

    ich verwende schon länger die Funktion GetPrivateProfileString um eine Datei mit einem INI-Format auszulesen. Jetzt habe ich die Situation, dass ich im Schlüssel nach Groß- und Kleinbuchstaben unterscheiden muss.

    In der Dokumentation der Funktion habe ich leider diese Information gefunden:

    Die Funktion GetPrivateProfileString unterscheidet nicht zwischen Groß- und Kleinschreibung. Die Zeichenfolgen können aus Groß- und Kleinbuchstaben bestehen.

    Hier noch den betreffenden Inhalt der Datei:

    [Buchstaben-Abstaende]
    AD=10.7100
    Ad=8.9200
    aD=0.0100
    ad=12.5100

    Hier mein Programmcode dazu:

    CString strFehler = _T("Fehler"); 
    TCHAR szInhalt[UCHAR_MAX];
    GetPrivateProfileString(_T("Buchstaben-Abstaende"), _T("Ad"), strFehler, szInhalt, sizeof(szInhalt), _T("C:\\Temp\\E.sag"));

    Leider liest die Funktion hierbei nicht den Wert des Schlüssels "Ad" aus, sondern liefert den Wert der Variable strFehler zurück.

    Kann ich die Funktion GetPrivateProfileString dazu bringen, den Wert für den Schlüssel "Ad" auszulesen?

    Oder gibt es eine andere Funktion um den Schlüssel "Ad" auslesen?

    Danke im Voraus und viele Grüße

    Bernd

    Dienstag, 22. Januar 2019 13:00

Antworten

  • es gibt in meiner Datei mehrere Zeilen dieser Art:

    [=57.1429

    Das bedeutet, dass der Buchstabe [ eine Breite von 57.1429 mm hat. Vermutlich kommt die Klasse CIniFile und deren Funktionen (z.B. GetValue) damit nicht zurecht.

    [ ist ein eindeutiger Hinweis, dass in einer Ini-Datei eine "section" beginnt. Der Name der section steht dann zwischen [] . Du nutzt [ aber auch als Key. Damit solltest du die GetValue Funktion für deine Anforderungen erweitern.

    Anstatt nur auf [ zu prüfen (if (s.find('[')..., solltest du auf [ und ] prüfen:

    if (s.find('[')!=string::npos && s.find(']')!=string::npos) …

    Dann wird dein [=14 auch als Key/Value gefunden.

    Gruß Guido


    Mittwoch, 23. Januar 2019 13:51
  • Hallo Bernd,

    hast du schon mal einen Blick auf GetPrivateProfileSection geworfen? Wenn man die Funktion noch verwenden kann, kann man sich den ganzen Overhead fremder Software sparen.

    Hinweis: Wenn ich die MSDN-Doku richtig interpretiere, muss der Parameter nSize die Länge des Buffers in Characters, statt in Bytes, enthalten.

    Gruß
    Heiko



    Mittwoch, 23. Januar 2019 17:47

Alle Antworten

  • Hallo,

    du kannst GetPrivateProfileString nicht ändern.

    Verwende stattdessen zum Beispiel folgendes: https://www.codeproject.com/Articles/20120/INI-Files

    Gruß Guido

    Dienstag, 22. Januar 2019 13:49
  • Hallo Guido,

    danke für Deine Information. Ich werde es nachlesen und melde mich dann wieder.

    Viele Grüße

    Bernd

    Dienstag, 22. Januar 2019 14:23
  • Hallo Guido,

    ich habe nun die Dateien IniFiles.cs, IniFileLight.cs und IniFileElement.cs meinem C++-Projekt hinzugefügt und möchte als Programmcode Folgendes verwenden:

    IniFileReader reader = new IniFileReader(strDatei);
    reader.GotoSection(strBereich);
    IniFileSettings.CaseSensitive = true; // Unterscheidung nach Groß- und Kleinbuchstaben
    IniFileValue val = reader.GotoValue(strSchluessel);
    reader.Close();
    

    Als Fehlermeldung erhalte ich dann dies:

    error C2065: 'IniFileReader': nichtdeklarierter Bezeichner

    Wie kann ich IniFileReader in mein C++-Projekt einbinden?

    Geht das denn überhaupt?

    Viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 09:07
  • Hallo Bernd,

    .cs Dateien enthalten in der Regel C# Code, keinen C++ Code. Du wirst die Dateien daher entsprechend anpassen müssen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport


    • Bearbeitet Stefan Falz Mittwoch, 23. Januar 2019 09:10
    Mittwoch, 23. Januar 2019 09:10
  • Mittwoch, 23. Januar 2019 09:25
  • Hallo Stefan,

    danke für Deine Information. Ich habe leider keine Ahnung C#, das ist für mich nicht möglich.

    Viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 10:14
  • Hallo Guido,

    danke für die Links. Ich werde es testen und melde mich dann wieder.

    Viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 10:14
  • Hallo,

    ich stehe gerade etwas auf der Leitung. Diesen Programmcode habe ich zum Testen in meinem C++-Projekt hinzugefügt:

    string sSchluessel = "Ad";
    string sBereich = "Buchstaben-Abstaende";
    string sDatei= "C:\\Users\\Foery\\Documents\\SWEntwicklung\\CPP\\GenWA\\Schriften\\E.sag";
    CIniFile ifTemp;
    string sInhalt = ifTemp.GetValue(sSchluessel, sBereich, sDatei);
    

    Leider erhalte ich dann diese Meldungen, die ich im Moment nicht beheben kann:

    error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall CIniFile::CIniFile(void)" (??0CIniFile@@QAE@XZ)" in Funktion ""public: int __thiscall CDateiIni::Lesen(class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > &,int)" (?Lesen@CDateiIni@@QAEHV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@00AAV23@H@Z)".
    error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: virtual __thiscall CIniFile::~CIniFile(void)" (??1CIniFile@@UAE@XZ)" in Funktion ""public: int __thiscall CDateiIni::Lesen(class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > &,int)" (?Lesen@CDateiIni@@QAEHV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@00AAV23@H@Z)".
    error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl CIniFile::GetValue(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?GetValue@CIniFile@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V23@00@Z)" in Funktion ""public: int __thiscall CDateiIni::Lesen(class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >,class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > &,int)" (?Lesen@CDateiIni@@QAEHV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@00AAV23@H@Z)".

    Was mache ich falsch?

    Danke und viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 11:08
  • Hallo,

    du musst die CInifile-source-Dateien deinem Projekt hinzufügen.

    Gruß Guido

    Mittwoch, 23. Januar 2019 11:16
  • Hallo Guido,

    das hatte ich bereits über Menü > Projekt > Vorhandenes Element hinzufügen gemacht:

    Was ist da noch falsch?

    Viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 12:11
  • Hallo Guido,

    die Fehlermeldungen haben sich erledigt. Ich hatte die Klasse falsch hinzugefügt. Jetzt kann ich die neue Klasse testen.

    Viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 12:15
  • Hallo,

    leider habe ich jetzt beim oben genannten Programmcode diesen Abbruch:

    und zwar an dieser Stelle:

    Was mache ich noch falsch?

    Danke und viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 12:40
  • Hallo,

    der Fehler kommt in der Zeile davor: s.erase(s.find[']'));
    Anscheinend wird ] nicht gefunden, so dass erase(-1) kommt, was den Fehler auswirft. Fragt sich, warum er [ vorher gefunden hat.

    s ist "=57.1429" und daher vermute ich, dass du nicht in einer []-Zeile (sog. "section", Überschriftenzeile in ini-Datei) bist sondern in einer "A=1.2" Zeile. Dann müsste in dem Text "A" ein [ sein? Wie sieht s aus, bevor es in die if (s.find('[')!=… kommt?

    Gruß Guido

    Mittwoch, 23. Januar 2019 13:08
  • Hallo Guido,

    es gibt in meiner Datei mehrere Zeilen dieser Art:

    [=57.1429

    Das bedeutet, dass der Buchstabe [ eine Breite von 57.1429 mm hat. Vermutlich kommt die Klasse CIniFile und deren Funktionen (z.B. GetValue) damit nicht zurecht.

    Ich sehe im Moment keine andere Möglichkeit als den Inhalt meiner Datei mit den ASCII-Werten der Buchstaben zu ergänzen. Dadurch hätte ich auch das Problem der Groß-/Kleinschreibung bei der Funktion GetPrivateProfileString umgangen.

    Viele Grüße

    Bernd

    Mittwoch, 23. Januar 2019 13:44
  • es gibt in meiner Datei mehrere Zeilen dieser Art:

    [=57.1429

    Das bedeutet, dass der Buchstabe [ eine Breite von 57.1429 mm hat. Vermutlich kommt die Klasse CIniFile und deren Funktionen (z.B. GetValue) damit nicht zurecht.

    [ ist ein eindeutiger Hinweis, dass in einer Ini-Datei eine "section" beginnt. Der Name der section steht dann zwischen [] . Du nutzt [ aber auch als Key. Damit solltest du die GetValue Funktion für deine Anforderungen erweitern.

    Anstatt nur auf [ zu prüfen (if (s.find('[')..., solltest du auf [ und ] prüfen:

    if (s.find('[')!=string::npos && s.find(']')!=string::npos) …

    Dann wird dein [=14 auch als Key/Value gefunden.

    Gruß Guido


    Mittwoch, 23. Januar 2019 13:51
  • Hallo Bernd,

    hast du schon mal einen Blick auf GetPrivateProfileSection geworfen? Wenn man die Funktion noch verwenden kann, kann man sich den ganzen Overhead fremder Software sparen.

    Hinweis: Wenn ich die MSDN-Doku richtig interpretiere, muss der Parameter nSize die Länge des Buffers in Characters, statt in Bytes, enthalten.

    Gruß
    Heiko



    Mittwoch, 23. Januar 2019 17:47
  • Hallo an alle,

    ich habe den Programmcode in der zusätzlichen Klasse so geändert

    int nL = s.length();
    if (s[0] == '[' && s[nL - 1] == ']') // Is this line a section?

    weil in meiner Datei auch noch die Zeile

    []-091093=7.1400

    vorhanden ist. Leider hat die zusätzliche Klasse den Wert für den Schlüssel Ad auch nicht gefunden und den Wert "" zurück geliefert.

    Deshalb habe ich in meiner Datei die Schlüssel zusätzlich noch mit den ASCII-Werten der Buchstaben so ergänzt:

    AD-065068=10.7100
    Ad-065100=8.9200
    aD-097068=0.0100
    ad-097100=12.5100

    Dadurch umgehe ich das Problem mit der Groß-/Kleinschreibung bei der Funktion GetPrivateProfileString.

    Danke nochmals an alle und viele Grüße

    Bernd

    Donnerstag, 24. Januar 2019 08:13
  • Hier noch den betreffenden Inhalt der Datei:

    [Buchstaben-Abstaende]
    AD=10.7100
    Ad=8.9200
    aD=0.0100
    ad=12.5100

    ----------

    es gibt in meiner Datei mehrere Zeilen dieser Art:

    [=57.1429

    ----------

    weil in meiner Datei auch noch die Zeile

    []-091093=7.1400

    Hallo,

    du hast uns also nicht alle Informationen gegeben, wie deine ini-Datei wirklich aussieht. In deiner Frage ging es zuerst nur um Groß/Kleinschreibung. Später kamen bei den Keys dann aber auch noch [ vor. Und nun auch noch [] . Der "Inhalt der Datei" ist also nicht so, wie du ihn anfangs angegeben hast. Jetzt erst wird klar, dass du gar keine "normale" ini-Datei hast.

    Bitte gebe beim nächsten Mal genug Informationen, damit wir dir sofort richtig helfen können. Denn dann wäre der Lösungsweg auch sofort ein anderer gewesen und wir hätten nicht 2 Tage nach einer Lösung suchen müssen.

    Gruß Guido


    Donnerstag, 24. Januar 2019 08:33
  • Hallo Bernd,

    wenn Du diese ominöse Dateistruktur doch selbst bastelst, warum nimmst Du dann eigentlich ein solch veraltetes und problematisches Format? Nimm JSON oder XML, das lässt sich problemlos serialisieren und deserialisieren, kann erheblich komplexere Elemente beinhalten, korrespondiert direkt mit deiner Klassenstruktur, usw.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Donnerstag, 24. Januar 2019 09:06