Hallo Leute!
Ich möchte aus einem gegebenen char-Array einen bestimmten Teil
ausschneiden. Dazu suche ich mit einer for-Schleife nach einem
Trennzeichen (in diesem Fall '.'). Der Inhalt vom Anfang des char-Arrays
bis zu dem character vor dem Trennzeichen soll über eine weitere
for-Schleife in einem neuen char-Array gespeichert werden.
Später soll dann mithilfe von atoi() der Inhalt des Arrays in eine
integer-Zahl umgewandelt werden. Das funktioniert auch soweit.
Allerdings sehe ich beim Debuggen einen komischen Wert im char-Array der
immer wieder auftaucht. Hier erstmal mein Code:
Die erste for-Schleife findet die Länge des Arrays heraus (hier
eigentlich unnötig, da sowieso fest) und die Stelle des Trennzeichens
'.'.
Nachdem aber die zweite for-Schleife durchlaufen ist, wird im letzten
Schleifendurchlauf immer noch ein '@' an die letzte Stelle hinzugefügt.
D.h. ich erhalte dann "123456@". Bei der letzten for-Schleife
funktioniert wieder alles bestens.
Weiß jemand woher dieses Zeichen kommt?
Eine weiter Frage: Ist das Nullen der Arrays mit memset() überhaupt
nötig? Wie sieht das ganze bei µC aus?
Schon mal vielen Dank! :)
Andi schrieb:> Weiß jemand woher dieses Zeichen kommt?
ja weil du keine ende vom String hast. Es fehlt ein 0 Byte.
Aber das ganze ist viel zu kompliziert!
das ganze umkopieren ist überhaupt nicht notwenig, atoi hört von selber
auf zu lesen wenn kein Digit mehr kommt.
Peter II schrieb:> Andi schrieb:>> Weiß jemand woher dieses Zeichen kommt?>> ja weil du keine ende vom String hast. Es fehlt ein 0 Byte.>> Aber das ganze ist viel zu kompliziert!>> das ganze umkopieren ist überhaupt nicht notwenig, atoi hört von selber> auf zu lesen wenn kein Digit mehr kommt.
Warum ist dann beim Array foo2 nie so ein Zeichen am Ende?
Danke für den Hinweis mit atoi! Da kann ich mir die Hälfte sparen ;)
Wobei atol natürlich auch ein wenig blöd ist, wenn Du den vollen
Wertebereich von uint32_t nutzen willst. Aber gut. Das Ganze ist sowieso
ein Blödsinn - äh, ein Übungscode zum wegschmeissen, da schadet das nun
auch nichts.
An dieser Stelle sollte Dein Compiler laut meckern:
1
charfoo1[indexDot];
Wenn Du ein Feld definieren willst muss die Größe zur Compilezeit
bekannt sein. indexDot ist aber eine Variable. Definiere das Feld auch
zu SERIAL_BUFFER_SIZE und probiere es noch mal.
Die schon erwähnte Bemerkung mit dem fehlenden '\0' Zeichen stimmt
natürlich auch. Du müsstest mindestens indexDot + 1 als Feldgröße
anlegen.
A. H. schrieb:> An dieser Stelle sollte Dein Compiler laut meckern:> char foo1[indexDot];>> Wenn Du ein Feld definieren willst muss die Größe zur Compilezeit> bekannt sein. indexDot ist aber eine Variable. Definiere das Feld auch> zu SERIAL_BUFFER_SIZE und probiere es noch mal.>> Die schon erwähnte Bemerkung mit dem fehlenden '\0' Zeichen stimmt> natürlich auch. Du müsstest mindestens indexDot + 1 als Feldgröße> anlegen.
Der Compiler sagt dazu nichts...seltsam. Ich dachte die Terminierung mit
dem '\0'-Zeichen wird nur für die Interpretation als String benötigt?
A. H. schrieb:> An dieser Stelle sollte Dein Compiler laut meckern:> char foo1[indexDot];>> Wenn Du ein Feld definieren willst muss die Größe zur Compilezeit> bekannt sein.
nein muss es nicht. Im Aktuellen C und C++ ist das zulässig.
Andi schrieb:> Ich dachte die Terminierung mit> dem '\0'-Zeichen wird nur für die Interpretation als String benötigt?
sie immer notwendig wenn man in C mit Strings arbeitet. Woher soll denn
sonst atoi wissen wo schluss ist.
Peter II schrieb:> A. H. schrieb:>> An dieser Stelle sollte Dein Compiler laut meckern:>> char foo1[indexDot];>>>> Wenn Du ein Feld definieren willst muss die Größe zur Compilezeit>> bekannt sein.>> nein muss es nicht. Im Aktuellen C und C++ ist das zulässig.
OK, man lernt nie aus, meine Standards sagen alle noch etwas anderes.
(Sind aber nicht mehr die neuesten :-) Obwohl ich mir nicht vorstellen
kann, wie der Compiler das macht. Zumindest dürfte es ja im gleiche
Stack-Frame keine weiteren Variablen dahinter mehr geben?!
Oder macht er daraus implizit Pointer, initialisert sie zur Laufzeit mit
dem Stackpointer und schiebt den einfach entsprechend weiter?
A. H. schrieb:> OK, man lernt nie aus, meine Standards sagen alle noch etwas anderes.> (Sind aber nicht mehr die neuesten :-)
VLA (Variable Length Array) gibt es seit C99.
Also auch schon seit 15 Jahren.
Dirk B. schrieb:> A. H. schrieb:>> OK, man lernt nie aus, meine Standards sagen alle noch etwas anderes.>> (Sind aber nicht mehr die neuesten :-)>> VLA (Variable Length Array) gibt es seit C99.>> Also auch schon seit 15 Jahren.
Der letzte Standard (C++), den ich hier habe ist von 2003. Angesichts
der Zeit, die viele Compiler brauchen, um neue Features zuverlässig zu
implementieren, erachte ich das für die meisten Fälle auch noch als
ausreichend. (Da wird für die Deklaration eines Arrays auch noch ein
konstanter Ausdruck verlangt. Wenn es auf die Portabilität des Codes
ankommt würde ich in diesem Fall auch versuchen, mich darauf zu
beschränken.)
Peter II schrieb:> nein muss es nicht. Im Aktuellen C und C++ ist das zulässig.
1
#include<stdint.h>
2
3
intmain(void)
4
{
5
uint8_ti;
6
uint8_tarray[i];
7
for(i=0;i<10;i++)
8
{
9
array[i]=0;
10
}
11
return0;
12
}
mit gcc 4.8.1, -Wall -Werror -pedantic -pedantic-errors -std=c++11
compiliert gibt:
1
error: ISO C++ forbids variable length array 'array' [-Wvla]
Scheint also doch nicht ganz so zulässig zu sein.
Andi schrieb:> Der Compiler sagt dazu nichts...seltsam.
Der compiler sagt da nur was zu wenn du mit -pedantic compilierst. Ohne
-pedantic hält er schön die klappe.
Grüße
Kaj schrieb:> Scheint also doch nicht ganz so zulässig zu sein.
In C99 schon, in C++ bisher nur als gcc-Erweiterung:
"Variable-length automatic arrays are allowed in ISO C99, and as an
extension GCC accepts them in C90 mode and in C++."
Kaj schrieb:> mit gcc 4.8.1, -Wall -Werror -pedantic -pedantic-errors -std=c++11> compiliert gibt:error: ISO C++ forbids variable length array 'array'> [-Wvla]> Scheint also doch nicht ganz so zulässig zu sein.
bei C geht es
-Wall -Werror -pedantic -pedantic-errors -std=c99
test.c:6:11: error: variable 'array' set but not used
[-Werror=unused-but-set-variable]
uint8_t array[i];
Peter II schrieb:> bei C geht es
Ja, habs grad festgestellt, liegt an der stelle am c++ compiler :-/
Tom K. schrieb:> in C++ bisher nur als gcc-Erweiterung
Danke für den hinweis
Tom K. schrieb:> Kaj schrieb:>> Scheint also doch nicht ganz so zulässig zu sein.>> In C99 schon, in C++ bisher nur als gcc-Erweiterung:>> "Variable-length automatic arrays are allowed in ISO C99, and as an> extension GCC accepts them in C90 mode and in C++."
Und um es noch komplizierter zu machen: In C11 ist das Feature nur noch
optional.