Hey
Ich suche verkrampft StringToHex, IntToHex, HexToString und HexToInt in C++. Ich habe schon über 10 Ansätze, aber leider vergebens.. Mein Problem ist es, dass ich bei StringToHex, nicht nur ein Zeichen, sonder einen ganzen String angeben möchte. Außderdem möchte ich, dass ich dann noch bei HexToString und HexToInt der dies automatisch erkennt.
Hoffe ihr versteht was ich meine - oh man, why gibt es nicht solche Funktionen in Includes?
Auch schon Ansätze wären sehr hilfreich
mfg
[C++] StringToHex, IntToHex, HexToString und HexToInt
-
AntiSpeed -
5. Juni 2011 um 20:33 -
Erledigt
-
-
oher soll er denn erkennen, ob Int oder String rauskommen soll, irgendeinen anhaltspunkt msus es ja geben. Abgesehen davon, kann man keine Überladungen machen, wo die Parameter gleich sind, aber die Rückgabe sich unterscheidet, woher soll der Compiler auch wissen was wo gemeint ist. Ich würde dann Pointer übergeben, wo das reingeschreiben werden soll.
Folgendes hab ich schonmal geschrieben, ist aber nicht so gut um es verwenden zu wollen, benutz es lieber um dein eigenes zu schreiben.
Spoiler anzeigen
Code
Alles anzeigenchar* Str2Hex(char *str) { char *ges=""; for(int x=0; x<strlen(str); x++) { BYTE ch=(BYTE)str[x]; char buff[2]; itoa(ch,buff,16); ges=cat(ges,buff); } return ges; } char* Str2Hex(const char *str) { char *ges=""; for(int x=0; x<strlen(str); x++) { BYTE ch=(BYTE)str[x]; char buff[2]; itoa(ch,buff,16); ges=cat(ges,buff); } return ges; } BYTE _HCTI(char cha) { if (cha>='A' && cha<='Z') cha-='A'+'a'; //tolower switch (cha) { case 'f': return 15; case 'e': return 14; case 'd': return 13; case 'c': return 12; case 'b': return 11; case 'a': return 10; default: char bu[2]; bu[1]='\0'; bu[0]=cha; return atoi(bu); } return 0; } char* Hex2Str(char *str) { char *ges=""; for(int x=0; x<strlen(str); x+=2) { BYTE ch; ch=_HCTI(str[x]); ch=ch<<4; ch+=_HCTI(str[x+1]); char buff[2]; buff[1]='\0'; buff[0]=(char)ch; ges=cat(ges,buff); } return ges; } char* Hex2Str(const char *str) { char *ges=""; for(int x=0; x<strlen(str); x+=2) { BYTE ch; ch=_HCTI(str[x]); ch=ch<<4; ch+=_HCTI(str[x+1]); char buff[2]; buff[1]='\0'; buff[0]=(char)ch; ges=cat(ges,buff); } return ges; }
-
Int2Hex ist das einfachste^^
Du musst nur 4er-Gruppen aus den Bits machen. Beispiel, der Integer 91 ist binär 0101 1011
die erste 4er-Gruppe Bits 0101 ergibt dezimal 5, also 5h
die zweite vierergruppe Bits 1011 ergibt dezimal 11, also Bh
91 dezimal ist also 5Bh -
Int2Hex ist das einfachste^^
Das gibt es doch auch schon als itoa mit basis 16 oder sprintf Die Performance sollte aber besser sein, wenn man eine spezialisierte Funktion erstellt. -
Leider kann ich nicht BYTE benutzen, ich benutze C::B mit MinGW.
Hat jmd eine andere Lösung?
Ihr würdet mir sehr weiterhelfenEdit:
Ich habe Char2Hex so gelöst, aber wie kann ich ihn wieder zurück konvertieren? -
du kannst einfach char stattdessen benutzen und dementsprechend die casts anpassen
-
Uhm, ich hab da einen Fehler (was denn anpassen?). Leider zeigt mir C::B nix and und das Programm stürtzt ab.
Code
Alles anzeigenchar* Str2Hex(char *str) { char *ges;; for(int x=0; x<strlen(str); x++) { char ch=str[x]; char buff[2]; itoa(ch,buff,16); ges=strcat(ges,buff); } return ges; } char _HCTI(char cha) { if (cha>='A' && cha<='Z') cha-='A'+'a'; //tolower switch (cha) { case 'f': return 15; case 'e': return 14; case 'd': return 13; case 'c': return 12; case 'b': return 11; case 'a': return 10; default: char bu[2]; bu[1]='\0'; bu[0]=cha; return atoi(bu); } return 0; } char* Hex2Str(char *str) { char *ges=""; for(int x=0; x<strlen(str); x+=2) { char ch; ch=_HCTI(str[x]); ch=ch<<4; ch+=_HCTI(str[x+1]); char buff[2]; buff[1]='\0'; buff[0]=(char)ch; ges=strcat(ges,buff); } return ges; }
-
1. Du returnst pointer auf lokale Variablen (löst Fehler aus)
2. Du schreibt in nicht alloziierten Speicher (löst den Absturz aus)Arbeite mehr mit Buffern.
So geht bei mir alles:
Spoiler anzeigen
C
Alles anzeigen#include <stdio.h> #include <iostream> using namespace std; char CharToSingleHex(char a, bool uppercase = true) { a &= 0x0f; //Unnötige obere 4 Bits löschen if (a>=0 && a<=9) //Für Hex-Zahlen return '0'+a; //Zahlen sind in einer Reihe ('0'+5 ergibt '5') if (uppercase && a>=10 && a<=16) //Wenn Großbuchstaben und im Buchstabenbereich return 'A'+a-10; //Buchstaben sind in einer Reihe ('A'+1 ergibt 'B'), 10 muss vorher weg if (!uppercase && a>=10 && a<=16) return 'a'+a-10; return 0; //Für den Fall eines Codefehlers } void StringToHex(const char *str, char *buffer, int buffersize, bool uppercase=true) { int i=0; for (int a=0; (i+1)<buffersize && str[a]; i+=2, ++a) { buffer[i] = CharToSingleHex(str[a]>>4, uppercase); //Obere 4 Bits buffer[i+1] = CharToSingleHex(str[a], uppercase); //Untere 4 Bits } if (i<buffersize) //0 am Ende hinzufügen { buffer[i]=0; } else //Fehlermeldung { puts ("StringToHex - Buffer is too small"); } } int HexToInt(char c) { if (c>='0' && c<='9') //Wenn c eine Zahl ist return c-'0'; // '5'-'0'=5 else if (c>='A' && c<='F') //Wenn c ein Buchstabe ist return c-'A'+10; // 'B' - 'A' = 1 else if (c>='a' && c<='f') //nochmal für Kleinbuchstaben return c-'a'+10; //ansonsten: return -1; } void HexToString(const char *hex, char *buffer, int buffersize) { int i=0; for (; i<buffersize && hex[i*2] && hex[i*2+1]; ++i) { char c = HexToInt(hex[i*2])<<4 | HexToInt(hex[i*2+1]); buffer[i] = c; } if (i<buffersize) //0 am Ende hinzufügen { buffer[i]=0; } else { puts ("HexToString - Buffer is too small"); } } int main() { //char* hex = "48616C6c6F202b2035"; //Hallo + 5 char hex[50]; StringToHex("Hallo + 5", hex, 50); cout<<hex<<endl; char buffer[50]; HexToString(hex, buffer, 50); cout<<buffer<<endl; system("PAUSE"); }
-
Vielen Dank
Nunja das ist genau das was ich wollte, aber wie kann ich nun dies als "wirkliches Hex" (also int 0x..) abspeichern? Also ich habe soetwas, dabei wird aber auch wirklich der Char und nicht der Hex-Wert übertragen. Also in au3 muss man eine File ja binär öffnen für eine Binary, der ja eigentlich Hex ist.
-
Ich hab noch nie mit Dateien und fstream gearbeitet.
Dafür verwende ich immer die alten C-Funktionen aus stdio.h: fopen, fclose, fread, fwrite, fseek, ftell, fputs,fprintf.
-
Gehen wir hier von eben aus :D:
Code
Alles anzeigenint main () { FILE * pFile; pFile = fopen ("myfile.txt","bw"); if (pFile!=NULL) { fputs ("AF41",pFile); fclose (pFile); } return 0; }
Aber dies funktioniert genau so wenig und "AF41" wird als Text und nicht als Hex abgespeichert, obwohl ich 'b' als Parameter angegeben habe. -
Der unterschied beim zusätzlichen b ist nur gering.
Ohne das b werden alle Zeilenumbruche CR (\n) zu CRLF (\n\r).Um wirklich binärdaten zu schreiben, würde ich auch kein fputs nehmen, sondern fwrite.
-
Aber dies funktioniert genau so wenig und "AF41" wird als Text und nicht als Hex abgespeichert, obwohl ich 'b' als Parameter angegeben habe.
Selbstverständlich wird es als "Text" gespeichert. Auch eine Textdatei ist eine binäre Datei, so wie alle Dateien.
Zahlensysteme existieren nur im Kopf. Der Computer versteht nur Nullen und Einsen.
Du möchtest jetzt vier Bytes Text als zwei Bytes Hex speichern.
Deine vier Bytes ASCII "AF41" binär: 0100 0001 (=A) 0100 0110 (=F) 0011 0100 (=4) 0011 0001 (=1).Gruß
Greenhorn -
Marthog:
Vielen Dank , aber ich bekomm ohne praktisches Bsp das iwie nicht auf die Reihe (ja auch mit der Referenz nicht) !?
Ich versteh nicht ganz wie das funkioniert soll:Zitat -
erzeugt nur einen buffer und ist damit erstmal nicht so wichtig.
AF41 kann man so binär abspeichern:
Die beiden Zahlen bei fwrite geben die Elementgröße an (1 wegen char) und die Anzahl der Elemente (2). Also zweimal ein byte.
EDIT: Der Buffer muss um 1 größer sein, damit auch die übliche 0 am Ende eines Strings noch daranpasst. Sie wird aber nicht mit in die Dtaei geschrieben.
-
Ich habe aber mit deinem Code ein Compilfehler:
Spoiler anzeigen
C
Alles anzeigen#include <iostream> #include <string> #include <stdio.h> using namespace std; int HexToInt(char c) { if (c>='0' && c<='9') //Wenn c eine Zahl ist return c-'0'; // '5'-'0'=5 else if (c>='A' && c<='F') //Wenn c ein Buchstabe ist return c-'A'+10; // 'B' - 'A' = 1 else if (c>='a' && c<='f') //nochmal für Kleinbuchstaben return c-'a'+10; //ansonsten: return -1; } void HexToString(const char *hex, char *buffer, int buffersize) { int i=0; for (; i<buffersize && hex[i*2] && hex[i*2+1]; ++i) { char c = HexToInt(hex[i*2])<<4 | HexToInt(hex[i*2+1]); buffer[i] = c; } if (i<buffersize) { buffer[i]=0; } else {puts ("HexToString - Buffer is too small");} } int main () { FILE * pFile; pFile = fopen ("myfile.txt","wb"); if (pFile!=NULL) { //fputs ("AF41",pFile); //char* binary = "AF41"; char *buffer = new char[3]; HexToString("AF41", buffer, 3); fwrite(pFile, buffer, 1, 2); } return 0; }
Dieser lautet:Code\Documents\CodeBlocks Projects\substr\main.cpp||In function `int main()':| \Documents\CodeBlocks Projects\substr\main.cpp|35|error: invalid conversion from `char*' to `size_t'| \Documents\CodeBlocks Projects\substr\main.cpp|35|error: initializing argument 2 of `size_t fwrite(const void*, size_t, size_t, FILE*)'| \Documents\CodeBlocks Projects\substr\main.cpp|35|error: invalid conversion from `int' to `FILE*'| \Documents\CodeBlocks Projects\substr\main.cpp|35|error: initializing argument 4 of `size_t fwrite(const void*, size_t, size_t, FILE*)'| ||=== Build finished: 4 errors, 0 warnings ===|
-
-
Du bist einfach ein Genie. Danke, danke, danke .