Toon posts:

c++ Weer probs met ontvangen en verturen van data

Pagina: 1
Acties:

Verwijderd

Topicstarter
Wordt wel erg heh :)

Probleem is dat we met het project een 1/2 jaar voorlopen dan met de C++ lessen. Ik kom dus nogal wat probleempjes tegen die ik niet kan oplossen omdat daar nog geen lesmateriaal voor is...

Ik probeer het dus zelf, maar het lukt niet echt helemaal :)

Nu heb ik dit probleem; er is een terminal gemaakt in C++ Builder... Er is een microcontroller aangesloten op de compoort zodat we stukjes tekst in de microcontroller kunnen zetten.

Nu gaat dat helemaal goed met behulp van een Memo veldje, het "luisterd" naar toetsaanslagen en stuurt ze direct door naar de com poort.

Nu wil ik ook graag een String uit een txt'je op het internet kunnen versturen naar de microcontroller.
Daarvoor gebruik ik:

C++:
1
2
NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
Memo->Text      = NMHTTP->Body;


De tekst komt mooi in de Memo te staan. Maar ik wil het graag direct door laten sturen. Ik dacht het zo op te lossen (helemaal onderaan):

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//---------------------------------------------------------------------------

#include <vcl\vcl.h>
#pragma hdrstop

#include "Main.h"
#include "Thread.h"
    //  GLOBAL VARIABLES
HANDLE hComm = NULL;
TRead *ReadThread;
COMMTIMEOUTS ctmoNew = {0}, ctmoOld;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
        : TForm(Owner)
{
}

//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
  DCB dcbCommPort;

    //  OPEN THE COM PORT.
    //  REPLACE "COM1" WITH A STRING OR "COM1", "COM3", ETC. TO OPEN
    //  ANOTHER PORT.

    hComm = CreateFile ("COM1",
                        GENERIC_READ | GENERIC_WRITE,
                        0,
                        0,
                        OPEN_EXISTING,
                        0,
                        0);

    //  IF THE PORT CAN'T BE OPENED, BAIL OUT.

    if (hComm == INVALID_HANDLE_VALUE) Application->Terminate();

    //  SET THE COMM TIMEOUTS IN OUR EXAMPLE.

    GetCommTimeouts (hComm,&ctmoOld);
    // Default setting is 100
    ctmoNew.ReadTotalTimeoutConstant = 0;
    ctmoNew.ReadTotalTimeoutMultiplier = 0;
    ctmoNew.WriteTotalTimeoutMultiplier = 0;
    ctmoNew.WriteTotalTimeoutConstant = 0;
    SetCommTimeouts (hComm, &ctmoNew);

    //  SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.

   dcbCommPort.DCBlength = sizeof (DCB);
   GetCommState(hComm, &dcbCommPort);
   BuildCommDCB("9600,N,8,1", &dcbCommPort);
   SetCommState(hComm, &dcbCommPort);

   //   Start the thread

   ReadThread = new TRead(false);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
{
    //  Stop the thread

    ReadThread->Terminate();

    //  WAIT FOR THE THREAD TO TERMINATE,
    //  PURGE THE INTERNAL COMM BUFFER,
    //  RESTORE THE PREVIOUS TIMEOUT SETTINGS
    //  AND CLOSE THE COMM PORT.

    Sleep(250);
    PurgeComm(hComm, PURGE_RXABORT);
    SetCommTimeouts(hComm, &ctmoOld);
    CloseHandle(hComm);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::mInvoerKeyPress(TObject *Sender, char &Key)
{
    //  TRANSMITS ANYTHING TYPED INTO THE MEMO AREA.

    TransmitCommChar(hComm, Key);

    //  THIS PREVENTS TYPED TEXT FROM DISPLAYING GARBAGE ON THE SCREEN.
    //  IF WE ARE CONNECTED TO A DEVICE THAT ECHOES CHARACTERS, SET
    //  Key = 0 WITHOUT THE OTHER STUFF.

    if (Key != 13 && (Key < ' ' || Key > 'z')) Key = 0;
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::Exit1Click(TObject *Sender)
{
        frmMain->Close();
}
//---------------------------------------------------------------------------6

void __fastcall TfrmMain::iExitClick(TObject *Sender)
{
   frmMain->Close();
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::iUploadClick(TObject *Sender)
{
NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
String sOverbreng     = NMHTTP->Body;
TransmitCommChar(hComm, sOverbreng);

}
//---------------------------------------------------------------------------


Maar nu krijg ik een foutmelding:
code:
1
[C++ Error] Main.cpp(112): E2034 Cannot convert 'AnsiString' to 'char'


Ik moet hem dus waarschijnlijk converteren....

  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

Goed opletten: Kijk ook eens naar nInvoerKeyPress, en bedenk hoeveel letters TransmitCommChar tegelijk verzend.

Verwijderd

Je TransmitCommChar verstuurt maar 1 char tegelijk. Je moet deze functie dus voor elk karakter in je String aanroepen. Nu roep je de functie aan op de String zelf.

  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

Verwijderd schreef op 21 september 2002 @ 15:05:
Je TransmitCommChar verstuurt maar 1 char tegelijk. Je moet deze functie dus voor elk karakter in je String aanroepen. Nu roep je de functie aan op de String zelf.
Dat is flauw. Geef ik een nette hint, ga jij m verpesten door de oplossing te geven ;)

Verwijderd

Topicstarter
Jah, ik weer het.
Je kunt dus geen string naar TransmitCommChar sturen, maar losse karakters. Ik was daar ook al achter gekomen :) , maar hoe zet ik een string om in losse karakters die naar TransmitCommChar worden verstuurd?

Is het uberhaupt wel mogelijk?

Verwijderd

Poohbear schreef op 21 september 2002 @ 15:07:
[...]
Dat is flauw. Geef ik een nette hint, ga jij m verpesten door de oplossing te geven ;)
Dan moet je ook geen hint geven als ik een reply aan het tikken ben ;)
Verwijderd schreef op 21 september 2002 @ 15:10:
Jah, ik weer het.
Je kunt dus geen string naar TransmitCommChar sturen, maar losse karakters. Ik was daar ook al achter gekomen :) , maar hoe zet ik een string om in losse karakters die naar TransmitCommChar worden verstuurd?

Is het uberhaupt wel mogelijk?
Dan zal vast wel, want die karakters zijn er ook een keer in "gezet". Maar hoe dat moet is afhankelijk van hoe je String in elkaar zit.

  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

pseudo-code hint:

for (int i=0; i < lengte string; i++) {
TransmitCommChar( handle, letter i uit string);
}

(ik weet niet hoever je met je C++ lessen bent, maar dit is wel les 2 hoor)

  • viper
  • Registratie: Augustus 1999
  • Laatst online: 28-08 20:54
Uh weet niet hoe dat in C++ zit, maar in C is een string volgens mij een array van char, met als laatste char een '\0'. Heb van beide talen nie zoveel verstand, maar als ik zie hoeveel code je kan produceren voor dat apparaatje, en niet eens weet hoe een string in elkaar steekt vind ik het een beeeetje vreemd :P

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Erm:
C++:
1
2
3
4
5
6
    //  WAIT FOR THE THREAD TO TERMINATE,
    //  PURGE THE INTERNAL COMM BUFFER,
    //  RESTORE THE PREVIOUS TIMEOUT SETTINGS
    //  AND CLOSE THE COMM PORT.

    Sleep(250);

Verander dit eens heel snel in:
code:
1
ReadThread->WaitFor();


En wat de rest betreft: no offense, maar jij hoort met jouw programmeerkennis niet een half jaar vooruit te lopen op de rest. Ga maar lekker in de pas lopen met de rest van de klas, dan krijg je het correcte lesmateriaal en leer je het wellicht. Op dit moment heb je de basisconcepten duidelijk nog niet eens door.

Professionele website nodig?


  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

curry684 schreef op 21 september 2002 @ 15:56:

En wat de rest betreft: no offense, maar jij hoort met jouw programmeerkennis niet een half jaar vooruit te lopen op de rest. Ga maar lekker in de pas lopen met de rest van de klas, dan krijg je het correcte lesmateriaal en leer je het wellicht. Op dit moment heb je de basisconcepten duidelijk nog niet eens door.
Denk niet dat t zo gaat. Lijkt er meer op dat hij electrotechniek ofzo doet, en de opleiding slecht in elkaar zit. Nog niet leren programmeren, al wel wat programmeerkennis nodig om projectje te doen. (hoop voorbeeldcode, rest zelf regelen waar nodig)

* PoohBear ziet dat toverstaf computertechniek doet, en vraagt zich nu inderdaad af waar dit allemaal over gaat... Dit is niet de manier om 't te leren, zeker niet als er een opleiding voorhanden is. Leer het liever in 1 keer goed, dan hoef je later ook geen kwalijke gewoonten af te leren. Van de grond af opbouwen dus.

Verwijderd

Topicstarter
Poohbear schreef op 21 september 2002 @ 16:10:
[...]


Denk niet dat t zo gaat. Lijkt er meer op dat hij electrotechniek ofzo doet, en de opleiding slecht in elkaar zit. Nog niet leren programmeren, al wel wat programmeerkennis nodig om projectje te doen. (hoop voorbeeldcode, rest zelf regelen waar nodig)

* PoohBear ziet dat toverstaf computertechniek doet, en vraagt zich nu inderdaad af waar dit allemaal over gaat... Dit is niet de manier om 't te leren, zeker niet als er een opleiding voorhanden is. Leer het liever in 1 keer goed, dan hoef je later ook geen kwalijke gewoonten af te leren. Van de grond af opbouwen dus.
Ik doe de versnelde opleiding :)

Maar de programmeer lessen duren 1 jaar, terwijl het project over een 1/2 jar af moet zijn.

Verwijderd

Topicstarter
Poohbear schreef op 21 september 2002 @ 15:13:
pseudo-code hint:

for (int i=0; i < lengte string; i++) {
TransmitCommChar( handle, letter i uit string);
}

(ik weet niet hoever je met je C++ lessen bent, maar dit is wel les 2 hoor)
C++:
1
2
3
4
5
6
7
8
9
void __fastcall TfrmMain::iUploadClick(TObject *Sender)
{
NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
String cLetter = NMHTTP->Body;

for (int i=0; cLetter[i] != '\0'; i++) {
TransmitCommChar(hComm, cLetter[i]);
}
}


Wanneer je dit gebruikt onstaat er een error als je op de button klikt.

de foutmelding komt in string.h te staan bij deze regel:
code:
1
2
3
4
5
6
char& __fastcall operator [](const int idx)
    {
      ThrowIfOutOfRange(idx);   // Should Range-checking be optional to avoid overhead ??
      Unique();                 // Ensure we're not ref-counted
      return Data[idx-1];
    }

  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

Verwijderd schreef op 21 september 2002 @ 18:21:
[...]


[code=c++]
for (int i=0; cLetter[i] != '\0'; i++) {
blaaaaaa;
}
Wanneer je dit gebruikt onstaat er een error als je op de button klikt.
Les 2b ging over het verschil tussen for en while...

Als je wil checken op cLetter[i] != '\0', dan doe je dat met een while-loop
int i = 0;
while(cLetter[i] != '\0) {
blaaaaaaa;
i++;
}

Als ik jou was ging ik: of een praten met mijn studiebegeleider, en vertellen dat wat ze je proberen te laten doen belachelijk is: Iemand laten werken met een taal waarvan hij de absolute basics nog niet beheerst; of met heel veel spoed een goed leerboek C/C++ aanschaffen en keihard werken om je achterstand in te halen. Zo gaat 't je nooit lukken...

  • Bertrik
  • Registratie: Mei 2000
  • Laatst online: 22-06-2023
>> [C++ Error] Main.cpp(112): E2034 Cannot convert 'AnsiString' to 'char'

Type AnsiString bevat inderdaad een memberfunctie die een AnsiString omzet naar char, die heet c_str geloof ik (zoek anders in de help van je compiler). Gebruik dus sOverbreng.c_str() ipv sOverBreng.

Of je een for-loop of een while-loop gebruikt maakt verder niet zoveel uit.

Verwijderd

Topicstarter
Poohbear schreef op 21 september 2002 @ 19:43:
[...]


Les 2b ging over het verschil tussen for en while...

Als je wil checken op cLetter[i] != '\0', dan doe je dat met een while-loop
int i = 0;
while(cLetter[i] != '\0) {
blaaaaaaa;
i++;
}

Als ik jou was ging ik: of een praten met mijn studiebegeleider, en vertellen dat wat ze je proberen te laten doen belachelijk is: Iemand laten werken met een taal waarvan hij de absolute basics nog niet beheerst; of met heel veel spoed een goed leerboek C/C++ aanschaffen en keihard werken om je achterstand in te halen. Zo gaat 't je nooit lukken...
Nogmaals; ik ben het helemaal met je eens... maar helaas werken meerdere opleidingen zo.
Vorig jaar Computer Techniek in Enschede gedaan, zelfde werkwijze. De ene docent is niet op de hoogte van de andere docent... en ik weet zeker dat dit op heel veel meer plaatsen voorkomt.
Van een achterstand kan ik nog niet spreken, we zijn pas 2 weken bezig :) Ik doe er erg veel aan, maar helaas beheers je een taal niet na 2 weken.
Ik vind dit een leuk project, maar nu heb ik toch een punt bereikt dat ik te weinig kennis heb.... maarja, project moet toch af heh :)

De while loops ed. heb ik al wel gehad; maar ik denk dat er toch iets anders aan de hand is.

Wanneer ik dit gebruik:

C++:
1
2
3
4
5
6
7
8
9
10
{
NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
String cLetter = NMHTTP->Body;

int i = 0;
while(cLetter[i] != '/0') {
edtUitvoer->Text = (" test ");
i++;
  }
}


komt er nog steeds dezelfde foutmelding in dstring.h wanneer je op de knop drukt:

code:
1
2
3
4
5
6
char& __fastcall operator [](const int idx)
    {
      ThrowIfOutOfRange(idx);   // Should Range-checking be optional to avoid overhead ??
      Unique();                 // Ensure we're not ref-counted
      return Data[idx-1];
    }


Ik weet zeker dat de string goed is... als ik namelijk

C++:
1
2
3
4
5
{
NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
String cLetter = NMHTTP->Body;

edtUitvoer->Text = cLetter;


gebruik wordt er wel "Dit is ff een leuke test" in de edit box afgedrukt :(

Er vind dus nog steeds een soort overflow plaats...

Verwijderd

Topicstarter
Als mensen zich vanavond nog vervelen.... :)

Dit is het programma (zipje = 14kb)
http://www.digibytes.net/~opslag/Project.zip

Hopelijk kan iemand een verlossende tip geven ;)

  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
Ik heb net heel deze thread gelezen, ik moet zeggen moedig dat je er zo tegenaan vliegt.
Spijtig genoeg (dit is zo'n zeldzaam moment waar ik ff een windows bak hebben wil :)) kan ik je niet helpen, dit zijn van die windows 'feature-rich' classes waar ik niet mee overweg kan...

Om een 'gewone' std::string naar een char * om te zetten doe je :
code:
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using std::cout;
using std::string;

int main()
{
  string x="Hello world"; char t[100];
  t=s.c_str();
  cout<<s<<endl<<t<<endl;
}

Maar dat maakt niet zo uit, je wil blijkbaar iets byte per byte uit een string sturen?
code:
1
2
3
4
[...]
for(int c=0;c<(string.size());c++){
  verstuurobject->send(string[c],...);
}


Beter dan deze pseudocode kan ik het niet krijgen...

Verwijderd

code:
1
2
3
for (int i=0; cLetter[i] != '\0'; i++) {
blaaaaaa;
}


code:
1
2
3
4
5
int i = 0;
while(cLetter[i] != '\0) {
blaaaaaaa;
i++;
}


Deze twee stukjes code doen PRECIES hetzelfde, ik snap het probleem dat jij hebt met het gebruik van for in dit geval dan ook niet...

Over de oplossing van je probleem : aangezien je niet vertelt WELKE error er precies optreed kan ik dat niet met zekerheid zeggen, maar het lijkt er wel ERG sterk op dat het een out-of-range error is (de hele reden waarom die ThrowIfOutOfRange er uberhaupt staat). Dat betekent dus dat de string niet wordt afgesloten met \0. Weet je zeker dat die string 0-terminated is?

  • viper
  • Registratie: Augustus 1999
  • Laatst online: 28-08 20:54
code doet idd precies hetzelfde. De C functie voor lengte van een string is strlen() als ik me niet vergis :P denk dat die er dan wel uit kan komen. En zoals al eerder vermeld, het kastje kan geen strings aan, dus als je de tekst een tekstgedeelde plaats kan het idd wel, maar kastje moet char voor char ontvangen.

Verwijderd

Topicstarter
Verwijderd schreef op 22 september 2002 @ 03:02:
code:
1
2
3
for (int i=0; cLetter[i] != '\0'; i++) {
blaaaaaa;
}


code:
1
2
3
4
5
int i = 0;
while(cLetter[i] != '\0) {
blaaaaaaa;
i++;
}


Deze twee stukjes code doen PRECIES hetzelfde, ik snap het probleem dat jij hebt met het gebruik van for in dit geval dan ook niet...

Over de oplossing van je probleem : aangezien je niet vertelt WELKE error er precies optreed kan ik dat niet met zekerheid zeggen, maar het lijkt er wel ERG sterk op dat het een out-of-range error is (de hele reden waarom die ThrowIfOutOfRange er uberhaupt staat). Dat betekent dus dat de string niet wordt afgesloten met \0. Weet je zeker dat die string 0-terminated is?
Uhm, ik weet het niet heel erg zeker, maar dat valt snel genoeg te testen.
De string bestaat namelijk uit: "Dit is ff een leuk test"

Wanneer ik bijvoorbeeld 't' invul ipv '/0' dan krijg ik dezelfde error.
Daar ligt het dus niet aan...

Maar ik zal eens naar die pseudo code van XTerm89D kijken..

Verwijderd

Topicstarter
weer even een update...

de pseudo code van XTerm89D geeft dezelfde foutmelding :(

Ik raak onderhand echt een beetje moedeloos...

Wanneer ik de volgende code gebruik krijg ik karakters op de terminal:

C++:
1
2
char sOverbreng = 'H';
TransmitCommChar(hComm, sOverbreng);


Dit stukje werkt dus.


Ook dit stukje code werkt:
C++:
1
2
3
4
NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
String sOverbreng = NMHTTP->Body; 

edtUitvoer->Text = sOverbreng;


Maar het enige wat niet werkt zijn de gegeven tips :'(
Ze werken ook niet wanneer je van sOverbreng een vaste string maakt, het ligt dus waarschijnlijk ook niet aan het NMHTTP component.

Zou iemand met c++ builder versie 5 deze code misschien willen compilen?
wellicht zit er een foutje in mijn systeem; je weet maar nooit.

download: http://www.digibytes.net/~opslag/Project.zip

Verwijderd

Het hangt er ook van af wat cLetter[] returned. Is dit wel van het type char, of is dit van het type wchar_t? Misschien moet je even unicode->multibyte code conversie doen?

Verwijderd

Topicstarter
Verwijderd schreef op 22 september 2002 @ 14:29:
Het hangt er ook van af wat cLetter[] returned. Is dit wel van het type char, of is dit van het type wchar_t? Misschien moet je even unicode->multibyte code conversie doen?
Het zal wel zoiets zijn ja, maar dat is dus het probleem.... ik heb daar nog geen verstand van :)

Kun je misschien het verschil er tussen kunnen uitleggen, en wat maakt het uit als hij van het type wchar_t is?

Verwijderd

een char is een single-byte-character (karakter neemt 1 byte in beslag). Een wchar_t is een unicode-character (karakter neemt 2 bytes in beslag). Zit me overigens ineens te bedenken dat dit het probleem niet echt kan zijn, aangezien simpele tekens in unicode meestal met 0 beginnen (hexcode 00 xx), de eerste nul is dan (als je hem als single-byte character interpreteert) '\0'.

IK HEB EM! De indexer van die String class begint op 1, niet op 0!!!
code:
1
return Data[idx-1];

stop hier maar eens 0 in... Die wordt dus al afgevangen in de bounds check. Gewoon bij 1 beginnen en doorgaan tot je de hele string gehad hebt.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 22 september 2002 @ 23:55:
IK HEB EM! De indexer van die String class begint op 1, niet op 0!!!
Goh lullig dat ik het een dagje weg was, ik had die verlossing wel eerder kunnen brengen :)

De oplossing is dus idd:
C++:
1
2
3
4
5
6
7
8
9
10
void __fastcall TfrmMain::iUploadClick(TObject *Sender)
{
int     Index;

NMHTTP->Get("http://www.digibytes.net/~opslag/uitvoer.txt");
String cLetter = NMHTTP->Body;

for (Index = 1; Index <= cLetter.Length(); Index++) 
  TransmitCommChar(hComm, cLetter[Index]);
}

Ennuh:
Ik doe de versnelde opleiding :)

Maar de programmeer lessen duren 1 jaar, terwijl het project over een 1/2 jar af moet zijn.
Dit is natuurlijk je reinste onzin, en niet ons probleem. We zijn hier niet om achterlijk opgezette opleidingen te vervangen maar om mensen te helpen die vastzitten op serieuze problemen. Ga die mensen die verantwoordelijk zijn voor de stupide planning van de verkorte opleiding maar eens onder z'n kont schuppen.

offtopic:
1000e post! :P

[ Voor 0% gewijzigd door curry684 op 23-09-2002 01:10 . Reden: Statistics :) ]

Professionele website nodig?

Pagina: 1