Hallo,
ich fange gerade an mich mit C zu beschäftigen.
Ich habe auf der Console schon die üblichen Hallo Welt Programme
compiliert und ausgeführt.
Nun kann ich dem Programm ja auch Parameter übergeben.
Mal angenommen ich möchte dem Programm 2 integer übergeben.
Eine normale Funktion würde so aussehen
1
int addiere(int wert1, int wert2) {
2
int ergebnis = wert1 + wert2;
3
return ergebnis
4
}
Bei der main Funktion habe ich Probleme die Argumente zu filtern
1
int main(int argc, char* argv[]) {
2
3
return 0;
4
}
Wie kann ich damit arbeiten?
argv sind doch Pointer auf Strings.
Muss ich die Strings zu Zahlen zusammensetzen? Das ist doch ein
Gefrickel ohne Ende.
Wieso kann da nicht auch stehen
Kommandozeilenparameter sind strings.
Darum bekommst du strings.
Denn:
Woher sollte das Betriebssystem wissen, ob da ein Name, oder ob da eine
Zahl kommt.
C Anfänger schrieb:> Gefrickel
atoi()
Nun ja,
da gibts einfach zu viele Möglichkeiten. Der nächste will einen String
und zwei floats übergeben, wieder einer will drei string übergeben, der
dritte will 4 floats, ein bool und ein flag übergeben.... Merkste was?
^^
du bekommst leider alles nur als char* und musst das dann konvertieren.
Sollte nicht so schwer sein.
C Anfänger schrieb:> Kann mir jemand erklären warum das im Anhang einen Fehler schmeißt?
Weil es keinen 2ten Parameter gibt, greifst du auf Speicher zu, welcher
nicht deinem Programm zugeordnet ist.
Es könnte die MMU sein, welche sich auf Umwegen bei dir beschwert.
C. W. schrieb:> Falsche Toolchain zum Image des Pi
Blödsinn...
OK, KA, kann die falsche ToolChain sein...
Ist aber hier nicht das Problem.
char* argv[] sollte 2 Zeiger enthalten.
Unser "Autor: C Anfänger (Gast)" versucht einen dritten Zeiger zu
nutzen. Dieser ist ungültig, und das bekommt er auch um die Ohren
gehauen.
Also alles richtig so.
C Anfänger schrieb:> Kann mir jemand erklären warum das im Anhang einen Fehler schmeißt?
Dein Aufruf: ./test 1,2
Parameter werden durch ein Leerzeichen getrennt und nicht durch ein
Komma. Daher hast Du hier genau einen Parameter und nicht zwei
übergeben.
Dabei gilt:
- argc ist die Anzahl der Argumente inkl. Programmname, also 2.
- argv[0] ist der Name des Programms, also "./test"
- argv[1] ist das erste Argument, also "1,2"
- argv[2] gibt es nicht und damit gibts einen Segfault.
Fazit:
Deine Parameterausgabe in main() macht mindestens einen dicken Fehler
und das Programm crasht.
Um Dir weiter zu helfen, zeige den Inhalt Deines Programms, damit wir
nicht weiter herumraten müssen. Aber bitte nicht als Foto, sondern als
ASCII-Text.
Frank M. schrieb:> Parameter werden durch ein Leerzeichen getrennt und nicht durch ein> Komma.
Vielen Dank das war der Fehler, super Erklärung.
Frank M. schrieb:> Um Dir weiter zu helfen, zeige den Inhalt Deines Programms, damit wir> nicht weiter herumraten müssen.
Verstehe ich nicht. Du hast mein Problem zu 100% gelöst.
Das vollständige Programm und die Ausgabe hatte ich bereits oben
gepostet.
Frank M. schrieb:> Aber bitte nicht als Foto, sondern als> ASCII-Text.
Aus dem Pi kan ich nicht einfach rauskopieren. Der Weg mit dem Bild
erschien mir der schnellste zumal mein Programm super simpel ist und ich
kein Filezilla oder ähnliches installiert habe.
C Anfänger schrieb:> argv sind doch Pointer auf Strings.> Muss ich die Strings zu Zahlen zusammensetzen? Das ist doch ein> Gefrickel ohne Ende.
Bei langen Parameterlisten oder solchen von unterschiedlicher Länge kann
das durchaus aufwändig werden. Deswegen gibt es zum Beispiel vom
GNU-Projekt die Bibliotheken getopt und argp [1], oder für C++
Boost.Program_options.
[1]
https://www.gnu.org/software/libc/manual/html_node/Parsing-Program-Arguments.html
Sheeva P. schrieb:> Deswegen gibt es zum Beispiel vom GNU-Projekt die Bibliotheken getopt> und argp [1],
Nur zur Info:
getopt ist keine GNU-Erfindung, sondern schon wesentlich älter und kommt
ursprünglich von UNIX System III, stammt also aus dem Anfang der 80er.
Natürlich gibt es da eine Adaption im GNU-Projekt.
Die eigentliche Innovation war getopt_long(), welches tatsächlich aus
dem GNU-Projekt stammt. Damit waren dann neben den Optionen, welche aus
lediglich einem Buchstaben bestanden (wie "ls -i") dann auch längere
Optionsnamen möglich - wie zum Beispiel "ls --inode".
Frank M. schrieb:> Sheeva P. schrieb:>> Deswegen gibt es zum Beispiel vom GNU-Projekt die Bibliotheken getopt>> und argp [1],>> getopt ist keine GNU-Erfindung, sondern schon wesentlich älter und kommt> ursprünglich von UNIX System III, stammt also aus dem Anfang der 80er.
Stimmt, das hatte ich fast vergessen. Danke für den Hinweis!
Frank M. schrieb:> - argv[2] gibt es nicht und damit gibts einen Segfault.
argv[2] gibt es schon. Aber es ist ein Nullzeiger. Die Liste der
Kommandozeilenargumente ist Nullterminiert.
Rolf M. schrieb:> argv[2] gibt es schon. Aber es ist ein Nullzeiger. Die Liste der> Kommandozeilenargumente ist Nullterminiert.
Ja, das ist korrekt. Aber wenn man sich daran hält, dass das letzte
Argument argv[argc - 1] ist, braucht man diese Information nicht. Diese
zusätzliche "Absicherung" ist genaugenommen sogar redundant.
Den Raspi kann man über Netzwerk ans Internet anhängen. Dann kann man
auf dem Raspi selber in diesem Forum browsen. Das geht alles schon mit
den Standard-Images (Raspian).
Code kann man dann mit copy/paste einfach kopieren. Also kein Bedarf für
Bildschirm-Photos.
PittyJ schrieb:> Dann kann man auf dem Raspi selber in diesem Forum browsen.
Das geht auch einfacher. Einfach auf dem PC, mit dem man im Internet
ist, per PuTTY oder einer anderen Terminalemulation eine Sitzung auf dem
PI eröffnen.
Das hat den Vorteil, dass man als Anfänger kleinere Beispielprogramme im
Internet direkt per Copy&Paste testen kann.