ini-Datei auslesen, Variable in Pfad integrieren



  • Hallo,

    nachdem ich tagelang nach einer Lösung für mein Problem gesucht und schon etliches ausprobiert habe, hoffe ich nun auf euren guten Rat. Ich habe keine großen C++ Kenntnisse, aber davon mehr als von anderen Programmiersprachen.

    Also folgende Aufgaben gilt für mich zu lösen:
    1. Ich habe eine ini-Datei (pdb.ini), Inhalt:

    [Device]
    NameType=2
    DeviceName=VWAGWOTEV141
    

    2. Ich muss eine Datei von einem Ort zum anderen kopieren. Der Dateiname ist abhängig von dieser Variablen und soll im folgenden so lauten
    "Devicename".wob.vw.vwg.p12
    Das heißt ich muss die Datei mit dem variablen Devicenamen und dem gebabel dahinter aus einem Ordner in einen anderen kopieren.

    Nun dachte ich mir, ich lese einfach die ini aus, speicher den Wert unter DeviceName als Variable DeviceName ab und füge sie einfach in meinen Pfad zum kopieren ein. So entstand folgender Quelltext, in dem sicherlich viel überflüssiges Zeug vorhanden ist:

    #include <windows.h>
    #include <std.lib>
    #include <iostream.h>
    #include <string.h>
    #include <stdafx.h>
    
    using namespace std;
    
    int Devicename;
    int Pfad;
    char buffer[40];
    
    int main()
    {
    	Devicename = GetPrivateProfileString ("Device", "DeviceName", buffer, sizeof(buffer), "\application\pdb.ini");
    	Pfad = "\temp\ "Devicename" .wob.vw.vwg.p12", "\application\certadd\ ";
    	CopyFile(Pfad);
    
    	return 0;
    }
    

    Folgende Fehler traten dabei auf:

    Fehler	1	error C2871: 'std' : a namespace with this name does not exist	Zeile 7	
    Fehler	3	error C3861: 'GetPrivateProfileString': identifier not found	Zeile 15	
    Fehler	5	error C2440: '=' : cannot convert from 'const char [6]' to 'int'	Zeile 16	
    Fehler	6	error C2146: syntax error : missing ';' before identifier 'Devicename'	Zeile 16	
    Fehler	7	error C2143: syntax error : missing ';' before 'string'	Zeile 16	
    Fehler	10	error C2660: 'CopyFileW' : function does not take 1 arguments	Zeile 17
    

    Ich hoffe es weiß jemand Rat. Wie gesagt, wirklich Ahnung habe ich davon nicht.


  • Administrator

    Es tut mir ja leid, aber der Code ist so kreuzfalsch, da frage ich mich, ob es sich überhaupt lohnt, die Fehler zu korrigieren. Lern lieber zuerst einmal C++ und lies die Dokumentation zu den Funktionen in der MSDN nach, zum Beispiel für CopyFile .

    Für C++ werden diese Bücher empfohlen:
    - C++ Primer
    - Thinking in C++ 1&2

    Grüssli



  • // Der Code ist nicht vollständig
    #include <iostream> // ohne .h 
    #include <string>
    
    int main()
    {
      // ...
      int written = GetPrivateProfileString("Device", "DeviceName", "" // default-ausgabe, wenn ncihts gefunden wird
    buffer, sizeof(buffer)/sizeof(buffer[0]), "DeinIniDateiName");
    
    string name = buffer;
    string from = "\\temp\\" + Devicename + ".wob.vw.vwg.p12";
    // CopyFile(from.c_str(), "\\application\\certadd\\"); stimmt so nciht, siehe MSDN
    
    }
    

    Ist aber alles ungetestet. Siehe auch
    http://msdn.microsoft.com/en-us/library/ms724353(VS.85).aspx



  • Danke erst mal für eure Antworten.

    Also ich hatte C++ in der Schule und hab es so angewendet, wie unserer Lehrerin es uns beigebracht hat. Leider haben wir dort nur Grundlagen durchgenommen, die ich mehr oder weniger wieder vergessen habe.

    @Maxi
    Ich habe wahrscheinlich den Großteil deines Codes falsch eingefügt oder Dinge vergessen, aber ich habe nen Haufen Fehlermeldungen erhalten. Ist wohl sinnlos das hier zu posten.
    Eine Sache geht aber auf jeden Fall nicht:

    string from = "\temp\! + Devicename + " .wob.vw.vwg.p12";
    

    Das hatte ich im Vorfeld schon ausprobiert.
    Meine Lösung:

    Pfad = "\temp\ "Devicename" .wob.vw.vwg.p12", "\application\certadd\ ";
    

    war die einzige bei der "Devicename" als Variable anerkannt wird. Erkennt man ja an den Farben. (Sagt mir wenn ich dummes Zeug erzähle)



  • \ in Text musst du duch \\ darstellen.
    ja und du hast recht, anstatt DeviceName muss da natürlich name stehen, die string-variable die in der zeile darüber erzeugt wurde.



  • das mit den \\ hatte ich vergesse, habe ich vorhin noch mal nachgelesen.

    bezüglich

    string from = "\\temp\\" + name + " .wob.vw.vwg.p12";
    

    gibt er mir folgenden Fehler:

    error C2110: '+' : cannot add two pointers
    

    Mein Englisch ist nicht gerade das beste, aber ich habe mir in der MSDN mal den CopyFile Befehl angeschaut. So wie ich das verstehe muss man das folgendermaßen schreiben:

    string from = "\\temp\\" + name + " .wob.vw.vwg.p12";
    CopyFile(from, "\\application\\certadd\\");
    


  • kann mir jemand sagen wie man grundsätzlich einen Wert aus einer ini-Datei auslesen kann und eine Variable in einen Pfad intergriert?



  • freaky_ak schrieb:

    #include <windows.h>
    
    //#include <std.lib> //gibts nich...
    #include <cstdlib>
    
    //#include <iostream.h> //gibts nich...
    #include <iostream>
    
    //#include <string.h> //umfasst nur char*-vergleichs funktionen (strcmp, stricmp, ...)
    #include <string>
    
    #include <stdafx.h>
    //wozu brauchst du den vorkompilierten header, wenn du ihn nicht mal nutzt? (da sollte zumindest das ganze standard-zeugs rein, wenn du ihn schon nicht dekativierst)
    
    using namespace std;
    
    int main()
    {
    	char buffer[40];
    	int Devicename = GetPrivateProfileString ("Device", "DeviceName", buffer, sizeof(buffer)/sizeof(buffer[0]), "/application/pdb.ini"); // statt jedes mal \\ zu schreiben, kann man auch einfach / schreiben - das geht dann wenigsten auch noch unter linux
    	/*std::*/string Pfad = "/temp/" + ToString(Devicename) + ".wob.vw.vwg.p12";
    	CopyFile(Pfad, "/application/certadd/");
    //	return 0; kannst du zwar auch stehen lassen, aber du kannst es auch genausogut weglassen ^^
    }
    

    Habs mal versucht, zu korrigieren, ohne die winapi-fkt nachzuschlagen ^^
    Wie das ToString() auszusehen hat, kannst du in der FAQ nachgucken...

    bb

    PS: Was willst du denn eigtl machen? Nur ne Datei kopieren? Dafür gibts eigtl *.bat-Dateien ^^

    freaky_ak schrieb:

    kann mir jemand sagen wie man grundsätzlich einen Wert aus einer ini-Datei auslesen kann und eine Variable in einen Pfad intergriert?

    fürs ini-auslesen gibts gesonderte winapi-funktionen (siehe msdn) und vermutlich auch (sehr) gute c++ - wrapper dafür (bzw die intern mit streams oä arbeiten - auf jeden fall eleganter ^^)
    wie du verschiedene Datensätze in einen string packen kannst, siehst du in der faq unter "einmal zahl und zurück" oder so ähnlich...



  • danke für die korrektur

    die Bibliotheken hab ich eingebunden, weil ich nicht genau wusste, welche ich benötige. Und den Rest an unnötigen Dingen habe ich so im Unterricht gelernt.

    folgende Aufgaben gilt für mich zu lösen:
    Ich habe eine ini-Datei (pdb.ini), Inhalt:

    [Device] 
    NameType=2 
    DeviceName=Rechner141
    

    Den Wert DeviceName muss ich auslesen und in einen Pfad als Variable integrieren.
    Also ich muss eine Datei von einem Ort zum anderen kopieren. Der Dateiname ist abhängig von dieser Variablen und soll im folgenden so lauten
    "Devicename".bla.blub.p12

    Nun dachte ich mir, ich lese einfach die ini aus, speicher den Wert unter DeviceName als Variable DeviceName ab und füge sie einfach in meinen Pfad zum kopieren ein.



  • naja - dann so:

    char buffer[40] = {0};
        int Devicename = GetPrivateProfileString ("Device", "DeviceName", buffer, sizeof(buffer)/sizeof(buffer[0]), "/application/pdb.ini"); 
    
        std::string Pfad = "/temp/";
        Pfad += buffer;
        Pfad += ".wob.vw.vwg.p12";
    
        CopyFile(Pfad, "/application/certadd/");
    

    ist dir das wenigsten alles klar?

    btw:
    für pfade nutzt man eigtl immer '/' als trennzeichen, weil es eben unter windows und linux funktioniert - und wenn man das aktuelle (arbeits-) verzeichnis meint, dann schreibt man so was: "./pfad/datei.endung"

    das mit dem "./x" statt dem "/x" kann ich dir aus dem kopf nicht sagen, aber kannst ja selbst ma googlen ^^

    bb



  • so siehts jetzt aus (wenn ich die stdafx.h nicht einbinde, bekomme ich immer nen fatalerror und er sagt, ich soll das gefälligst mit einbinden):

    #include <windows.h>
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <stdafx.h>
    
    using namespace std; 
    
    int Devicename;
    string Pfad;
    
    int main()
    {
    	char buffer[40] = {0};
        int Devicename = GetPrivateProfileString ("Device", "DeviceName", buffer, sizeof(buffer)/sizeof(buffer[0]), "/application/pdb.ini");
    
    	std::string Pfad = "/temp/";
    	Pfad += buffer;
    	Pfad += ".wob.vw.vwg.p12"; 
    
    	CopyFile(Pfad, "/application/certadd/"); 
    }
    

    bekomme leider zahlreiche Fehler...

    Fehler 1	error C2871: 'std' : a namespace with this name does not exist	Zeile 7	
    Fehler	2	error C2146: syntax error : missing ';' before identifier 'Pfad'	Zeile 9	
    Fehler	3	error C4430: missing type specifier - int assumed. Note: C++ does not support default-int	Zeile 9	
    Fehler	4	error C4430: missing type specifier - int assumed. Note: C++ does not support default-int	Zeile 9	
    Fehler	5	error C3861: 'GetPrivateProfileString': identifier not found	Zeile 14	
    Fehler	6	error C2653: 'std' : is not a class or namespace name	Zeile 16	
    Fehler	7	error C2146: syntax error : missing ';' before identifier 'Pfad'	Zeile 16	
    Fehler	8	error C2440: '=' : cannot convert from 'const char [7]' to 'int'	Zeile 16	
    Fehler	9	error C2297: '+=' : illegal, right operand has type 'char [40]'	Zeile 17	
    Fehler	10	error C2040: '+=' : 'int' differs in levels of indirection from 'char [40]'	Zeile 17	
    Fehler	11	error C2297: '+=' : illegal, right operand has type 'const char [16]'	Zeile 18	
    Fehler	12	error C2040: '+=' : 'int' differs in levels of indirection from 'const char [16]'	Zeile 18	
    Fehler	13	error C2660: 'CopyFileW' : function does not take 2 arguments	Zeile 20
    

    was ich da überhaupt nicht verstehe sind die Fehler wegen dem using namespace std...



  • Die Header, die du vor "stdafx.h" (sollte vielleicht in Anführungszeichen statt spitzer Klammern stehen) inkludierst, werden ignoriert, da sie ebenfalls als vorkompiliert angeschaut werden. Ändere also deren Reihenfolge.



  • Du hasts nicht verstanden -.-

    Also: Vorkompilierten Header kann man deaktiveren (links auf das Projekt rechtsklicken und dann mal suchen ^^)

    Wenn man ihn verwendet (was durchaus ab und an Sinn macht, dann included man dort zumindest alle stdandard-header (string/iostream/vector/... was man halt alles so braucht) - jz mal zum eigentlichen Code:

    #include "stdafx.h" // !
    
    #include <windows.h> 
    #include <cstdlib> //brauchst du nicht
    #include <iostream> //brauchst du auch nicht
    #include <string> 
    
    using namespace std; 
    
    /*
    int Devicename; //NEIN!
    string Pfad; //NEIN!
    
    du brauchst keine globalen variablen, weil du die variablen in der main-fkt eh deklarierst
    (wo du sie sinnigerweise auch gleich definieren kannst und so theoretisch auch nen const davormachen könntest.
    Aber das ist immer so nen streitthema, ob man const-correctness auch im scope an sich beachten sollte)
    */
    
    int main() 
    { 
        char buffer[40] = {0}; //verstehst du das? (1)
        /*int*/ DWORD /*ist zwar auf nem x86-system das gleiche, aber man kanns ja auch ordentlich machen ;o)*/
          Devicename = GetPrivateProfileString ("Device", "DeviceName", buffer, sizeof(buffer)/sizeof(buffer[0]), "/application/pdb.ini"); // (2)
    
        std::string Pfad = "/temp/"; // (3)
        Pfad += buffer; //(3a)
        Pfad += ".wob.vw.vwg.p12"; //(3b)
    
        CopyFile(Pfad, "/application/certadd/"); // (4)
    }
    

    erst man zu den includes: <> und "" ist nicht das gleiche - ich hab die fachausdrücke nicht parat und kann auch so nicht behaupten, es gut formulieren zu können - aber hab auch auf die schnelle nix finden können, obwohl es da imho nen ganzen artikel zu in der vs-hilfe (bzw. msdn) gab...
    bei #include <x> sucht der compiler zuerst die system-verzeichnisse durch (dort, wo die ganze standard-lib ist, also iostream, string, vector, ...) und erst, wenn er dort nirgendwo was gefunden hat, wird in dem normalen ordner (da, wo auch die main.cpp oder wie auch immer du sie genannt hast, liegt).
    bei #include "x" macht er das andersrum...

    Die Variable Devicename brauchst du eigtl auch gar nicht, ist "nur" nen Rückgabe-Wert:

    MSDN schrieb:

    The return value is the number of characters copied to the buffer, not including the terminating null character.

    also die anzahl der zeichen, die er in buffer geschrieben hat... falls das also 40 ist (bzw die größe des buffers im allgemeinen), solltest du überlegen, den buffer vll zu vergrößern (-> new[] / delete[], kein sizeof mehr, da das zur compilezeit ausgewertet wird, aber new[] nicht) und dann die Funktion noch einmal aufzurufen...

    falls du konkrete fragen hast: ich hab dir nummern rangeschrieben ^^
    falls du es im allgemeinen nicht verstehst, dann frag noch mal nach und ich werd dir sagen, dass du hättest auch googlen können, aber dir wohl trotzdem erklären, was du wissen musst...

    bb



  • danke erst mal!

    ich hab gegooglet, so is es ja nich, aber ich hätte diesen thread nich geöffnet, wenn ich dort etwas gefunden hätte, was mir weiterhilft. ich arbeite an diesem prob schon seit zwei wochen ohne ne lösung gefunden zu haben.

    also der wert der in den buffer geschrieben wird hat immer genau 12 zeichen. ändere ich also buffer[40] in buffer[12] ? oder hab ich dich schon wieder falsch verstanden?

    ich bekomme immer wieder zwei fehlermeldungen:
    (2) 'GetPrivateProfileString': identifier not found
    (4)'CopyFileW': function does not take 2 arguments

    den rest hab ich soweit verstanden.



  • hab jetzt folgenden code:

    #include <stdafx.h>
    #include <windows.h>
    #include <string>
    
    using namespace std; 
    
    int main()
    {
    	char buffer[40] = {0};
    	int DWORD;
        DWORD WINAPI GetPrivateProfileString (
    		__in   LPCTSTR lp"Device",
    		__in   LPCTSTR lp"DeviceName", 
    		__in   LPCTSTR lpbuffer, 
    		__in   DWORD sizeof(buffer)/sizeof(buffer[0]), 
    		__in   LPCTSTR lp"./application/pdb.ini");
    
    	std::string Pfad = "/temp/";
    	Pfad += buffer;
    	Pfad += ".wob.vw.vwg.p12"; 
    
    	BOOL CopyFile(LPCTSTR lpPfad, LPCTSTR lp"/application/certadd/", BOOL bFailIfExists); 
    }
    

    aber bekomme immer noch fehler:

    Fehler	1	error C2143: syntax error : missing ';' before '__cdecl'	Zeile 11	
    Fehler	2	error C2143: syntax error : missing ';' before '__cdecl'	Zeile 11	
    Fehler	3	error C2143: syntax error : missing ',' before 'string'	Zeile 22
    

    weiß da jemand rat?



  • In Zeile 11 stimmt die Syntax für den Funktionsaufruf nicht. Wieso WINAPI ? Und willst du das Resultat keiner Variable zuweisen?



  • WINAPI habe ich ausm MSDN:
    http://msdn.microsoft.com/en-us/library/ms724353(VS.85).aspx

    Ich wollte das Resultat ursprünglich einer Variablen zuweisen, aber unskilled schrieb:

    Die Variable Devicename brauchst du eigtl auch gar nicht, ist "nur" nen Rückgabe-Wert:

    Wenn ich mich nicht vollkommen irre, sollte das doch jetzt aber auch ohne laufen oder?

    Edit: Was muss ich denn in Zeile 11 ändern, damit es rennt?



  • freaky_ak schrieb:

    WINAPI habe ich ausm MSDN:
    http://msdn.microsoft.com/en-us/library/ms724353(VS.85).aspx

    Du kennst den Unterschied zwischen einer Funktionsdeklaration und einem Funktionsaufruf?

    freaky_ak schrieb:

    Edit: Was muss ich denn in Zeile 11 ändern, damit es rennt?

    Die Funktion aufrufen, indem du Argumente angibst. Das sind nun aber wirklich Grundlagen von C++ - wenn du daran scheiterst, solltest du mit WinAPI vielleicht noch etwas warten.



  • Nexus schrieb:

    Du kennst den Unterschied zwischen einer Funktionsdeklaration und einem Funktionsaufruf?

    ja, kenne ich

    ich kann nicht warten, das ist ja mein Problem. Wenn es unwichtig wäre hätte ich den Aufwand gar nicht betrieben.



  • freaky_ak schrieb:

    ja, kenne ich

    Dann schreibe doch die Deklaration in Zeile 11 zu einem Aufruf um. 😉

    freaky_ak schrieb:

    ich kann nicht warten, das ist ja mein Problem. Wenn es unwichtig wäre hätte ich den Aufwand gar nicht betrieben.

    Aber die Funktion aufzurufen solltest du ja schon noch zustande bringen.

    Falls nicht, ist das ja nicht schlimm. Aber du solltest dich wirklich mit der Thematik befassen. Wenn du jetzt eine Lösung hast, die zwar für den Moment funktioniert, aber die du nicht verstehst, ist das auch nicht gerade ideal. Plötzlich willst du etwas ändern, weisst aufgrund mangelnder C++-Kenntnis nicht mehr weiter und verlierst wieder sehr viel Zeit.

    Und Funktionen sind wirklich etwas vom Grundlegendsten in C++. Du brauchst sie überall. Wenn du sie nicht verstanden hast, wirst du kein richtiges Programm schreiben können.


Anmelden zum Antworten