Hi da.
Wie liegt ein 2d-Array genau im Speicher?
Kann/Darf man z.B. atoi über eine Reihe laufen lassen (Terminiert mit
0)?
Ich habe hier ein Projekt bei dem der alte Programmierer das an etlichen
Stellen gemacht hat.
Ab und an haben wir Controller die nicht antworten.
Also habe ich nun einmal nachgeschaut und gesehen, dass es bei solch
einem problematischen Controller am atoi() liegt.
Wenn ich die Daten in mein eigenes 1d-Array schaufel, läuft es durch.
Source läuft schon so seit 15Jahren...
Beispiel:
> Wie liegt ein 2d-Array genau im Speicher?>> unsigned char ucInputData[10][8];
ucInputData[a][b] liegt an &ucInputData + a*8 + b
> Kann/Darf man z.B. atoi über eine Reihe laufen lassen (Terminiert> mit 0)?
Solange die \0 da ist, kein Problem.
foobar schrieb:> Solange die \0 da ist, kein Problem.
Ich würde da auch mal in die atoi-Source schauen, ob das nicht auch bei
unzulässigen Zeichen abbricht (was es eigentlich tun sollte). Die
Chance, daß das dann trotz fehlender /0 niemals zurückkehrt, ist dann
doch sehr gering.
Und ich würde mal nach Strings der Länge 8 bzw. einer Begrenzung auf 8
Zeichen suchen...
Oliver
Hi!
foobar schrieb:>> Wie liegt ein 2d-Array genau im Speicher?> ucInputData[a][b] liegt an &ucInputData + a*8 + b
Ja, okay - Dann sollte es ja passen.
Gerade auch ein Video dazu gefunden, was es auch gut erklärt:
https://www.youtube.com/watch?v=_j5lhHWkbnQ>> Kann/Darf man z.B. atoi über eine Reihe laufen lassen (Terminiert>> mit 0)?> Solange die \0 da ist, kein Problem.
Ich selbst kam auf die Idee noch nicht, aber dann kommt das Problem
nicht von der Ecke...
Veit D. schrieb:> kontrolliere das Programm auch auf Bereichsüberschreitungen /> Buffer-Overflows. Nicht das im RAM im Nirwarna gelesen bzw. geschrieben> wird.
Leider hat der Controller (M16C) hier keine Debugging-Schnittstelle und
ich muss mich mit Blinky und UART-Ausgaben zufrieden geben :)
Ich habe noch etwas entdeckt nachdem ich jedes Byte des Arrays
ausgegeben habe. Es gibt z.B. auf [0][0] ein Nullbyte. Alle zwei
fortlaufenden Bytes [0][1], [0][2]... ist dieses auch zu sehen.
So kann das mit atoi ja nicht klappen.
...Nur warum ab und an bei verschiedenen Controllern...
Verrückt (RAM kaputt?)
Tobi schrieb:> Wie liegt ein 2d-Array genau im Speicher?
Die liegen hintereinander im Speicher (zumindest wenn es static ist):
int array1[3][2] = {{0, 1}, {2, 3}, {4, 5}};
Speicher -> 0 1 2 3 4 5
Tobi schrieb:> Kann/Darf man z.B. atoi über eine Reihe laufen lassen (Terminiert mit> 0)?
Wie bereits gesagt ist das kein Problem, solange die 0 wirklich da ist.
Je nachdem wo das her komm ist das aber nicht unbedingt robust. Beim
Empfangen kann ja auch mal etwas schief gehen.
Persönlich bevorzuge ich immer die Längenlimitierten String Funktionen
wie z.B. strncmp statt strcmp. Ob es sowas für atoi gibt, weiß ich
gerade nicht.
PS: Ich meine mich zu erinnern das atoi bei Zahlen, die zu groß sind,
undefiniertes verhalten aufweist, vielleicht hat da ja noch wer anders
Infos zu.
Oliver S. schrieb:> foobar schrieb:> Ich würde da auch mal in die atoi-Source schauen, ob das nicht auch bei> unzulässigen Zeichen abbricht (was es eigentlich tun sollte). Die> Chance, daß das dann trotz fehlender /0 niemals zurückkehrt, ist dann> doch sehr gering.>> Und ich würde mal nach Strings der Länge 8 bzw. einer Begrenzung auf 8> Zeichen suchen...
Ok, ich schaue mal quer durch.
...Ein Debugger wäre doch soooo schön nun :)
Kevin M. schrieb:> Wie bereits gesagt ist das kein Problem, solange die 0 wirklich da ist.> Je nachdem wo das her komm ist das aber nicht unbedingt robust. Beim> Empfangen kann ja auch mal etwas schief gehen.
Wenn die /0 fehlt, wird atoi aber über nicht wandelbare Zeichen
stolpern, und dann (hoffentlich) 0 zurückgeben. Der Fall wird ja
(hoffentlich) abgefangen.
Ich würde aber auch mal schauen, ob da die Länge des Input-String
begrenzt wird (und das auf weniger als 8 Zeichen ;) )
Alles in allem stirbt die Hoffnung, wie immer, zuletzt.
Oliver
Tobi schrieb:> Wie liegt ein 2d-Array genau im Speicher?> Kann/Darf man z.B. atoi über eine Reihe laufen lassen (Terminiert mit> 0)?
Allgemein darf in einem 2d-Array an beliebiger Stelle eine \0 im
Speicher stehen. Nur für dein Beispiel, bei dem du offensichtlich zu
wissen scheinst, dass in dem Array nur ASCII-Werten stehen können, macht
die Frage überhaupt Sinn.
atoi() erwartet ein NTBS, das kannst Du erzwingen (sicherstellen), indem
Du ucInputData[...][7] = `\0` setzt (`\0` ist das Sentinel, was bei NTBS
erwartet wird).
Besser wäre natürlich ein
1
std::array<std::array<char,8>,10>ucInputData;
und ein
1
template<autoN>
2
intatoi(conststd::array<char,N>&);
Ansonsten hat atoi() das große Problem, das atoi() `0` liefert, wenn es
die Zeichenkette nicht parsen kann. Man kann also ein gültiges nicht von
einem ungültigen Ergebnis unterscheiden. Das ist broken-by-design.
Besser wäre natürlich
Tobi schrieb:> Es gibt z.B. auf [0][0] ein Nullbyte. Alle zwei> fortlaufenden Bytes [0][1], [0][2]... ist dieses auch zu sehen.> So kann das mit atoi ja nicht klappen.>> ...Nur warum ab und an bei verschiedenen Controllern...> Verrückt (RAM kaputt?)
Big- und Little-Endian Problem?
Wiviel Dezimalstellen hat denn die Zahl?
Oliver S. schrieb:> Wenn die /0 fehlt, wird atoi aber über nicht wandelbare Zeichen> stolpern, und dann (hoffentlich) 0 zurückgeben. Der Fall wird ja> (hoffentlich) abgefangen.
Nein. Dann hört atoi() einfach auf und gibt den bereits ermittelten Wert
zurück. Bei "8ung" wäre das 8.
Tobi schrieb:> Ich habe noch etwas entdeckt nachdem ich jedes Byte des Arrays> ausgegeben habe. Es gibt z.B. auf [0][0] ein Nullbyte. Alle zwei> fortlaufenden Bytes [0][1], [0][2]... ist dieses auch zu sehen.> So kann das mit atoi ja nicht klappen.
Wo kommen denn die Daten her?
Hi Ihr.
Erst einmal vielen Dank für das Mitdenken!
Ich habe einiges getestet und es scheint tatsächlich so zu sein, dass
bei manchen frisch bestückten Controllern der RAM spinnt.
Ich habe das Problem-Array einmal gefüllt und ausgelesen.
Bei dem funktionierenden Controller kommen die korrekten Bytes zurück
(wenn auch meine for/next irgendwo noch patzt :) ).
Bei dem defekten Controller kommen nur zwei, mal drei Bytes zurück.
Je nach dem wie oft ich starte... Auch mit LogicAnalyzer gecheckt.
Beide Ausgaben im Anhang.
1
unsignedinti;
2
unsignedchar*pointbase;
3
unsignedchar*pointa;
4
5
pointbase=&ucInputData[0][0];//Pointer von Array start speichern
6
7
//32+4 * 8 -> 288bytes
8
9
for(i=0;i<250;i++)
10
{
11
pointa=pointbase+i;
12
*pointa=i;//RAM-Speicherstellen setzen 0-250
13
}
14
15
for(i=0;i<250;i++)
16
{
17
pointa=pointbase+i;
18
uart_0_put_uart_mode(*pointa);//RAM-Speicherstellen wieder zurück lesen und via UART ausgeben
19
}
20
21
while(1);
Somit baue ich nun mal ein kleines Testprogramm, dass die Chips im
Nullkraft-Sockel identifizieren kann.
Sch*** Bauteilemangel...
Nun endlich Feierabend.
Cu, Tobi
Wilhelm M. schrieb:> Tobi schrieb:>> Ich habe noch etwas entdeckt nachdem ich jedes Byte des Arrays>> ausgegeben habe. Es gibt z.B. auf [0][0] ein Nullbyte. Alle zwei>> fortlaufenden Bytes [0][1], [0][2]... ist dieses auch zu sehen.>> So kann das mit atoi ja nicht klappen.> Wo kommen denn die Daten her?
Von der UART und externen Programm.
Tobi schrieb:> Ich habe das Problem-Array einmal gefüllt und ausgelesen.> Bei dem funktionierenden Controller kommen die korrekten Bytes zurück> (wenn auch meine for/next irgendwo noch patzt :) ).
Denke nicht: sollte ja mit 0 beginnen.
Tobi schrieb:> Wilhelm M. schrieb:>> Tobi schrieb:>>> Ich habe noch etwas entdeckt nachdem ich jedes Byte des Arrays>>> ausgegeben habe. Es gibt z.B. auf [0][0] ein Nullbyte. Alle zwei>>> fortlaufenden Bytes [0][1], [0][2]... ist dieses auch zu sehen.>>> So kann das mit atoi ja nicht klappen.>> Wo kommen denn die Daten her?> Von der UART und externen Programm.
Ok, aber das ist ja für den obigen Test irrelevant.
Tobi schrieb:> (wenn auch meine for/next irgendwo noch patzt :) ).
Was soll das sein?
C99 liegt schon 23 Jahre zurück, also der alte Code und v.a. Dein
Testprogramm sollte dann schon etwas moderner sein (Stichwort:
Gültigkeitsbereich der Variablen).
Tobi schrieb:> Beide Ausgaben im Anhang.
Ich sehe da nur zwei Pixelhaufen im JPG-Format. Soll man jetzt eine
OCR-SW drauf loslassen, um irgendetwas damit anfangen zu können.
Wilhelm M. schrieb:> Was soll das sein?>> C99 liegt schon 23 Jahre zurück, also der alte Code und v.a. Dein> Testprogramm sollte dann schon etwas moderner sein
Die Aussage ist doch Quatsch. Wie der Themenersteller schon erwähnte,
wurde der originale Sourcecode vor 15 Jahren geschrieben. Damals war C99
sehr wohl der Stand der Technik.
Mark B. schrieb:> Wilhelm M. schrieb:>> Was soll das sein?>>>> C99 liegt schon 23 Jahre zurück, also der alte Code und v.a. Dein>> Testprogramm sollte dann schon etwas moderner sein>> Die Aussage ist doch Quatsch. Wie der Themenersteller schon erwähnte,> wurde der originale Sourcecode vor 15 Jahren geschrieben. Damals war C99> sehr wohl der Stand der Technik.
Genau!
Du hast meine Aussage so gar nicht verstanden ...
Wilhelm M. schrieb:>> Ich habe das Problem-Array einmal gefüllt und ausgelesen.>> Bei dem funktionierenden Controller kommen die korrekten Bytes zurück>> (wenn auch meine for/next irgendwo noch patzt :) ).> Denke nicht: sollte ja mit 0 beginnen.
Ja, theoretisch schon.
Ist aber Quick n dirty programmiert ohne zu checken ob ich das richtig
gemacht habe ;)
Daher ist es für mich erst einmal nicht schlimm, wenn was nicht so ganz
passt (Hatte einfach auch kein Bock mehr irgendwann).
Man sieht jedenfalls sehr gut, dass der merkwürdige Controller seine
Arbeit in keinster Weise verrichtet.
Das reicht mir eigentlich schon zum ausfiltern.
Wilhelm M. schrieb:> C99 liegt schon 23 Jahre zurück, also der alte Code und v.a. Dein> Testprogramm sollte dann schon etwas moderner sein (Stichwort:> Gültigkeitsbereich der Variablen).
Mein Testprogramm ist ein Debug-Teil des kompletten Programmes und auch
in der alten WinXP-IDE geschrieben.
Da ändert sich also nichts.
Forist schrieb:> Ich sehe da nur zwei Pixelhaufen im JPG-Format. Soll man jetzt eine> OCR-SW drauf loslassen, um irgendetwas damit anfangen zu können.
Sehr konstruktiv!
Du bist auch der Meinung das NavyCIS die Pixelhaufen der Nummernschilder
im wahren Leben so knackscharf hin bekommt oder? ;)
Spaß - Aber man kann sehr wohl das erkennen, was man erkennen muß.
Also bitte nicht so unnötig dazwischen quatschen.
Tobi im Feierabend :) schrieb:> Wilhelm M. schrieb:>>> Ich habe das Problem-Array einmal gefüllt und ausgelesen.>>> Bei dem funktionierenden Controller kommen die korrekten Bytes zurück>>> (wenn auch meine for/next irgendwo noch patzt :) ).>> Denke nicht: sollte ja mit 0 beginnen.> Ja, theoretisch schon.> Ist aber Quick n dirty programmiert ohne zu checken ob ich das richtig> gemacht habe ;)
Wie so oft, hast Du mal wieder nicht alles gezeigt!
Ich ging davon aus, dass das der Inhalt von main() ist. Wenn das so ist,
dann ist das von Dir gezeigte Ergebnis eben nicht OK.
Tobi im Feierabend :) schrieb:> Wilhelm M. schrieb:>> C99 liegt schon 23 Jahre zurück, also der alte Code und v.a. Dein>> Testprogramm sollte dann schon etwas moderner sein (Stichwort:>> Gültigkeitsbereich der Variablen).> Mein Testprogramm ist ein Debug-Teil des kompletten Programmes und auch> in der alten WinXP-IDE geschrieben.> Da ändert sich also nichts.
Warum schreibst Du auch Deinen Test-Code so grottig wie der
ursprüngliche Autor? Das zeugt nicht unbedingt von Kompetenz.
Wilhelm M. schrieb:> Wie so oft, hast Du mal wieder nicht alles gezeigt!> Ich ging davon aus, dass das der Inhalt von main() ist. Wenn das so ist,> dann ist das von Dir gezeigte Ergebnis eben nicht OK.
Wie so oft? Wie kommst Du darauf? Kennen wir uns?
Es ist mein Testcode am Anfang der Main.
Das Programm selbst hat ca. 5000 LOC.
Aber das ist ja auch nicht relevant, wenn man in dem kurzen Code snipped
schon sieht, dass was gravierend nicht passt.
Wilhelm M. schrieb:> Warum schreibst Du auch Deinen Test-Code so grottig wie der> ursprüngliche Autor? Das zeugt nicht unbedingt von Kompetenz.
Weil man eben nach einem Tag herumstochern bei solch einem blöden
Problem auch irgendwann keine Lust mehr hat.
Vor allem, wo soll das kleine Ding denn grottig sein?
Es zeigt in Kürze den Fehler auf.
Reicht doch erst einmal, wenn man auch mal Feierabend möchte...
Wilhelm M. schrieb:> Halte mal den Ball flach!
Du hast schon gesehen, dass der Kommentar nicht an Dich ging oder?
Tobi im Feierabend :) schrieb:> Wilhelm M. schrieb:>> Wie so oft, hast Du mal wieder nicht alles gezeigt!>> Ich ging davon aus, dass das der Inhalt von main() ist. Wenn das so ist,>> dann ist das von Dir gezeigte Ergebnis eben nicht OK.> Wie so oft? Wie kommst Du darauf?
Standard in diesem Forum.
> Es ist mein Testcode am Anfang der Main.> Das Programm selbst hat ca. 5000 LOC.> Aber das ist ja auch nicht relevant, wenn man in dem kurzen Code snipped> schon sieht, dass was gravierend nicht passt.
Was hier nicht passt, ist:
1
unsignedcharucInputData[10][8];
Hier haben wir also 180 Bytes (auf dem Stack oder global, kann ich nicht
entscheiden, weil Du mal wieder nicht alles zeigst).
Und im folgenden Snippet schreibst Du gnadenlose über das Ende des
Arrays hinaus. Also, was sollen wir davon halten, wenn solche Basics
nicht passen. Dann wird wohl auch an anderer Stelle was gravierend faul
sein.
1
unsignedinti;
2
unsignedchar*pointbase;
3
unsignedchar*pointa;
4
pointbase=&ucInputData[0][0];//Pointer von Array start speichern
5
//32+4 * 8 -> 288bytes
6
for(i=0;i<250;i++)
7
{
8
pointa=pointbase+i;
9
*pointa=i;//RAM-Speicherstellen setzen 0-250
10
}
11
for(i=0;i<250;i++)
12
{
13
pointa=pointbase+i;
14
uart_0_put_uart_mode(*pointa);//RAM-Speicherstellen wieder zurück lesen und via UART ausgeben
Tobi im Feierabend :) schrieb:> Vor allem, wo soll das kleine Ding denn grottig sein?
Ich hatte Dir oben einen Hinweis gegeben, den Du ggf. übersehen oder
nicht verstanden hast.
Tobi im Feierabend :) schrieb:> Wilhelm M. schrieb:>> Halte mal den Ball flach!> Du hast schon gesehen, dass der Kommentar nicht an Dich ging oder?
Natürlich, und trotzdem schreibe ich was dazu. Es ist ein Forum und
keine P2P-Kommunikation.
Wilhelm M. schrieb:>> Aber das ist ja auch nicht relevant, wenn man in dem kurzen Code snipped>> schon sieht, dass was gravierend nicht passt.> Was hier nicht passt, ist:> unsigned char ucInputData[10][8];>> Hier haben wir also 180 Bytes (auf dem Stack oder global, kann ich nicht> entscheiden, weil Du mal wieder nicht alles zeigst).
Ja, da hast Du recht.
Das habe ich nicht erwähnt.
Die 10/8 Bytes waren anfangs geschätzt, da über mehrere Defines
deklariert und es zu dem Zeitpunkt auch nur um das atoi() ging.
Das hatte ich bei meinem Testcode dann jedoch nachgeschaut und meine
Notiz "//32+4 * 8 -> 288bytes" hinzugefügt.
Sorry.
> Und im folgenden Snippet schreibst Du gnadenlose über das Ende des> Arrays hinaus. Also, was sollen wir davon halten, wenn solche Basics> nicht passen. Dann wird wohl auch an anderer Stelle was gravierend faul> sein.
Wie gesagt, das passt schon :)
Wir haben 288byte Platz.
Wilhelm M. schrieb:> Tobi im Feierabend :) schrieb:>> Vor allem, wo soll das kleine Ding denn grottig sein?>> Ich hatte Dir oben einen Hinweis gegeben, den Du ggf. übersehen oder> nicht verstanden hast.
Scheinbar habe ich das.
Welchen genau meintest Du?
Wilhelm M. schrieb:> Tobi im Feierabend :) schrieb:>> Du hast schon gesehen, dass der Kommentar nicht an Dich ging oder?>> Natürlich, und trotzdem schreibe ich was dazu. Es ist ein Forum und> keine P2P-Kommunikation.
Kein Problem, aber auch das ist eine Unsitte in diesem Forum.
Plötzlich tauchen Leute auf, die über unnützes Zeug herum nörgeln ohne
konstruktiv dazu beizutragen.
Ich kann ihm natürlich nicht unterstellen, dass er es nicht könnte, aber
mit der Aussage das man mit einem OCR den Text lesbarer machen könnte,
unterstreicht es nicht sehr.
Tobi im Feierabend :) schrieb:> Wilhelm M. schrieb:>>> Aber das ist ja auch nicht relevant, wenn man in dem kurzen Code snipped>>> schon sieht, dass was gravierend nicht passt.>> Was hier nicht passt, ist:>> unsigned char ucInputData[10][8];>>>> Hier haben wir also 180 Bytes (auf dem Stack oder global, kann ich nicht>> entscheiden, weil Du mal wieder nicht alles zeigst).> Ja, da hast Du recht.> Das habe ich nicht erwähnt.> Die 10/8 Bytes waren anfangs geschätzt, da über mehrere Defines> deklariert und es zu dem Zeitpunkt auch nur um das atoi() ging.> Das hatte ich bei meinem Testcode dann jedoch nachgeschaut und meine> Notiz "//32+4 * 8 -> 288bytes" hinzugefügt.
Kommentare sind irrelevant, da keine überprüfbare Verknüpfung zum Code
besteht.
> Sorry.
Kein Thema.
Tobi im Feierabend :) schrieb:> Wilhelm M. schrieb:>> Tobi im Feierabend :) schrieb:>>> Vor allem, wo soll das kleine Ding denn grottig sein?>>>> Ich hatte Dir oben einen Hinweis gegeben, den Du ggf. übersehen oder>> nicht verstanden hast.> Scheinbar habe ich das.> Welchen genau meintest Du?
Z.B. Lokalität / Gültigkeitsbereich von Variablen, ...
Wilhelm M. schrieb:> Ansonsten hat atoi() das große Problem, das atoi() `0` liefert, wenn es> die Zeichenkette nicht parsen kann. Man kann also ein gültiges nicht von> einem ungültigen Ergebnis unterscheiden. Das ist broken-by-design.
Ich benutze daher sscanf(), das liefert die Anzahl der fehlerfrei
gelesenen Werte zurück.
Peter D. schrieb:> Wilhelm M. schrieb:>> Ansonsten hat atoi() das große Problem, das atoi() `0` liefert, wenn es>> die Zeichenkette nicht parsen kann. Man kann also ein gültiges nicht von>> einem ungültigen Ergebnis unterscheiden. Das ist broken-by-design.>> Ich benutze daher sscanf(), das liefert die Anzahl der fehlerfrei> gelesenen Werte zurück.
Das sind doch alles Krücken, die zuviel Aufwand verursachen (bei
sscanf() in der Tat nur, wenn man >1 Format-Spezifizierer hat).
Wesentlich besser ist da
https://en.cppreference.com/w/cpp/utility/from_chars
was man auch gut verketten kann (oder man nutzt - wie oben schon
geschrieben - std::optional<>, falls man Output-Parameter vermeiden
möchte).
Wilhelm M. schrieb:> std::
Wie häufig sind deine Ratschläge zwar prinzipiell richtig, helfen aber
einem C-Programmierer nicht wirklich weiter. Und sehr vermutlich wird es
auch hier um C gehen.
Oliver
Oliver S. schrieb:> Wilhelm M. schrieb:>> std::>> Wie häufig sind deine Ratschläge zwar prinzipiell richtig, helfen aber> einem C-Programmierer nicht wirklich weiter. Und sehr vermutlich wird es> auch hier um C gehen.
Naja, dass es um C geht, das steht ja schon in der Überschrift ;-)
Und wie immer erlaube ich mir den Blick etwas zu weiten.
Und eine C-Lib-Funktion wie `int atoi()` gehört einfach auf den Orkus
der Geschichte: den Wert `0`, der zum gültigen Wertebereich eines `int`
gehört, als Fehlerindikator zu verwenden, ist einfach nur Quatsch
(wohlwissend, dass man natürlich zunächst prüfen kann, ob der String
sicher aus `[+-0-9]` zusammensetzt).
Peter D. schrieb:> Wilhelm M. schrieb:>> Ansonsten hat atoi() das große Problem, das atoi() `0` liefert, wenn es>> die Zeichenkette nicht parsen kann. Man kann also ein gültiges nicht von>> einem ungültigen Ergebnis unterscheiden. Das ist broken-by-design.>> Ich benutze daher sscanf(), das liefert die Anzahl der fehlerfrei> gelesenen Werte zurück.
Als Ersatz für atoi gibt es strtol.
Das benutzt auch errno und liefert auch die Position, an der die
Umwandlung stoppt.
Dirk B. schrieb:> Peter D. schrieb:>> Wilhelm M. schrieb:>>> Ansonsten hat atoi() das große Problem, das atoi() `0` liefert, wenn es>>> die Zeichenkette nicht parsen kann. Man kann also ein gültiges nicht von>>> einem ungültigen Ergebnis unterscheiden. Das ist broken-by-design.>>>> Ich benutze daher sscanf(), das liefert die Anzahl der fehlerfrei>> gelesenen Werte zurück.>> Als Ersatz für atoi gibt es strtol.> Das benutzt auch errno und liefert auch die Position, an der die> Umwandlung stoppt.
Stimmt nicht ganz:
- error wir benutzt, wenn ein range-error auftritt (C99 konform)
- bei anderen Fehlern wie nach wie vor `0` zurück gegeben.
Nur bei nicht C99-konformen Implementierungen wird errno == EINVAL
gesetzt:
https://en.cppreference.com/w/c/string/byte/strtolhttps://man7.org/linux/man-pages/man3/strtol.3.html
Wilhelm M. schrieb:>> Als Ersatz für atoi gibt es strtol.>> Das benutzt auch errno und liefert auch die Position, an der die>> Umwandlung stoppt.>> Stimmt nicht ganz:>> - error wir benutzt, wenn ein range-error auftritt (C99 konform)> - bei anderen Fehlern wie nach wie vor `0` zurück gegeben.
Und:
If there were no digits at all,
strtol() stores the original value of nptr in *endptr (and
returns 0). In particular, if *nptr is not '\0' but **endptr is
'\0' on return, the entire string is valid.
> https://man7.org/linux/man-pages/man3/strtol.3.html
Da gibt es auch ein Beispiel.