Henrik Wellschmidt schrieb:> Ich raffs nicht ...>> ich erstell mir einen Zeiger aus einem FD auf ein String,
Was ist denn ein "Zeiger aus einem FD"?
> ptr=strstr(buffer, "1-0:21.7.0*255");> printf(ptr);>> 1-0:21.7.0*255(+00023*W)> 1-0:21.7.0*255(+00023*W)> 1-0:21.7.0*255(+00023*W)>> Super! Aber nun will ich die Zahl in den Klammern extrahieren mit>> char value[6];> strncpy(value, ptr+16, 5);>> Und egal was ich mache -> Segmentation fault.
Hast du auch daran gedacht, das '\0' anzuhängen?
Rolf Magnus schrieb:> Was ist denn ein "Zeiger aus einem FD"?
Hallo Rolf,
also ich lese mit read() aus einem 'File Fescriptor' in ein
char array (buffer) ...
strstr() liefert dann einen Zeiger auf die Fundstelle
im char array (buffer).
Das wollte ich damit sagen ;-)
Hast Du Rolfs Frage gesehen?
Rolf Magnus schrieb:>> Und egal was ich mache -> Segmentation fault.>> Hast du auch daran gedacht, das '\0' anzuhängen?
Was kommt noch nach der strncpy-Anweisung, eine Ausgabe mit printf?
Volkmar
Volkmar Dierkes schrieb:> Hast Du Rolfs Frage gesehen?
Ja, kann ich aber noch nicht zuordnen ...
> Was kommt noch nach der strncpy-Anweisung, eine Ausgabe mit printf?
Erstmal noch nischt ... ich wollte dann mit atof[] in ein Float wandeln
und dann ein eine andere Funktion schicken ...
Henrik Wellschmidt schrieb:> Volkmar Dierkes schrieb:>> Hast Du Rolfs Frage gesehen?>> Ja, kann ich aber noch nicht zuordnen ...
Strings müssen nullterminiert sein. Ein strncpy kopiert zwar ein \0 des
Originalstrings mit, wenn es einen kompletten String kopiert, aber wenn
der Quellstring länger ist als die angegebene Maximallänge, dann hängt
es keins an.
>> Was kommt noch nach der strncpy-Anweisung, eine Ausgabe mit printf?>> Erstmal noch nischt ...
Dann dürfte aber auch kein Segfault passieren. Der kommt erst, wenn du
mangels String-Ende-Zeichen über das Ende hinaus liest.
Rolf Magnus schrieb:> Strings müssen nullterminiert sein. Ein strncpy kopiert zwar ein \0 des> Originalstrings mit, wenn es einen kompletten String kopiert, aber wenn> der Quellstring länger ist als die angegebene Maximallänge, dann hängt> es keins an.
Ahh!
1-0:21.7.0*255(+00023*W)
|1|-|0|:|2|1|.|7|.|0|*|2|5|5|(|+|0|0|0|2|3|*|W|)|\0
strncpy(value, ptr+16, 5);
| | | | | | | | | | | | | | | | |0|0|0|2|3| | | |\0
Fehlt also hier ^
|0|0|0|2|3|
Ich wollte aber danach eigentlich gleich:
>> ranhängen ?!
Na dann setz halt hinten in value ein 0 Byte ein
strncpy(value, ptr+16, 5);
value[5] = '\0';
Egal was strncpy gemacht hat, jetzt ist das Zeug im Array value ganz
sicher ein String, weil sichergestellt ist, dass da auf jeden Fall eine
0-Terminierung existiert.
Und du solltest den Pointer, den dir strstr gegeben hat,
sicherheitshalber auch gegen NULL prüfen :-)
PS: Wärs nicht besser und auch einfacher, nach der öffnenden Klammer '('
suchen zu lassen?
Karl Heinz Buchegger schrieb:>> strncpy(value, ptr+16, 5);> value[5] = '\0';>>> Egal was strncpy gemacht hat, jetzt ist das Zeug im Array value ganz> sicher ein String, weil sichergestellt ist, dass da auf jeden Fall eine> 0-Terminierung existiert.>> Und du solltest den Pointer, den dir strstr gegeben hat,> sicherheitshalber auch gegen NULL prüfen :-)>> PS: Wärs nicht besser und auch einfacher, nach der öffnenden Klammer '('> suchen zu lassen?
Hallo Karl Heinz ...
Segmentation fault :(
1
while(1){
2
3
res=read(fd,buffer,sizeof(buffer)-1);
4
5
if(res>=0){
6
buffer[res]=0;
7
8
ptr=strstr(buffer,"1-0:21.7.0*255");
9
10
charvalue[10];
11
strncpy(value,ptr+14,5);
12
value[5]='\0';
13
14
15
}
16
}
Ich denke das liegt an dem zeiger ptr 'strncpy(value, ptr+14,5);'
In den beispielen verwenden die immer 'char arrays' keine pointer
auf ein 'char arry' ...
Mist.
In deinem letzten Code:
Liest read() genug Zeichen ein? Wenn read() einen Fehler zurückliefert,
dann wird 'buffer' nie 0-Terminiert und du liest u.U. über das buffer
ende.
Findet strstr() auch wirklich den gesuchten string? Ansonsten ist ptr
ein NULL pointer der beim Zugriff zu einem segfault führt.
Henrik Wellschmidt schrieb:> Ich raffs nicht ...
Tja, Stringverarbeitung war schon immer eine der besonderen Stärken von
C.
W.S.
(dem heut abend beim Tempranillo nach Stänkern zumute ist)
Apropos char* Pointer: versuche es doch mal mit
strncpy(value, &buffer[16], 5);
vielleicht verschafft dir das ne Erkenntnis.
Thomas Miletich schrieb:> In deinem letzten Code:>> Liest read() genug Zeichen ein? Wenn read() einen Fehler zurückliefert,> dann wird 'buffer' nie 0-Terminiert und du liest u.U. über das buffer> ende.>> Findet strstr() auch wirklich den gesuchten string? Ansonsten ist ptr> ein NULL pointer der beim Zugriff zu einem segfault führt.
Ja, das passt alles ... ich greif ja nur auf buffer zu
wenn 'if (res >=0)'
1
res=read(fd,buffer,sizeof(buffer)-1);
2
3
if(res>=0){
4
buffer[res]=0;
Das kommt 5sekündlich über die Schnittstelle rein ->
1
/HAG5eHZ010C_EHZ1WA02
2
3
1-0:0.0.0*255(1095110000152759)
4
1-0:1.8.0*255(000005.2786)
5
1-0:96.5.5*255(82)
6
0-0:96.1.255*255(0000152759)
7
1-0:32.7.0*255(232.15*V)
8
1-0:52.7.0*255(232.16*V)
9
1-0:72.7.0*255(000.00*V)
10
1-0:31.7.0*255(000.10*A)
11
1-0:51.7.0*255(000.21*A)
12
1-0:71.7.0*255(000.00*A)
13
1-0:21.7.0*255(+00023*W)
14
1-0:41.7.0*255(+00042*W)
15
1-0:61.7.0*255(+00000*W)
16
1-0:96.50.0*0(67)
17
1-0:96.50.0*1(07CF)
18
1-0:96.50.0*2(19)
19
1-0:96.50.0*3(09)
20
1-0:96.50.0*4(25)
21
1-0:96.50.0*5(1A)
22
1-0:96.50.0*6(003D381B300AF9003D00490200009F80)
23
1-0:96.50.0*7(00)
24
!
Und
ptr = strstr(buffer, "1-0:21.7.0*255");
printf(ptr);
sucht mir schoen das was ich brauche ...
versuche mal das hier, achte auf das '&' bei value.
1
charvalue[10];
2
strncpy(&value,ptr+14,5);
3
value[5]='\0';
Wenn ich mich nicht irre, mußt Du der strncpy-Funktion ja eine Adresse
übergeben, wo der String hingeschrieben werden soll. Aber da value kein
Pointer ist, sondern eine Array of char, brauchst Du die Adresse davon.
Volkmar
Henrik Wellschmidt schrieb:> Und dann verlässt es mich ...
Das einzige was dich verlässt ist, dass dein printf offenbar eine
Sicherung gegen NULL-Pointer hat ....
UND DEIN CODE NICHT !
Frag jetzt endlich mal den Pointer ab, den du von strstr kriegst. Denn
das kann ich aus 300km Entfernung sehen, dass in der Hälfte deiner Daten
der Suchstring gar nicht vorkommt. Und in dem Fall liefert dir strstr
einen NULL-Pointer! Und mit einem NULL Pointer kannst du nicht weiter
arbeiten!
Bei ausnahmslos jeder Suche muss man immer damit rechnen, dass der
gesuchte Wert nicht vorhanden ist! Auch du musst damit rechnen! So wie
alle anderen auch!
Und buffer ist hoffentlich ein char Array!
(Immer diese HickHack Technik nur Ausschnitte aus einem Programm zu
zeigen. Was ist da so toll drann? Ist das wirklich cool, wenn wir auf
der anderen Seite des Monitors Rätselspielchen spielen müssen?)
1
charbuffer[100];
2
3
...
4
5
while(1){
6
7
res=read(fd,buffer,sizeof(buffer)-1);
8
9
if(res>0){
10
buffer[res]='\0';
11
12
printf("received >%s<\n",buffer);
13
14
ptr=strstr(buffer,"1-0:21.7.0*255");
15
if(ptr!=NULL){
16
charvalue[6];
17
strncpy(value,ptr+16,5);
18
value[5]='\0';
19
20
printf("'%s' -> '%s'\n",buffer,value);
21
}
22
}
23
}
Und ich schätze mal, das alles funktioniert überhaupt nicht, weil gar
nicht garantiert ist, dass read immer eine komplette Zeile liefert.
read() interessieren deine Zeilen nämlich nicht, der liefert was da ist,
bzw. füllt dir den Buffer randvoll an. Verwende fgets. Dann bist du
zumindest dieses Problem los. fgets teilt die eingehenden Daten schön in
Zeilen auf und liefert dir immer eine komplette Zeile.
Wenn du fgets nimmst, musst du deinen open durch einen fopen austauschen
und den close gegen einen fclose.
>> versuche mal das hier, achte auf das '&' bei value.
Quatsch
> übergeben, wo der String hingeschrieben werden soll. Aber da value kein> Pointer ist, sondern eine Array of char, brauchst Du die Adresse davon.
Kauf dir ein C-Buch und lies mal nach wie Arrays übergeben werden.
Henrik Wellschmidt schrieb:> Thomas Miletich schrieb:>> In deinem letzten Code:>>>> Liest read() genug Zeichen ein? Wenn read() einen Fehler zurückliefert,>> dann wird 'buffer' nie 0-Terminiert und du liest u.U. über das buffer>> ende.>>>> Findet strstr() auch wirklich den gesuchten string? Ansonsten ist ptr>> ein NULL pointer der beim Zugriff zu einem segfault führt.>> Ja, das passt alles ... ich greif ja nur auf buffer zu> wenn 'if (res >=0)'
Stimmt. Hab ich aufgrund der fehlerhaften Formatierung falsch gelesen.
Karl Heinz Buchegger schrieb:>Und mit einem NULL Pointer kannst du nicht weiter arbeiten!
Jetzt verstehe ich ....
(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)
(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)1-0:21
.7.0*255(+00000*W)
Thomas Miletich schrieb:> Stimmt. Hab ich aufgrund der fehlerhaften Formatierung falsch gelesen.
Ich weiss, ich habe da grosse Differenzen zum Standard ;-)
Es hilft alles nichts. Du brauchst ein C-Buch und musst es
durcharbeiten. Diese Try&Error Programmierung, das Zusammenkopieren von
Code, das funktioniert vielleicht bei kleinen Programmen (und auch da
nicht besonders gut), aber irgendwann ist ein Punkt erreicht, an dem man
ohne solide gelernte Grundlagen nicht weiter kommt.
> Ich weiss, ich habe da grosse Differenzen zum Standard ;-)
Und warum tust du dann nichts dagegen?
Wenigstens Einrückungen richtig zu stellen, kostet dir nichts. Die sind
aber ein solides und erprobtes Mittel um { } Fehler zu sehen und zu
finden. Erfordert Dispziplin, schon klar. Aber im Vergleich zu dem, was
dir die restliche Programmierung an Disziplin abverlangt, ist das
Pipifax.
Karl Heinz Buchegger schrieb:> Es hilft alles nichts. Du brauchst ein C-Buch und musst es> durcharbeiten. Diese Try&Error Programmierung, das Zusammenkopieren von> Code, das funktioniert vielleicht bei kleinen Programmen (und auch da> nicht besonders gut), aber irgendwann ist ein Punkt erreicht, an dem man> ohne solide gelernte Grundlagen nicht weiter kommt.
Ich habe 4 C-Bücher :-)
Aber es ist halt zu verlockend sich vor den Rechner zu setzen.
Ich verstehe ja ganz gut was hier geschrieben wird und lerne dabei.
Klar, blind Code kopieren wäre wirlich blöde.
Karl Heinz Buchegger schrieb:> bzw. füllt dir den Buffer randvoll an. Verwende fgets. Dann bist du> zumindest dieses Problem los. fgets teilt die eingehenden Daten schön in> Zeilen auf und liefert dir immer eine komplette Zeile.
Hallo Karl Heinz,
Ich habe noch nirgens gesehen, wie man fopen() und tcsetattr() zusammen
bekommt ...
http://en.wikibooks.org/wiki/Serial_Programming/termios
...
Henrik Wellschmidt schrieb:> Ich habe noch nirgens gesehen, wie man fopen() und tcsetattr() zusammen> bekommt ...
Das sollte über die Funktion fileno() gehen.
Henrik Wellschmidt schrieb:> Ich habe 4 C-Bücher :-)>> Aber es ist halt zu verlockend sich vor den Rechner zu setzen.
Ich kann das ja verstehen.
Aber es bringt nichts. Dafür, dass du 4 Bücher hast, schwächelst du
extrem. Um es mal freundlich auszudrücken.
Du musst die Dinger auch durcharbeiten! In einem guten Buch sind am Ende
eines jeden Kapitels Übungen drinnen mit denen man kontrollieren kann,
ob man alles verstanden hat.
> Ich verstehe ja ganz gut was hier geschrieben wird und lerne dabei.
Das was hier geschrieben wird, ist noch nicht mal ein matter Abklatsch
dessen, was es zu den Themenkreisen Files, Strings, deren Zusammenspiel,
Textparsing, Konvertierungen, Pointer, Arrays und der Zusammenhang
Pointer zu Arrays, ... zu sagen gibt. Und das sind in deinem Code gerade
mal 8 Zeilen, die in den Büchern aber 3 bis 5 komplette Kapitel
(teilweise auch kapitelübergreifend) in Anspruch nehmen, mit allem drum
und drann. In Programmiersprachen ist es oft so, dass die Dinge
zusammenhängen, wie Zahnräder in einem Getriebe. Man kann ein Getriebe
nicht dadurch verstehen, indem man sich jedes Zahnrad einzeln ansieht.
Es ist die Gesamtheit aller Räder, die ein Getriebe ausmachen.