[C++] Vreemde tekens bij schrijven naar *.txt

Pagina: 1
Acties:
  • 121 views sinds 30-01-2008
  • Reageer

  • SmidsY
  • Registratie: Juni 2001
  • Laatst online: 21:14

SmidsY

hallo!?.............

Topicstarter
Ik wil in mijn programma op het moment dat er blijkt dat de voorraad onder de minimum gestelde voorraad komt dat dit wordt weggeschreven in een txt bestand. Dit heb ik voor elkaar echter hij vult het bestand aan met "jibberisch" ter groote van de opgeven buffer gevolgd door de te schrijven info.

Dus wat onderstaande code moet doen is, het volgende wegschrijven in bestellen.txt

22/04/04 11:52:38 1311 XFX Geforce4 Ti42008X 64mb DDR +TV-out 2

wat het echter doet is dit

ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ22/04/04 11:52:38 1311 XFX Geforce4 Ti42008X 64mb DDR +TV-out 2

Het vreemde is dat ik onderstaande code al eerder eens heb toegepast in een ander programma, waar dit probleem niet eens in voorkwam. Het enige verschil ertussen is een aangepaste benaming in de code.

C++:
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// Vrije voorraad berekenen
void CSQLVoorraadView::OnBnClickedButton1()
{
    int Aantal,Totaal;

    Aantal = GetDlgItemInt(IDC_Aantal);
    Totaal = GetDlgItemInt(IDC_Totaalverkocht);
    
    Vrijevoorraad.Format("%d", Aantal-Totaal);
    SetDlgItemText(IDC_EDIT2,Vrijevoorraad);

// Minimum voorraad controle
    {
    GetDlgItemText(IDC_Artikelcode, Artikelcode);
    GetDlgItemText(IDC_Omschrijving, Omschrijving);
    GetDlgItemText(IDC_MinimumVoorraad,Minimum);
    GetDlgItemText(IDC_EDIT2,VrijeVoorraad);
    
    if(Vrijevoorraad <= Minimum)
    {
    AfxMessageBox("voorraad is onder minimum");
//Bestellijst maken
//bestand openen
    HANDLE hFile;
    DWORD dwNumRead;
    BOOL bTest;
    char dwBuffer[12560];
    CString tijd;
    CString buf;
    hFile = CreateFile("e:\\bestellen.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    bTest = ReadFile(hFile,dwBuffer,sizeof(dwBuffer),&dwNumRead,NULL);
    buf=dwBuffer;
    CloseHandle(hFile);
    CTime DeTijd = CTime::GetCurrentTime();
    tijd = DeTijd.Format( "%d/%m/%y %X" );
    CString B1=Artikelcode;
    CString B2=Omschrijving;
    CString B3=Minimum;
//Bestand indelen
    buf+=tijd;
    buf+="\t"; //tab invoegen
    buf+=B1;
    buf+="\t"; //tab invoegen
    buf+=B2;
    buf+="\t"; //tab invoegen
    buf+=B3;
    buf+="\r\n"; //enter, nieuwe regel
//opslaan
    CString Save;
    Save=buf;
    HANDLE hSaveFile;
    DWORD dwNumRead2;
    int bTest2;
    hSaveFile = CreateFile("e:\\bestellen.txt", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    bTest2 = WriteFile(hSaveFile,Save,Save.GetLength(),&dwNumRead2,NULL);
    CloseHandle(hSaveFile);
    }
    else
    { 
        AfxMessageBox("voorraad is boven minimum");
    }
}


Heeft er hier iemand een idee wat ik fout doe of waarom het niet werkt, want ik ben het nu even kwijt.

Het probleem is gelokaliseerd, het bevindt zich tussen het keyboard en de rugleuning.


Verwijderd

Ik ben geen kei in C++, maar volgens mij initialiseer je nergens je buffervariabele ( die je wegschrijft). In sommige talen mag je aannemen dat een variabele leeg is bij het aanmaken, bij sommige niet, en ik denk dat hier dat je probleem is

  • MrEdge_
  • Registratie: April 2000
  • Laatst online: 17-11-2023
Verwijderd schreef op 22 april 2004 @ 13:34:
Ik ben geen kei in C++, maar volgens mij initialiseer je nergens je buffervariabele ( die je wegschrijft). In sommige talen mag je aannemen dat een variabele leeg is bij het aanmaken, bij sommige niet, en ik denk dat hier dat je probleem is
Daar sluit ik me bij aan.
char dwBuffer[12560];

Geen initialisatie en vervolgens

buf=dwBuffer;

Dus dat gaat mis.

Verwijderd

MrEdge_ schreef op 22 april 2004 @ 13:36:
[...]

Daar sluit ik me bij aan.
char dwBuffer[12560];

Geen initialisatie en vervolgens

buf=dwBuffer;

Dus dat gaat mis.
C++:
1
    bTest = ReadFile(hFile,dwBuffer,sizeof(dwBuffer),&dwNumRead,NULL);


^^^ dat is toch een initialisatie, alleen hoop ik dat die ook goed gaat...

Misschien komen daar al die rare tekens vandaan?

[ Voor 17% gewijzigd door Verwijderd op 22-04-2004 13:42 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Jullie moeten beter lezen
C++:
1
  bTest = ReadFile(hFile,dwBuffer,sizeof(dwBuffer),&dwNumRead,NULL); 


Overigens komt het aantal open-accolades niet overeen met het aantal sluit-accolades, maar dat kun je amper zien door je rare manier van indenting (zeg maar gerust geen indenting ;)). Maar goed, het compilet, dus daar zal het wel niet aan liggen


Overigens lees je eerst van bestellen.txt en schrijf je daarna weer naar bestellen.txt. Ik vermoed dus dat die hele rits Ì tekens er al in staan... aangezien je ze er weer uitleest en er dan een tijd en datum e.d. achter plakt dan blijft het er natuurlijk ook in staan. Of bedoel je dat dat stukje echt de laatst bijgeschreven waarde is?

En waarom open je de file niet gewoon voor appending, ipv de hele file in te lezen, in het geheugen er wat achter te plakken, en dan de hele file weer weg te schrijven?

[ Voor 49% gewijzigd door .oisyn op 22-04-2004 13:48 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SmidsY
  • Registratie: Juni 2001
  • Laatst online: 21:14

SmidsY

hallo!?.............

Topicstarter
Overigens komt het aantal open-accolades niet overeen met het aantal sluit-accolades, maar dat kun je amper zien door je rare manier van indenting (zeg maar gerust geen indenting ;))
Tja ik denk dat ik aan het eind een accolade teveel heb meegenomen uit de cpp file. En qua layout, mijn excuses,been geen programmeer pro, maar doe mijn uiterste best.

Volgens mij initialiseer ik hem wel, anders zou het toch in zijn geheel niet werken. :? Of initialiseer ik hem niet correct!?. Wat ik vreemd blijf vinden is dat het in dit programma niet correct werkt, en in het andere wel.

Het probleem is gelokaliseerd, het bevindt zich tussen het keyboard en de rugleuning.


  • SmidsY
  • Registratie: Juni 2001
  • Laatst online: 21:14

SmidsY

hallo!?.............

Topicstarter
Overigens lees je eerst van bestellen.txt en schrijf je daarna weer naar bestellen.txt. Ik vermoed dus dat die hele rits Ì tekens er al in staan... aangezien je ze er weer uitleest en er dan een tijd en datum e.d. achter plakt dan blijft het er natuurlijk ook in staan. Of bedoel je dat dat stukje echt de laatst bijgeschreven waarde is?

En waarom open je de file niet gewoon voor appending, ipv de hele file in te lezen, in het geheugen er wat achter te plakken, en dan de hele file weer weg te schrijven?
Het idee is dat bestellen.txt iig wordt aangemaakt voor het geval deze er niet is. Hij wordt dus leeg aangemaakt. Verder schrijft hij eerst de reeks tekens meteen gevolgd door de gewenste data. Doe ik nog een schrijfactie, dan krijg ik weer een rij tekens gevolgd door mijn gewenste info.

En waarom open je de file niet gewoon voor appending, hoe zou ik dit moeten doen. Ik ben namelijk al redelijk blij dat ik zover ben gekomen. Programmeren is namelijk niet mijn meest sterke punt.

Het probleem is gelokaliseerd, het bevindt zich tussen het keyboard en de rugleuning.


  • MrEdge_
  • Registratie: April 2000
  • Laatst online: 17-11-2023
* MrEdge_ vind dat het toch netter is als je je variabele bij de declaratie meteen initialiseert, al was het maar voor de duidelijkheid. Maar dan kom je al snel uit op coding guidelines waar je het niet mee eens hoeft te zijn.

  • SmidsY
  • Registratie: Juni 2001
  • Laatst online: 21:14

SmidsY

hallo!?.............

Topicstarter
even ter vergelijking dit is de 'originele' code, waar het wel zonder problemen werkt.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
void CPersoonsgegevensView::OnBnClickedButton4()
{
//logboek uit
    GetDlgItem(IDC_EDIT3)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATICe)->ShowWindow(FALSE);
    GetDlgItem(IDC_MONTHCALENDAR1)->ShowWindow(FALSE);
//Database Uit
    GetDlgItem(IDC_VoorNaam)-> ShowWindow(FALSE);
    GetDlgItem(IDC_AchterNaam)-> ShowWindow(FALSE);
    GetDlgItem(IDC_W8Woord)-> ShowWindow(FALSE);
    GetDlgItem(IDC_StudentNummer)-> ShowWindow(FALSE);
    GetDlgItem(IDC_ToegangTijd)-> ShowWindow(FALSE);
    GetDlgItem(IDC_ToegangLokaal)-> ShowWindow(FALSE);
    GetDlgItem(IDC_TypeGebruiker)-> ShowWindow(FALSE);
    GetDlgItem(IDC_RADIO2)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC1)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC2)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC3)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC4)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC5)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC6)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC7)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATIC8)-> ShowWindow(FALSE);
    GetDlgItem(IDC_STATICd)-> ShowWindow(FALSE);
//Menu Uit
    GetDlgItem(IDC_BUTTON1)-> ShowWindow (TRUE);
    GetDlgItem(IDC_BUTTON2)-> ShowWindow(FALSE);
    GetDlgItem(IDC_BUTTON3)-> ShowWindow(FALSE);
    GetDlgItem(IDC_BUTTON4)-> ShowWindow(FALSE);
    GetDlgItem(IDC_BUTTON6)-> ShowWindow(FALSE);


//LOGGEN

//bestand openen
    HANDLE hFile;
    DWORD dwNumRead;
    BOOL bTest;
    char dwBuffer[18650];
    CString s;
    CString buf;
    hFile = CreateFile("e:\\logboek.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    bTest = ReadFile(hFile,dwBuffer,sizeof(dwBuffer),&dwNumRead,NULL);
    buf=dwBuffer;
    CloseHandle(hFile);
    CTime theTime = CTime::GetCurrentTime();
    s = theTime.Format( "%d/%m/%y %X" );
    CString Gn=GebruikersNaam;
    CString Ww="*****";
    CString Gsl;
    buf+=s;
    buf+="  ";
        buf+=Gn;
        int x=Gn.GetLength();
        int y=10-x;
        while(y>0)
            {
            buf+=" ";
            y--;
            }
        buf+="  ";
        buf+=Ww;
        int a=Ww.GetLength();
        int b=10-a;
        while(b>0)
            {
            buf+=" ";
            b--;
            }
        buf+="  ";
        buf+="Uitgelogd";
        buf+="\r\n";
//opslaan
    CString Save;
    Save=buf;
    HANDLE hSaveFile;
    DWORD dwNumRead2;
    BOOL bTest2;
    hSaveFile = CreateFile("e:\\logboek.txt", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    bTest2 = WriteFile(hSaveFile,Save,Save.GetLength(),&dwNumRead2,NULL);
    CloseHandle(hSaveFile);
}

Het probleem is gelokaliseerd, het bevindt zich tussen het keyboard en de rugleuning.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Sorry .oisyn, maar jij moet beter lezen. dwBuffer wordt niet geinitialiseerd, en de ReadFile leest maximaal 12560 karakters. Als de file nog niet bestaat worden dus precies 0 chars in dwBuffer geinitialiseerd.

De code heeft wel meer problemen. dwBuffer? dw is de Hungarian prefix voor DoubleWord, niet voor een character array. acBuffer is zinniger, voor zover Hungarian natuurlijk zinnig te noemen is. Fixed size buffers zijn sowieso dubieus. Wat als de file meer dan 12560 karakters bevat? Dan wordt de file ergens in het midden van een regel getruncate?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 19:11

BoAC

Memento mori

Verkeerd gelezen :'(

[ Voor 110% gewijzigd door BoAC op 22-04-2004 14:07 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

MSalters schreef op 22 april 2004 @ 14:02:
Sorry .oisyn, maar jij moet beter lezen. dwBuffer wordt niet geinitialiseerd, en de ReadFile leest maximaal 12560 karakters. Als de file nog niet bestaat worden dus precies 0 chars in dwBuffer geinitialiseerd.
Daar had ik idd nog niet bij stilgestaan. Hij moet er sowieso nog een appending '\0' achter stoppen (op de positie aantal_gelezen_bytes), of gewoon het aantal bytes (inclusief de buffer natuurlijk) meegeven met de constructor van CString.

Maar goed, zoals ik al zei, hij moet gewoon de file openen voor appending, dan heeft ie al de problemen die zijn opgenoemd niet.

En SmidsY, hoe je dat doet kun je lezen in de documentatie van CreateFile

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SmidsY
  • Registratie: Juni 2001
  • Laatst online: 21:14

SmidsY

hallo!?.............

Topicstarter
via de MSDN gezocht op CreatFile en Append en het enige nuttige stuk dat ik kan vinden is http://msdn.microsoft.com...e_to_another_file.aspdeze. Maar dat gaat erover om twee tekstbestanden aan elkaar te koppelen en dat is niet dat wat ik wil.

[ Voor 3% gewijzigd door SmidsY op 22-04-2004 15:30 ]

Het probleem is gelokaliseerd, het bevindt zich tussen het keyboard en de rugleuning.


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 19:11

BoAC

Memento mori

CreateFile
Ik denk dat je deze moet gaan gebruiken:

OPEN_ALWAYS
Opens the file, if it exists. If the file does not exist, the function creates the file as if dwCreationDisposition were CREATE_NEW.

icm 'SetFilePointer'

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je zou ook gewoon de C++ streams kunnen gebruiken, std::ofstream bijvoorbeeld.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

BoAC schreef op 22 april 2004 @ 15:39:
CreateFile
Ik denk dat je deze moet gaan gebruiken:

OPEN_ALWAYS
Opens the file, if it exists. If the file does not exist, the function creates the file as if dwCreationDisposition were CREATE_NEW.

icm 'SetFilePointer'
staat toch gelijk aan ios:app

code:
1
ofstream schrijfweg("myTextfile.txt", ios::app);

[ Voor 3% gewijzigd door Verwijderd op 22-04-2004 16:16 ]


  • SmidsY
  • Registratie: Juni 2001
  • Laatst online: 21:14

SmidsY

hallo!?.............

Topicstarter
Oeps bijna vergeten, probleem uiteindelijk weten op te lossen met jullie pointers waarna ik op een leuks msdn voorbeeldje uit kwam :Y) de uiteindelijk code zie hieronder.

C++:
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// Vrije voorraad berekenen
void CSQLVoorraadView::OnBnClickedButton1()
    {
    int Aantal,Totaal;

    Aantal = GetDlgItemInt(IDC_Aantal);
    Totaal = GetDlgItemInt(IDC_Totaalverkocht);
    
    Vrijevoorraad.Format("%d", Aantal-Totaal);
    SetDlgItemText(IDC_EDIT2,Vrijevoorraad);

// Minimum voorraad controle    
    GetDlgItemText(IDC_Artikelcode, Artikelcode);
    GetDlgItemText(IDC_Omschrijving, Omschrijving);
    GetDlgItemText(IDC_MinimumVoorraad,Minimum);

    if(Vrijevoorraad <= Minimum)
    {
        AfxMessageBox("voorraad is onder minimum");

        // Bestand maken
        CString fileNaam = "e:\\bestel.txt";
        std::ofstream txtFile;
        // Tijd en datum opzoeken en instellen
        CTime DeTijd = CTime::GetCurrentTime();
        tijd = DeTijd.Format( "%d/%m/%y %X" );
        // Inhoud Schrijven
        txtFile.open(fileNaam, std::ios_base::out|std::ios_base::app);
        txtFile << tijd + "\t" + Artikelcode + "\t" + Omschrijving + "\t"  + Minimum <<std::endl;
        // Bestand sluiten, veranderingen opslaan.
        txtFile.close();
    } else  { 
        AfxMessageBox("voorraad is boven minimum");
    }

Het probleem is gelokaliseerd, het bevindt zich tussen het keyboard en de rugleuning.


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 99% gewijzigd door Eelis op 18-02-2015 19:35 ]


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 11-03 09:21
Als je toch in MFC bezig bent (zo ziet het er tenminste uit).. waarom gebruik je niet gewoon de CStdioFile klasse.

BOOL CStdioFile::ReadString(CString& rString);

leest gewoon een string in...

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Omdat je helemaal geen string wil inlezen, duh.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1