Buffer to Int... aber etwas anderes
-
Kennt jmd einen schnelleren/ besseren/ anderen Weg, als bisher die, die ich mir ueberlegt hab!?
-
escapete schrieb:
An jeder Position steht eine bestimmte Zahl, die vorher durch eine formatierte Ausgabe mittels %4i etc. eingehalten wurde.
char buffer[50] = {"11301146 3213200 200014050 120 4035139001"};
Ich brauche aus dem oberen Buffer folgende Werte:
11
30
11
46
32
13200[...]Kannst Du das Prinzip skizzieren, welche Werte du rausgefischst haben möchtest? Immer zweistellig, außer es hängen ein paar Nullen dran? Oder werden nur die letzten Zeichen sonderbehandelt? Oder anders gefragt: wie bestimmst Du die Länge für deinen StrToInt-Aufruf?
Vielleicht reicht es ja, den Puffer nur einmal anzusehen und nicht mehrfach (einmal zur Längenbestimmung und einmal zur Umwandlung). Und: bist Du dir sicher, daß das die Stelle ist, die die Laufgeschwindigkeit deines Programms am meisten beeinflußt?
-
Vielleicht sollte ich sagen, dass ich den Buffer aus einer Datei auslese...
eine moeglichkeit ist mittels des sizeof(member) der struct:
struct charPaket{ char zeit_start_stunde[2]; // 11 char zeit_start_minute[2]; // 30 char zeit_ende_stunde[2]; // 11 char zeit_ende_minute[2]; // 46 char temperatur[3]; // 32 char spannung_akku[5]; // 13200 char strom_zuleitung[5]; // 200 char last_ladebetrieb[1]; // 0 char winkel_horizontal[3]; // 40 char widerstand[3]; // 35 char spannung_vergleichspanel[5]; // 13900 char summertimeflag[1]; // 1 };
natuerlich koennte ich auch al/les ueber defines machen, da die laenge fest ist...
es muessen alle Werte ausgelesen werden und in integer werte gewandelt werden..
-
Warum willst du deine Struktur nicht binär schreiben und lesen? Wäre erstens eleganter und zweitens schneller.
Greetz, Swordfish
-
weil diese daten auch in excel importier werden muessen, somit brauch ich asci zeichen in der txt
-
bei dieser struct fehlen die null-terminierungen. irgendwie nutzlos. *gedanke*
ich empfehle scanf.
-
Mal so 'ne Idee (ich hab nämlich nichts gefunden, dass man bei sscanf() auch Längen angeben kann, zumindestens nicht in den Linux-Manuals, aber scanf() nutze ich auch eher selten):
(1) Ich gehe mal davon aus, dass Du den kompletten Buffer irgendwo zur Verfügung hast und den Inhalt später nicht noch einmal benötigst (sonst kopierst Du ihn einfach in einen Arbeits-Buffer um, es geht auch anders, doch das später).
(2) Der Buffer hat irgendwie am Ende ein 0x00 (sonst sorgst Du dafür).
(3) Du fängst einfach von hinten an. Du weißt ja die genaue Position, die kannst Du nämlich etwa so bestimmen:
pos = &paket.summertimeflag[0] - &paket.zeit_start_stunde[0]; // oder irgendwie anders
Dann liest Du mit dieser Position aus dem Buffer, z.B.:
zeit_start_stunde = atoi(&buffer[pos]);
(4) Anschließend setzt Du ein 0x00 auf den Beginn des eben eingelesenen Wertes:
buffer[pos] = (char) 0x00;
und liest jetzt den zweitletzten Wert ein mit:
pos = &paket.spannung_vergleichspanel[0] - &paket.zeit_start_stunde[0];
(...)
und das setzt Du fort bis zum ersten Element und hoffst, dass atoi() irgendwie schneller implementiert ist als Deine Routine (Du kannst natürlich auch sscanf() nehmen, ich befürchte aber, das Ding ist langsamer). Wenn das langsamer ist als Deine Version, schaltest Du mal den Optimizer ein und hoffst noch einmal.
Der Buffer hat danach natürlich überall einige 0x00 drin, aber vielleicht ist das egal. Anderenfalls kannst Du ja auch den Buffer umkopieren (s.o.) oder das mit 0x00 überschriebene Zeichen zwischenspeichern und nach der atoi() Operation wieder restaurieren. Das geht natürlich etwas langsamer, aber mit solch einer Methode kannst Du dann natürlich auch den Buffer von vorne beginnend interpretieren.
P.S.: Das Ganze kann man natürlich noch eleganter machen, indem man die einzelnen Positionen in ein separates Array packt, alle Platzhalter für die integer Werte ebenfalls in ein Array und dann mit einer Schleife und einem Index arbeitet (oder mit einem Array bestehend aus Tupeln <position,int-Platzhalter>).
-
Hallo!
Guck mal, ob Du für Deinen Compiler die Option "Data Alignment" (so heisst das beim BC++B) einstellen kannst. Setzte die auf "Byte". Dann wird Dein Struct in einer "Reihe" angelegt. Ergänze dann noch die Leerzeichen als einzelnes Char. Jetzt brauchst Du nur noch den Buffer auf den Struct zu kopieren und kannst dann alle Elemente direkt ansprechen.
-
Integer werden sowie so nur auf 0 grenzen, Short auf 0 und mod%2 grenzen und char ueberall hingelegt. Es koennte das Problem des Padding Bytes auftreten.
Ausserdem loest es ncih das Problem, dass ich es als INT anstelle von ASCII brauche. Programmiere uebrigrens unter Linux...
-
escapete schrieb:
Ausserdem loest es ncih das Problem, dass ich es als INT anstelle von ASCII brauche. Programmiere uebrigrens unter Linux...
z.B. char buffer[50] = {"11301146 3213200 200014050 120 4035139001"};
z.B. hol Dir die 5 Token wandele sie in Integer-Zahlen 5 unsigned int,
Mit den unsigned int kannste rechnen (Integerdivision) und die Ergebnisse abspeichern.
11301146/1000000 = 11
(11301146-(111000000))
301146/10000 = 30
(301146-(3010000)
1146/100 = 11
(1146-11*100)
46 = 46usw. usw.
-
escapete schrieb:
Ausserdem loest es ncih das Problem, dass ich es als INT anstelle von ASCII brauche. Programmiere uebrigrens unter Linux...
Es gibt die Funktion atoi.
-
Hatte dabei so etwas im Auge. Musste dann aber feststellen, dass die Längen der struct member micht mit den Längen der Zahlen übereinstimmen. Aber vielleicht hilft Dir die Idee trotzdem irgendwie.
struct charPaket{ char zeit_start_stunde[2]; // 11 char zeit_start_minute[2]; // 30 char zeit_ende_stunde[2]; // 11 char zeit_ende_minute[2]; // 46 char Del_1[1]; char temperatur[3]; // 32 char spannung_akku[5]; // 13200 char Del_2[1]; char strom_zuleitung[5]; // 200 char Del_3[8]; // Nicht benotigte Daten ?? char last_ladebetrieb[1]; // 0 char Del_4[1]; char winkel_horizontal[3]; // 40 char widerstand[3]; // 35 char spannung_vergleichspanel[5]; // 13900 char summertimeflag[1]; // 1 }; int main(int argc, char* argv[]) { struct charPaket Paket ; int i_zeit_start_stunde = 0 ; int i_temperatur = 0 ; char buffer[50] = {"11301146 3213200 200014050 120 4035139001"}; strncpy( (char*) &Paket, buffer, sizeof( buffer ) ); strncpy( buffer, Paket.zeit_start_stunde, sizeof( Paket.zeit_start_stunde)); buffer[sizeof(Paket.zeit_start_stunde)] = '\0' ; i_zeit_start_stunde = atoi( buffer ); strncpy( buffer, Paket.temperatur, sizeof( Paket.temperatur)); buffer[sizeof(Paket.temperatur)] = '\0' ; i_temperatur = atoi( buffer ); return 0; }
-
#include <stdio.h> int main(void) { char foo[100]; sscanf("hallo", "%3s", foo); puts(foo); return 0; }
viel einfacher.