Hallo,
für diejenigen, die es interessiert. Ich habe lange verzweifelt an einem
Server, der mir Messdaten aufs Handy spielt als Webseite und der immer
wieder mal einfror, d.h. das Hauptprogramm zur Steuerung der
Balkonsolaranlage zur Speisung ins Netz, in die Batterien oder von den
Batterien ins Netz (mit einem Inverter, der Batterien akzeptiert und den
MPPT abschaltet) lief noch aber nix mehr mit Webanzeige. Aus lauter Not
ein Wifi Relais eingebaut als Reset EIn/Aus. Er stürzte dabei völlig
unregelmäßig ab, mal nach ein paar Stunden, mal erst nach einem Tag usw.
Bis mir dann die idee kam mit der KI "Gemini Advanced" (kostet was aber
gut) mal den ganzen Arduino Code hoch zu laden und analysieren zu
lassen. Da kann man einfach die Dateien reinziehen, muss nichts
abtippen. Die Analyse spuckte vieles aus, u.a. dass die exzessive
Verwendung von String Literalen und String Umwandlungen, die man ja gern
macht bei HTML Seiten Erzeugung um den Riesenstring zu erzeugen, der mit
send an den Client geschickt wird Probleme auf dem Heap erzeugen kann.
denn String nicht nicht nur den Heap sondern erzeugt auch temporäre
lokale Fragmente auf dem Stack, wenn es Float etc umwandelt in Text. Der
Stack ist nur 4bKB gross beim ESP32, die sind schnell voll mit lokalen
Buffern.
Gemini schrieb mir die komplexe Webausgabe um auf Standard C. Irre was
die KI da leistet! Sie machte auf Anhieb alles richtig, schneller als
jeder Mensch das hinkriegen würde. Selbst eine Analyse nach MISRA kann
das Ding durchführen. Da sie den ganzen Code hatte wurde auch Buffer
gleich richtig dimensioniert für die json Ausgabe an weitere Clients,
z.b die Anzeigetafel. If then else Gräber wurden aufgelöst und
verkleinert usw. Und das Ding lief auf Anhieb! Seit Tagen absturzfrei
durch. HTML Code erzeugen mit dieser KI ist ein Kinderspiel, ob Buttons,
javascript, CSS Styles oder was auch immer. Damit kriegt man sehr
komplexe Sachen hin mit dem ESP32.
Falls es also noch jemand nicht glaubt: String ist ein heisses Eisen!
Kann funktionieren, muss aber nicht. Vor allem nicht bei dynamischen
Ausgaben, denn es hat zb. keinen Destruktor, das Zeug stopft den
Speicher zu, bis Absturz.
Wieder was dazugelernt :-) Der Code hier ist komplett KI erzeugt, auch
die Variablennamen wurden angepasst.
1
/* Bei Inverter Betrieb Batterie grau machen */
2
strcat(msg,"Batterie ");// Batterie Text immer hinzufügen
3
dtostrf(Data.UBatterie/2.0,1,1,fbuf);// Konvertiere float zu String
4
if(Flags.fInvertSolarPower)
5
{
6
strcat(msg,"<span style=\"color:#A4A4A4\">");// Graue Schrift wenn Inverter aktiv
7
strcat(msg,fbuf);
8
strcat(msg," V</span><br/>");
9
}
10
else
11
{
12
strcat(msg,fbuf);
13
strcat(msg," V<br/>");// Keine spezielle Formatierung wenn kein Inverter aktiv
Thorsten M. schrieb:> dass die exzessive Verwendung von String Literalen und String> Umwandlungen, die man ja gern macht bei HTML Seiten Erzeugung um den> Riesenstring zu erzeugen
Das ist halt die hässliche und suboptimale Variante.
Liefere doch lieber einfach ein statisches HTML aus. Beim ESP kannst du
die Dateien sogar nachträglich auf das Filesystem laden und neue
Versionen aktualisieren bei Bedarf.
Dann musst du auf ESP Seite rein garnichts ersetzen oder mit Strings
machen.
Sobald das HTML auf PC Seite angekommen ist soll es lieber asynchrone
Requests über JS machen. Dann brauchst du nur relativ kleine JSON
"Strings" mit den aktuellen Prozessdaten zusammensetzen die noch nicht
einmal eine dynamische allokierung von Speicher benötigen.
So sinkt der dynamische Speicherbedarf sehr schnell und die Latenz
sucht.
Wo ist überhaupt die Frage?
So, und um wirklich was zu gewinnen, könntest du die KI das noch auf
einen AsyncHTTPServer umschreiben lassen, unter Verwendung der
Template-Engine, mit HTML, CSS und JS auf dem Dateisystem.
Die Herangehensweise "Erstmal das ganze HTML im RAM zusammenbauen, und
dann erst raussenden" (Egal ob strcat oder String) passt zwar für so
kleine "Hallo Welt"-Beispiele, kommt aber schnell an ihre Grenzen.
Und ja, das kriegt die KI auch (zumindest großteils) hin.
N. M. schrieb:> Wo ist überhaupt die Frage?
Gibt keine :-) Dachte mir, das könnte jemand interessieren :-) Die
Ablage im Filesystem wäre zu aufwendig, denn es werden viele Dinge erst
berechnet und dann ein String daraus gebaut.
Εrnst B. schrieb:> Die Herangehensweise "Erstmal das ganze HTML im RAM zusammenbauen, und> dann erst raussenden" (Egal ob strcat oder String) passt zwar für so> kleine "Hallo Welt"-Beispiele, kommt aber schnell an ihre Grenzen.
Aber für jemand, der das noch nie gemacht hat ist das ja ein Anfang. Die
fortschrittlicheren Dinge lernt man ja erst nachher. Ich haue das alles
als HTML raus oder als großer json Container, je nachdem was im GET
steht. Teilweise auch mit POST, wenn zb Daten in beide Richtungen
fliessen sollen. OTA Update sowieso. Asynchroner Server Code ist
schwerer zu debuggen, damit habe ich noch keine Erfahrungen gemacht.
Thorsten M. schrieb:> Die> Ablage im Filesystem wäre zu aufwendig, denn es werden viele Dinge erst> berechnet und dann ein String daraus gebaut.
Genau das kannst du damit loswerden. In's HTML packst du Variablen wie
z.B
<span id="voltage>%BAT_VOLTAGE%</span>
Speicherst das HTML-File so ins Filesystem, und beim raussenden kannst
du die Variable mit dem aktuellen Wert ersetzen lassen.
Und das als Stream, es muss nie das ganze HTML auf einmal in den RAM.
=> Kein Problem mit sehr großen Dateien, kein Problem mehrere Requests
gleichzeitig zu bearbeiten.
Oder du machst das HTML gleich komplett statisch, und aktualisierst die
Werte per fetch/json, websocket, SSE, ... wie von Mani vorgeschlagen.
Die KI hat dir deinen Vorschlaghammer durch einen Pflasterstein ersetzt.
Gut, der ist leichter erhältlich, vielleicht auch handlicher. Schonmal
ein Fortschritt.
Zum Schrauben reindrehen gehen beide irgendwie, schön ist keine Lösung.
Wenn du die KI vorsichtig in Richtung Schraubendreher schubst, findet
die auch was Passenderes.
Thorsten M. schrieb:> Dachte mir, das könnte jemand interessieren :-)
Wie gesagt, mach es nicht so. Dann funktioniert das auch auf deutlich
kleineren uC als einem ESP.
Thorsten M. schrieb:> Die Ablage im Filesystem wäre zu aufwendig
Eben gerade nicht. Ist viel einfacher weil es sich vorab auch einfach am
PC entwickeln und debuggen lässt.
> denn es werden viele Dinge> erst berechnet und dann ein String daraus gebaut.
Das kannst du ja machen. Aber du musst das ja nicht auf dem schwächsten
Glied (ESP) machen. Die HTML einfach so wie sie ist zu übertragen und
nachträglich die Prozessdaten nachladen ist viel einfacher und
Ressourcen schonender.
N. M. schrieb:> Das kannst du ja machen. Aber du musst das ja nicht auf dem schwächsten> Glied (ESP) machen. Die HTML einfach so wie sie ist zu übertragen und> nachträglich die Prozessdaten nachladen ist viel einfacher und> Ressourcen schonender.
Ich behalte es im Kopf dass es so geht. Aber da muss ich mich erst
einarbeiten. Webprogrammierung ist Neuland für mich, bin froh dass ich
was angezeigt bekomme und das Daten hin und her laufen. Sobald die
Notwendigkeit besteht schaue ich mir das mal an.
Im grunde stehen da texte wie
Spannung = x.yz Volt
und Infotexte über den betriebsmode, sowie Bargraphen aus * und #, die
anzeigen wie voll der Akkku ist.
Thorsten M. schrieb:> Der> Stack ist nur 4bKB gross beim ESP32, die sind schnell voll mit lokalen> Buffern.
Das ist doch Unsinn.
Der Stack ist so gross, wie Du ihn machst, natürlich je nach
RAM-Ausstattung des ESP. Auf jeden Fall erheblich mehr als nur 4kB.
Thorsten M. schrieb:> Irre was> die KI da leistet!
Der Code ist irre. Irre scheiße. Eine wilde strcat-Orgie. Alleine schon
die Verwendung von strcat(). Dann noch ohne die aktuelle Belegung des
Puffers mit zu zählen. Statt dessen der Glaube an:
> Da sie den ganzen Code hatte wurde auch Buffer> gleich richtig dimensioniert
Sicher, sicher ... Sogar wenn die KI wirklich für den gegebenen Fall
richtig mit gerechnet hat (hast du das selber nachgerechnet oder
behauptest du das nur?), spätestens wenn jemand anfängt an den Strings
was zu ändern ist die ganze KI-Berechnung fürn Arsch.
Der Code bettelt dann förmlich nach einem Pufferüberlauf weil er nicht
robust geschrieben ist. Echter Scheißdreck.
> Falls es also noch jemand nicht glaubt: String ist ein heisses Eisen!
Es hilft ungemein zu wissen was man tut, statt sich von einer KI
verarschen zu lassen. Ehrlich, als offensichtlicher Anfänger rumzutröten
wie man solchen Code zu schreiben hat ist lachhaft.
> Wieder was dazugelernt :-)
Nein, du hast dich von einer KI verarschen lassen.
Hannes J. schrieb:> , du hast dich von einer KI verarschen lassen
Er hat sein Problem schneller gelöst, als er es ohne KI hätte können.
Also alles richtig gemacht.
Hannes J. schrieb:> Der Code ist irre. Irre scheiße. Eine wilde strcat-Orgie.
Es ist ist in diesem Forum nur eine Frage der Zeit, wann die "Helden"
mit narzisstischer Persönlichkeitsstörung auftauchen und jeden Thread in
den Dreck ziehen, wo nicht alles so gemacht wird, wie sie es meinen.
Gut, dass ich den Alptraum solche asozialen Kollegen zu haben schon
lange hinter mir weiß. Ich beende daher meine Teilnahme in diesem Fred
und wünsche alles Gute bis irgendwann mal wieder.
Εrnst B. schrieb:> Genau das kannst du damit loswerden. In's HTML packst du Variablen wie> z.B> <span id="voltage>%BAT_VOLTAGE%</span>
Hast du mal einen Link wo man sich da einarbeiten kann wie ein async.
Server arbeitet und wie man die Daten in diese Platzhalter einpackt?
Thorsten M. schrieb:> Hannes J. schrieb:>> Der Code ist irre. Irre scheiße. Eine wilde strcat-Orgie.>> Es ist ist in diesem Forum nur eine Frage der Zeit, wann die "Helden"> mit narzisstischer Persönlichkeitsstörung auftauchen und jeden Thread in> den Dreck ziehen, wo nicht alles so gemacht wird, wie sie es meinen.> Gut, dass ich den Alptraum solche asozialen Kollegen zu haben schon> lange hinter mir weiß. Ich beende daher meine Teilnahme in diesem Fred> und wünsche alles Gute bis irgendwann mal wieder.
Die Worte von Hannes sind schon sehr drastisch, und das geht so nicht.
In der Sache hat er aber recht.
Thorsten M. schrieb:> Ich beende daher meine Teilnahme in diesem Fred ...
Das hast du ja nicht lange durchgehalten 😄
Thorsten M. schrieb:> Hast du mal einen Link ...
Komisch, dass man mit solchen Probleme schon vor 20 Jahren umgehen
konnte.
Damals gab es den SitePlayer, basierend auf einem 20MHz-8051-Derivat.
Wer faul ist, braucht ne KI statt des eigene Hirnschmalzes.
Das sieht ja gruselig aus, diese strcat Orgie. Spaghetticode at its
best.
Warum nimmt man nicht einfach sprintf, um die Ausgaben in einem Rutsch
zu erzeugen?
Es ist auch praktisch, wenn Ausgaben immer nach dem gleichen Schema
erfolgen, dann kann sie auch der Mensch besser parsen.
Dann kann man sich dafür Hilfsfunktionen schreiben, denen dann nur die
Unterschiede übergeben werden.
Thorsten M. schrieb:> Der Code hier ist komplett KI erzeugt, auch> die Variablennamen wurden angepasst.
Und der Code ist großer Mist, weil er strcat benutzt. Damit gibt es
überhaupt keinen Schutz vor Pufferüberläufen.
Wie groß ist "msg"?
Eben. Funktionen wie strcpy, strcat oder auch sprintf sollte man
konsequent vermeiden, außer in Fällen, wo ganz offensichtlich ist, daß
das Ziel niemals überschrieben werden kann.
Stattdessen verwendet man strncpy, strncat und snprintf.
Thorsten M. schrieb:> Es ist ist in diesem Forum nur eine Frage der Zeit, wann die "Helden"> mit narzisstischer Persönlichkeitsstörung auftauchen und jeden Thread in> den Dreck ziehen, wo nicht alles so gemacht wird, wie sie es meinen.
So kann man natürlich auch reagieren. Ist dann halt nur blöd, wenn man
a) nichts gelernt hat und b) der Code einem auf die Füße fällt.
Peter D. schrieb:> Warum nimmt man nicht einfach sprintf, um die Ausgaben in einem Rutsch> zu erzeugen?
Die 2025 Variante davon wäre fmt::format (oder std::format).
https://en.cppreference.com/w/cpp/utility/format/format
Der kleinste ESP32 hat meines Wissens nach 520kB RAM, ich verstehe nicht
wieso man da nicht einfach mit std::string arbeitet?
Ich hab z.B. eine kleine Anwendung die ein "Captive Portal" liefert. Im
Code wird hierzu statisches HTML mit "{}" Plathaltern hinterlegt. Ein
Element darin kann etwa so aussehen:
Hallo,
man sollte eine abschätzbare Mindestgröße des Strings anlegen. Im Grunde
kennt man die Größe die man benötigt + etwas Reserve. Das wirkt der
dynamischen Speicherreservierung entgegen. Was auf dem PC egal ist, ist
auf einem µC nicht egal. Der Umgang damit ist entscheidend. Man lernt
immer dazu.
Thorsten M. schrieb:> Falls es also noch jemand nicht glaubt: String ist ein heißes Eisen!
Das ist mir beim ESP8266 aufgefallen, mein erster Kontakt zu Arduino.
Dass man schnell zu viel Speicher belegt war mir eigentlich schon vorher
klar. Aber die vielen praktischen Methoden dieser Klasse können den Heap
je nach Anwendung dermaßen fragmentieren, dass nach einiger Zeit trotz
freiem Speicher nichts mehr geht.
Ich bevorzuge []char und die zugehörigen Funktionen der standard C
Bibliothek. Sie sind weniger komfortabel, aber es ist offensichtlicher,
was dabei im Speicher passiert.
Die Stream-Methoden readString() und readStringUntil() sind auch gemein,
denn sie können mehr Daten lesen, als in den Stack passen. DOS Angriffe
leicht gemacht :-)
Sherlock 🕵🏽♂️ schrieb:> Die Stream-Methoden readString() und readStringUntil() sind auch gemein,> denn sie können mehr Daten lesen, als in den Stack passen. DOS Angriffe> leicht gemacht :-)
Stack?
Nee..
Die nutzen den Heap.
Thorsten M. schrieb:> solche asozialen Kollegen
OT: was bitte soll an den bisherigen Reaktionen asozial oder
narzisstisch sein? Meinungsverschiedenheiten und die Darstellung von
Unzulänglichkeiten oder Verbesserungsmöglichkeiten haben auch rein gar
nichts mit asozialem Verhalten oder gar Narzissmus zu tun. Schlimm ist
hingegen, dass Du die Leute hier mit diesen Attributen titulierst.
ciao
Marci
Peter schrieb:> Die Worte von Hannes sind schon sehr drastisch
Finde ich überhaupt nicht. Ja, er ist sehr deutlich geworden, aber sind
wir denn inzwischen so zart besaitet, dass man solch harmloses
Geschimpfe bzw. deren Verfasser gleich als asozial oder narzisstisch
titulieren muss?
Ich habe auch keinerlei Verständnis und bin sehr empfindsam darüber, wie
im Netz bzw. in social media miteinander umgegangen wird. Aber Hannes'
Worte hätte ich jetzt sicher nicht in diese Schublade gepackt.
Wenn natürlich nur noch das Warmduschergeplänkel von ChatGPT(*) als
erträglich eingestuft wird, wird einem ein rauerer Ton verstörend
vorkommen.
Wie gesagt, ich bin auch ein großer Freund höflicher Umgangsformen. Aber
ich habe auf mc schon sehr viel schlimmere Texte gelesen als in diesem
Thread.
ciao
Marci
(*) Das ist jetzt nicht negativ gemeint. Mir gefällt die sehr höfliche
und angenehme Ausdrucksweise von ChatGpt auch. Aber das muss meinetwegen
nicht zum Standard der zwischenmenschlichen Kommunikation werden.
Peter D. schrieb:> Das sieht ja gruselig aus, diese strcat Orgie. Spaghetticode at its> best.> Warum nimmt man nicht einfach sprintf, um die Ausgaben in einem Rutsch> zu erzeugen
Das ist der Maschine sowas von egal! Das ist der gleiche Quark wie mit
den
msg += String(..) + String ("Lalalaa") Gräbern, die sich in hunderten
Programmen finden und auch die Libs strotzen vor Strings.
Für mich sieht das alles ordentlich aus und nachvollziehbar. Außerdem
wird eben der "Riesenstring" gebraucht, der an send übergeben wird und
bei etlichen "Bargraphen", die aus Ascii Zeichen bestehen und die
berechnet werden müssen kommt printf an seine Grenzen.
1. Es läuft einwandfrei durch und hat sich nie wieder aufgehängt
2. Dank KI wenig Arbeit damit gehabt
3. "Schönheit" des Codes interessiert hier niemanden, es muss einfach
nur funktionieren und Platz hat der ESP soviel, dass es wumpe ist.
Danke für den Link, diese Async Sache schaue ich mir mal an, das scheint
doch "fortschrittlicher" zu sein, wenn man es mal durchdrungen hat.
Und der Ton hier ist mir egal, ich bin nur froh solche Leute nicht um
mich haben zu müssen. Den letzten haben wir rausgeworfen, der meinte
andere Kollegen ständig abwerten zu müssen, die seinem "Genie" nicht
huldigen, Narzissmus eben. Ich muss mich da nicht anpassen, ich drehe
mich um und gehe.
1
memset(msg,0,sizeof(msg));/* Wichtig, msg wieder löschen! */
Sorry, der Code geht für mich gar nicht. Mag für ein Hobbyprojekt gehen.
Aber wenn man nach 5 Jahren da Änderungen vornehmen muss, dann fragt man
sich selber, was man damals für einen Mist gebaut hat.
Oder man bekommt solch einen Code vom Kollegen, und darf sich mit
obskuren Fehlern durch kleine Änderungen durchschlagen.
Beispiel:
char colorcode[30];
strcpy(colorcode, "<span style=\"color:#FE2E2E\">"); // Rot
Sobald man nur etwas an dem style ändert, reicht möglicherweise der
Platz in colorcode nicht aus. Da ist doch schon ein Fehler vorbereitet.
Für mich ist das keine defensive, portable Programmierung, sondern
einmaliger Hobby-Müll, der im Keller bleiben sollte.
Aber auf keinen Fall veröffentlicht werden sollte. Davon lernt die KI
nur das schlechte.
Peter schrieb:> Davon lernt die KI> nur das schlechte.
Was interessiert dich die KI? Die brauchst und willst du doch gar nicht.
Ich wiederhole mich: der TE hat alles richtig gemacht.
Thorsten M. schrieb:> Das ist der Maschine sowas von egal! Das ist der gleiche Quark wie mit> den> msg += String(..) + String ("Lalalaa") Gräbern, die sich in hunderten> Programmen finden und auch die Libs strotzen vor Strings.
Schön, wenn jemand C und C++ (oder C# etc.) dureinanderwirft.
Die String-Überladung von "+=" gibt es in C gar nicht (da man da auch
gar nichts überladen kann).
Bei C darf man sich um die Einhaltung von Speichergrenzen selber
kümmern. Die interessieren den Compiler einen Dreck, weil der davon
ausgeht, dass man weiß, was man tut.
Peter schrieb:> Beispiel:> char colorcode[30];> strcpy(colorcode, "<span style=\"color:#FE2E2E\">"); // Rot
Wozu überhaupt erst einen konstanten String in eine Variable kopieren?
Ein Pointer reicht doch:
Thorsten M. schrieb:> memset(msg, 0, sizeof(msg)); /* Wichtig, msg wieder löschen! */
Es reicht völlig aus, nur das 1. Byte zu leeren:
1
msg[0]=0;
Thorsten M. schrieb:
prozent = (int)(((Data.UBatterie / 2.0f) - (UBATT_FULL_RUHE / 2.0f)) /
((BATT_BOOST / 2.0f) - (UBATT_FULL_RUHE / 2.0f)) * 100.0f);
Was soll die "/ 2.0f" Orgie bewirken?
Das kürzt sich doch eh raus.
Klaus schrieb:> Er hat sein Problem schneller gelöst, als er es ohne KI hätte können.> Also alles richtig gemacht.
Bis ihm der Code spätestens nächste Woche auf die Füße fällt, und er
dann noch ratloser da steht, weil er nun gar nicht mehr versteht, was da
eigentlich passiert.
Aber ChatGPT wirds schon irgend wie richten - hoffentlich.
Oliver
Peter D. schrieb:> Thorsten M. schrieb:> prozent = (int)(((Data.UBatterie / 2.0f) - (UBATT_FULL_RUHE / 2.0f)) /> ((BATT_BOOST / 2.0f) - (UBATT_FULL_RUHE / 2.0f)) * 100.0f);>> Was soll die "/ 2.0f" Orgie bewirken?> Das kürzt sich doch eh raus.
Da hast Du recht aber das ist nur für mich, damit ich weiss, dass die
Batteriespannung / 2 geteilt wird. Mir sind die Spannungen von 12V
geläufiger als die von 24V. Musst Du jetzt nicht verstehen, ich habe mir
dabei was gedacht. Das kürzt sich schon beim Kompilieren raus. Im
Übrigen gute Einwürfe aber von "Peda" kenne ich das nicht anders :-)
Thorsten M. schrieb:> Da hast Du recht aber das ist nur für mich, damit ich weiss, dass die> Batteriespannung / 2 geteilt wird.
Man könnte auch einfach den Programmteil kommentieren, wie es sich für
ordentlichen Quellcode gehört.
Bernhard M. schrieb:> Hmm, scheint das mit den _s ist ein Microsoft Vorschlag den sonst> niemand so richtig unterstützt, damit bezweifle ich dass das auf ESP32> geht...
Die _s-Funktionen sind Teil des C11-Standards. Die hat jede C-Toolchain,
die C11 unterstützt, im Gepäck. Auch auf einem ESP32.
C++ ist halt nicht C. Andere Programmiersprache, andere lib-Funktionen.
Da gibt es die _s nicht.
Oliver
Oliver S. schrieb:> Klaus schrieb:>> Er hat sein Problem schneller gelöst, als er es ohne KI hätte können.>> Also alles richtig gemacht.>> Bis ihm der Code spätestens nächste Woche auf die Füße fällt, und er> dann noch ratloser da steht, weil er nun gar nicht mehr versteht, was da> eigentlich passiert.
Wieder die Tatsachen verdreht. Vorher stand er ratlos da und hatte mir
sporadischen Crashes zu kämpfen.
Jetzt läuft es stabil und das Problem ist gelöst.
Dass der Code nicht schön, nicht gut dokumentiert, und im Falle weiterer
Änderungen fehleranfällig ist stelle ich nicht in Abrede.
> Aber ChatGPT wirds schon irgend wie richten
Eben.
Klaus schrieb:> Wieder die Tatsachen verdreht. Vorher stand er ratlos da und hatte mir> sporadischen Crashes zu kämpfen.
Nee. Vorher hatte er Code, dessen Nebenwirkungen ihm unbekannt waren.
Jetzt hat er Code, von dem er gar nichts mehr versteht.
Oliver
Der Vollständigkeit halber, strcat hat 2 Nachteile:
* Man muss aufpassen, dass man den Buffer wirklich gross genug gewählt
hat. Sonst crashts.
* Jedes mal, wenn man strcat aufruft, ist das wie
"strcpy(dest+strlen(dest),src)". Anders gesagt, der String, den man
erweitert, wird jedes mal nach dem 0 byte durchsucht.
(Ich verstehe ehrlich gesagt nicht, warum man strcpy nicht einen Pointer
auf das Ende des Strings zurückgeben liess, aber das ist jetzt nunmal
so, wie es ist)
Daniel A. schrieb:> (Ich verstehe ehrlich gesagt nicht, warum man strcpy nicht einen Pointer> auf das Ende des Strings zurückgeben liess, aber das ist jetzt nunmal> so, wie es ist)
Wenn du das für so sinnvoll hälst, könntest du leicht einen Wrapper
schreiben der das so macht.
Peter D. schrieb:> void make_answer(buff, prolog, value, epilog);
Hier hat Peda ausnahmsweise mal Abstraktion verstanden.
Genau so sollte man es machen: Man macht (String) Funktionen genau für
die aktuelle Applikation. Und da drin kann man dann sämtliche str
Sauereinen veranstalten die man will. Man kann die Implementierung
jederzeit auch auf printf ändern oder auf sonst was. Und man muss genau
in dieser Funktion, und nur dort, nach Fehler und Überläufen in str
Funktionen suchen.
Einfach an zig Stellen im programm mit strcat rumpfuschen ist eben genau
das: Pfusch.
Cyblord -. schrieb:> Daniel A. schrieb:>> (Ich verstehe ehrlich gesagt nicht, warum man strcpy nicht einen Pointer>> auf das Ende des Strings zurückgeben liess, aber das ist jetzt nunmal>> so, wie es ist)>> Wenn du das für so sinnvoll hälst, könntest du leicht einen Wrapper> schreiben der das so macht.
Ja, das ist einfach:
Warum muss eigentlich der komplette Output zuvor in einem riesengroßen
Buffer landen? Man kann durchaus zwischendurch auch mal irgendeine
write-Funktion aufrufen, um schon mal einen Teil des Ausgabestrings
loszuwerden. So kann man die benötigte Buffergröße auf einen sinnvollen
Wert eindampfen.
Möchte man doch erst den kompletten Buffer füllen, dann noch eine
Bemerkung zum vorgeschlagenen strcat() in der C-Variante:
Abgesehen von möglichen Buffer-Overflows ist diese Funktion für große
Buffer extrem ineffizient. Das liegt daran, dass strcat() jedes mal die
aktuelle Stringlänge des Buffers erst ermitteln muss, bevor es dann
etwas anhängen kann. Das macht strlen() in der Regel durch Iteration
über alle Zeichen im Buffer.
Führt man hier aber immer die Länge des Buffers mit, dann wird aus:
1
strcat(buffer,str);
ein:
1
staticintlen=0;
2
...
3
strcpy(buffer+len,str);
4
len+=strlen(str);
Dann wird die Stringlänge nur für die kleinen anzuhängenden Strings
ermittelt und nicht jedes Mal für den riesengroßen Brocken. Das geht
wesentlich schneller.