Forum: PC-Programmierung vb to c convertieren


von Der G. (jonnyk)


Lesenswert?

Hallo

ich muss ein existierendes programm in vb to c umschreiben.

Da ich von beiden nicht sehr viel ahnung habe dachte ich dass ich hier 
richtig bin.

hier nun meine frage wenn ich in visual basic etwas mit chr(230) an 
rs232 schike ist es das selbe wie in c printf("%c",*variable mit dem 
wert 230*);

oder wie ist es?

Freue  mich über jede mögliche antwort.

von Falk B. (falk)


Lesenswert?

Ja.

von Severino R. (severino)


Lesenswert?

Ja, aber nur wenn printf() an die serielle Schnittstelle sendet. 
Normalerweise sendet printf() auf die Konsole (also den Textbildschirm).

von Der G. (jonnyk)


Lesenswert?

es geht auch wenn ich ihm sage nicht variable mit dem wert 230 sonder 
als hexa übergebe? z.b. für 230, E6??



char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};

for(x=0;x<8;x++)
{
   printf("%c",boot_seq[x]);
}

weil es irgend wie nicht richtig funktioniert? oder müsste es gehen und 
mache etwas grundsetzliches falsch?(möglich wegen meiner vb kenntnissen)

von Philipp B. (philipp_burch)


Lesenswert?

Auf alle Fälle solltest du beachten, dass du beim Initialisieren von 
Arrays in C die Anzahl der Elemente in die Klammer schreiben solltest. 
Bei VB ist es jeweils der oberste Index.
Schreibt dein printf() denn überhaupt auf die serielle Schnittstelle?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};

Zähle mal die Werte in den geschweiften Klammern und vergleiche die Zahl 
mit der in den eckigen.

von Der G. (jonnyk)


Lesenswert?

Rufus t. Firefly wrote:
>> char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};
>
> Zähle mal die Werte in den geschweiften Klammern und vergleiche die Zahl
> mit der in den eckigen.

arrays gehen immer von 0 bis ... also in meinem fall 8 zeichen lang.

und an den rest danke es geht jetzt.

werde mich bad aber noch ma melden...(Bestimmt)

von Philipp B. (philipp_burch)


Lesenswert?

Der Grosse wrote:
> Rufus t. Firefly wrote:
>>> char boot_seq[7]={0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70};
>>
>> Zähle mal die Werte in den geschweiften Klammern und vergleiche die Zahl
>> mit der in den eckigen.
>
> arrays gehen immer von 0 bis ... also in meinem fall 8 zeichen lang.

In VB ja, in C gehört in die Klammer die ANZAHL der Elemente.

> und an den rest danke es geht jetzt.

Schön, aber komisch.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> arrays gehen immer von 0 bis ... also in meinem fall 8 zeichen lang.

Das stimmt schon. Aber bei der Deklaration eines Arrays wird nicht der 
größte Arrayindex, sondern die Anzahl der Elemente spezifiziert.

von Karl H. (kbuchegg)


Lesenswert?

...
Wobei es in so einem Fall immer das Beste ist, diese
Schmutzarbeit dem Compiler zu überlassen:
1
// lass den Compiler die Arraygröße aus der Initialisierung
2
// bestimmen. Der macht das nämlich fehlerfrei
3
char boot_seq[] = { 0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70 };
4
5
// for(x=0;x<8;x++)
6
// auch hier wieder: die 8 kann auch vom Compiler bestimmt
7
// werden
8
for( x = 0; x < sizeof( boot_seq ); x++ )
9
{
10
   printf("%c",boot_seq[x]);
11
}

Anstatt den sizeof da im Code zu verstecken, kann man auch
den Präprozessor hier sinnvoll einsetzen
1
char boot_seq[] = { 0xe6,0xf0,0x60,0xfa,0x9a,0xb7,0xfe,0x70 };
2
#define BOOT_SIZE ( sizeof( boot_seq ) / sizeof( *boot_seq ) )
3
4
for( x = 0; x < BOOT_SIZE; x++ )
5
{
6
   printf("%c",boot_seq[x]);
7
}

Hmm. Wer vergibt denn solche Auftraege? Da kann einer nicht
ordentlich C und auch nicht ordentlich VB und soll doch ein
Programm von der einen Sprache in die andere transferieren.
Solche Umsetzungen sind mit das Schwierigste, was die Branche
zu bieten hat, weil man in beiden Sprachen absolut firm sein
muss. Die Probleme entstehen nämlich immer dadurch dass 2
Sprachen sich in Details unterscheiden und nur wenn man ueber
diese Details in beiden Sprachen Bescheid weiss, kann man das
richtig machen.

von Der G. (jonnyk)


Lesenswert?

@Karl heinz Buchegger

kommplet richtig aber was gemacht werden muss das muss halt gemacht 
werden...

oder nocht besser

was mich nicht umbringt macht mich stärker...

und ausserdem haben viele andere was davon wenn sie später ma so ne 
aufgabe haben und hier im forum nachschauen.

von Der G. (jonnyk)


Lesenswert?

eine korrektur und zwar sende ich ihm nicht
printf("%c",...)

sondern

printf("%X",...);

warum auch immer,
müsste das eigentlich nicht falsch sein? weil so wie ich es in der vb 
hilfe verstanden habe macht chr() aus den übergebenen zeichen ein ascii 
entsprächendes zeichen und nicht die hex zahl, so wie es in diesem fall 
printf ausgibt.

von Niels H. (monarch35)


Lesenswert?

printf ("%c",...) "sendet" ein 8-Bit Datenbyte, nämlich den wert des 
parameters.

printf ("%X",...) "sendet" soviele Datenbytes, wie nötig sind, um den 
Wert des Parameters hexadezimal in ASCII darzustellen.

printf ("%d",...) "sendet" soviele Datenbytes, wie nötig sind, um den 
Wert des Parameters dezimal in ASCII dazustellen.

von Der G. (jonnyk)


Lesenswert?

und was macht chr() in VB ?

printf("%c")

oder nicht?

von Niels H. (monarch35)


Lesenswert?

chr() macht alleine keine Ausgaben, aber es gibt das ASCII-Zeichen des 
übergebenen Wertes zurück.

print chr(...); wäre der richtige Ausdruck.

von Karl H. (kbuchegg)


Lesenswert?

Der Grosse wrote:
> und was macht chr() in VB ?
>
> printf("%c")
>
> oder nicht?

chr wandelt den Datentyp, entspricht also im weitesten
Sinne in C einem cast. Allerdings ist der in C gar nicht
notwendig, da in C ein char zu einem int Zuweisungskompatibel
ist.

Ein VB Konstrukt
   DIM c as Character
   c = chr( 255 )

kann in C geschrieben werden

   char c;
   c = 255;

oder aber, wenn man genau sein will:

   char c;
   c = (char)255;

von Der G. (jonnyk)


Lesenswert?

Guten Morgen!!!

Schaut ma kann ich folgendes machen?


wenn ich ein feld habe hex-zahlen

und ich daraus integer machen mäöchte um sie dann als char auszugeben.

weil in VB kann man ja mit val() verschiedene hex zahlen oder chars nach 
int convertieren.

also ich meine es so:

loop_until_bit_is_set(UCSR1A, UDRE);
UDR = (int)lenge;

wenn in lenge z.b. ein 0x10 drin steht.

wird er 16 ausgeben?

oder brauche ich gar nichts zu konvertieren?
macht c automatisch aus hex -> int?

in vb folgendes:

laenge = Val("&H" & Left$(antwort, 2))

von Niels H. (monarch35)


Lesenswert?

Was im Empfangsregister drinsteht, kommt ganz drauf an, was der Sender 
gesendet hat.

Hat der Sender print chr(16) bzw chr (&h10) gesendet, wurde ein byte mit 
dem wert 16 empfangen. Die Wandlung nach Hexadezimal verändert den Wert 
dieser Zahl nicht; es ist eine reine Darstellungssache, wie ich diesen 
Wert repräsentiere. 0x10 und 16 und 0b010000 sind von ihrer Wertigkeit, 
also inhalt der Speicherzelle, absolut identisch.

Hat der Sender "0x10" (als String) gesendet, wurden 4 Byte gesendet mit 
den Werten 0x30, 0x78, 0x31, 0x30 gesendet. In diesem Fall reicht einmal 
UDR auslesen nicht aus, um den übermittelten Wert zu erfassen, sondern 
die Werte müssen in einem Buffer erfasst und dann geparst werden.

von Der G. (jonnyk)


Lesenswert?

Ich habe jetzt folgendes ich kriege zwar einen string zurück muss aber 
nur das erste zeichen daraus auswerten.

vb:

If Hex$(Asc(antwort)) = "55" Then List1.AddItem "8xC166 µC gefunden!"

wie kann ich es den in c realisieren?

ich habe folgendes gemacht

aber funktionalität noch nciht ausprobiert kann es den überhaupt gehen?

if((char)b == (char)85)
  {
    lcd_print("Codierer Found",4,22,0,Schwarz,Gruen);
  }
  else if(b == 0)
  {
    lcd_print("Kein Codierer",4,22,0,Schwarz,Gruen);
    getkey();
    menue();
  }
  else
  {
    lcd_print("Falsche Antwort",4,22,0,Schwarz,Gruen);
    getkey();
    menue();
  }

oder muss ich mehr mals auslesen und den string dann bearbeiten? in vb 
lese ich es ja auch nur einmal ein:

antwort = MSComm1.Input

und was sende ich wenn ich sage chr(0) == (char)NULL

von Niels H. (monarch35)


Lesenswert?

Der Grosse wrote:

> vb:
>
> If Hex$(Asc(antwort)) = "55" Then List1.AddItem "8xC166 µC gefunden!"
>
> wie kann ich es den in c realisieren?
>
> ich habe folgendes gemacht
>
> aber funktionalität noch nciht ausprobiert kann es den überhaupt gehen?
>
> if((char)b == (char)85)
>   {
>     lcd_print("Codierer Found",4,22,0,Schwarz,Gruen);
>   }

Ja, die übersetzung entspricht funktional ungefähr dem 
VB-vorbild...(vorrausgesetzt in 'b' ist das empfangene Zeichen, genauso 
wie "antowort" ein einzelnes empfanges Zeichen entspricht)

von Der G. (jonnyk)


Lesenswert?

ich bins noch mal

Als erstes Danke für die schnellen und präziesen antworten... Ich fülle 
mich immer deprimiert das ich selbst nicht darauf komme weil es ja 
eigentlich voll einfach ist.

Danke schön...

habe jetzt ma folgende frage in vb kann man ja aus einem string wo sagen 
wir ma Hex zahlen drin stehen 2 zeichen einlesen und dann als einzelnes 
zeichen benutzen

beispiel:

puffer = Input(2, #1)
laenge = Val("&H" & puffer)

dadurch habe ich je den wert des Hex wertes der im string als z.b 01 
drin steht.

kann ich es in C so realisieren?

adrL = (int)strcat(Buffer[d+5],Buffer[d+6]);
adrL = (int)adrL;

von Karl H. (kbuchegg)


Lesenswert?

Der Grosse wrote:
> habe jetzt ma folgende frage in vb kann man ja aus einem string wo sagen
> wir ma Hex zahlen drin stehen 2 zeichen einlesen und dann als einzelnes
> zeichen benutzen
>
> beispiel:
>
> puffer = Input(2, #1)
> laenge = Val("&H" & puffer)
>
> dadurch habe ich je den wert des Hex wertes der im string als z.b 01
> drin steht.
>
> kann ich es in C so realisieren?
>
> adrL = (int)strcat(Buffer[d+5],Buffer[d+6]);
> adrL = (int)adrL;

nein.
strcat macht was anderes.
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

Aber warum machst du nicht eine 1:1 Umsetzung deiner Beschreibung?
Lass uns die nochmal etwas strukturieren
* Gegeben sei ein String
* An einer bekannten Position in diesem String steht die
  ASCII Repräsentierung einer HEX Zahl (sprich: 2 aufeinanderfolgende
  Zeichen ergeben die Hex Zahl)
* Um die Zahl zu erhalten, reicht es aus der ASCII Repräsentierung
  jedes einzelnen Zeichens die jeweilige Ziffer zu erzeugen
* Liegen beide Ziffern vor, werden die beiden Ziffern zu Zahl montiert.

Die Umwandlung eines Zeichens (im Bereich 0..9, A..F) in die
korrespondierende Ziffer, ist es uns wert, dafür eine eigene
Funktion zu schreiben:
1
void ToNumber( char c )
2
{
3
  // war c im Bereich 'A' bis 'F'?
4
  // wenn ja, dann in eine Ziffer 10 .. 15 wandeln
5
  if( c >= 'A' && c <= 'F' )
6
    return c - 'A' + 10;
7
8
  // c muss im Bereich '0' bis '9' liegen
9
  return c - '0';
10
}

Soweit, so gut. Damit ist es jetzt aber nicht mehr
schwer, jeweils einen char in seine korrespondierende
Ziffer umzuwandeln, für die beiden hintereinander folgenden
Character lautet das zb. so
1
  unsigned char High;
2
  unsigned char Low;
3
4
  High = ToNumber( Buffer[5] );
5
  Low  = ToNumber( Buffer[6] );

und da jetzt beide Ziffern in numerischer Form vorliegen, kann
dann auch die Hex-Zahl in seiner Gesamtheit bestimmt werden:
1
  unsigned char Zahl;
2
3
  Zahl = 16 * High + Low;
4
5
  // oder andere Schreibweise
6
  // Zahl = (High << 4) | Low;

Fragt sich natürlich noch, wozu eigentlih die beiden Zwischen-
variablen gebraucht werden. Eigentlich braucht die ja kein
Mensch:
1
  unsigned char Zahl;
2
3
  Zahl = ( ToNumber( Buffer[5] ) << 4 ) | ToNumber( Buffer[6] );

und weil wir heute einen guten Tag haben, packen wir das
ganze in eine Funktion:
1
unsigned char ToHex( char* String )
2
{
3
  // wertet die ersten beiden char im String aus und wandelt
4
  // sie in eine Hex-Zahl.
5
  // Es wird davon ausgegangen, dass dort auch wirklich
6
  // eine Hex Zahl gespeichert ist
7
8
  return ( ToNumber( String[0] ) << 4 ) | ToNumber( String[1] );
9
}

und wird dann so verwendet
1
int main()
2
{
3
  char Test[] = "HalloAF";
4
  unsigned char Number;
5
6
  Number = ToHex( &Test[5] );
7
}

Was du mitnehmen solltest:
In C sind char (also Character) auch nichts anderes als ein
numerischer Datentyp, mit dem man durchaus auch rechnen kann.
In einem char ist einfach nur der jeweilige ASCII Code eines
Zeichens gespeichert. Und mit diesem ASCII Code kann man
rechnen. Einzig und alleine die Ein/Ausgabe ist bei einem
char anders. Anstelle der Textreräsentierung der in der Variblen
gespeicherten Zahl, wird die Zahl selbst ausgegeben. Enthält
also ein char den Wert 65, so wird bei einer Ausgabe nicht
'6' '5' an das Ausgabegerät geschickt (also die Codes für
'6' bzw. '5'), sondern 65 ist bereits der Code, der an
das Ausgabegerät weitergegeben wird. Das malt daraufhin,
in Übereinstimmung mit der ASCII Code Tabelle ein 'A' auf
seine Ausgabefläche.
Aber abgesehen davon, sind char ganz normale numerische Objekte
in C, mit denen man rechnen kann. Man rechnet dann halt mit
Codezahlen. Aber 65 / 2 ist auch bei einem char immer noch 32.

von Philipp B. (philipp_burch)


Lesenswert?

> kann ich es in C so realisieren?
>
> adrL = (int)strcat(Buffer[d+5],Buffer[d+6]);
> adrL = (int)adrL;

Eher nein. strcat liefert dir einen Zeiger zurück, wenn du den nach int 
castest, steht in adrL &Buffer[d+5] als Adresse. Für sowas solltest du 
atoi() (Ascii to integer) verwenden. Allerdings müsstest du dazu erst 
einen String aus zwei Zeichen erstellen
1
char temp[3];
2
memcpy(temp, &Buffer[d+5], 2);
3
temp[2] = 0;
4
int adr = atoi(temp);
oder aber, falls du "Buffer" nachher nicht mehr brauchst, den Puffer 
eben direkt anpassen:
1
Buffer[d+7] = 0;
2
int adr = atoi(Buffer[d+5]);

von Karl H. (kbuchegg)


Lesenswert?

Philipp Burch wrote:

>
1
> Buffer[d+7] = 0;
2
> int adr = atoi(Buffer[d+5]);
3
>

Das hat nur einen klitzekleinen Schönheitsfehler.
Es war von Hex-Zahlen die Rede. atoi() kann mit
Hex nichts anfangen.

von Philipp B. (philipp_burch)


Lesenswert?

Ups, nicht bedacht. Dann halt strtoi() oder sowas. Für den Zweck 
allerdings bestimmt Overkill.

von Der G. (jonnyk)


Lesenswert?

Danke für eure antworten

da ich ja auch schon etwas schlauer geworden bin habe ich etwas anderes 
gemacht.

Ich weiss nicht ob das kommplet richtig ist ABER es funktioniert(Sieht 
zumindest danach aus):

//Rechne die erste zahl *0x10 dadurch bekomme ich z.b aus 4 -> 40
adr = (Buffer[d]*0x10);

//addire die zweite zahl dazu wenn es z.b. F ist dann bekomme ich 4F
adr = adr+Buffer[d+4];

//und mit dem cast operator kann man jetzt den entsprächenden integer 
machen
adr = (int)adr;

von Niels H. (monarch35)


Lesenswert?

Der Grosse wrote:
> adr = (Buffer[d]*0x10);
> adr = adr+Buffer[d+4];

was ist d+4 ?!?

Nein, das funktioniert so nicht. ascii Zeichen "0" hat den wert 48 und 
"1"=49.

Deine Funktion würde für "0x10" (wenn d auf die '1' zeigt)
wert=49*16 + 48

Damit wäre das ergebnis 832.

Du kommt nicht drumherum, zur Wandlung eines einzelnen Hexzeichens nach 
Dezimal eine Funktion zu schrieben. Beispielsweise:

uint8_t toNumber (char *buf)
{
   if (buf>=48 && buf<=57) // 0 - 9
   {
        return buf-48;
   }
   if (buf>=65 && buf<=70) // A - F
   {
        return buf-55;
   }
   if (buf>=97 && buf<=102) // a - f
   {
        return buf-87;
   }
   return 255; // illegales Zeichen in buf

}

die Wandlung für "0x10" in Buffer sähe dann so aus: (d zeigt auf '1')

adr=toNumber(Buffer[d])*16;
adr+=toNumber(Buffer[d+1]);

von Der G. (jonnyk)


Lesenswert?

so´n mist habt ihr recht...

man man man
Das macht mich richtig deprimierend ich weiss es alles was ihr schreibt 
aber von selbst komme ich irgend wie nicht drauf.. :-((

Danke für eure hilfe.
(Was nicht heissen soll das es schon alles ist.)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.