Char aus String



  • Hallo,

    ich würde gerne in der main-Funktion:

    int main(int argc, char *argv[])
    {
    }
    

    einen eingegebenen "String" als Character interpretieren, es soll vom Benutzer ein Buchstabe eingegeben werden (Kommandozeile), welcher dann weiterverwendet wird, also z.b. ./datei.exe e beispiel.txt

    e ist ein Buchstabe und Argument von Main, auf der Position argv[1], da auf [0] der Programmname gespeichert ist. wie kann ich das e aus diesem string in ein char umwandeln?

    gibt es da so eine Möglichkeit wie bei Ziffern das atol, wo man ins long umwandelt?

    danke für eure Hilfe



  • Äh...du kannst argv[1] wie einen ganz normalen String verwenden. Wenn du sein erstes Zeichen haben willst, ist das argv[1][0]. Du solltest natürlich vorher sicherstellen, dass argc > 1 ist, und vermutlich wäre es sinnvoll, auch zu verlangen, dass argv[1][1] == '\0' ist, um Eingaben wie ./datei.exe einvielzulangerparameter foo.txt vorzubeugen.



  • ich überprüfe sowieso, dass mind 3 argumente übergeben wurden, programmname, buchstabe und datei die verwendet wird.

    habe es jetzt so gemacht, dass ich in

    char ch = argv[1][0];

    den buchstaben speichere.

    mein fehler war, dass ich zwar alles richtig gespeichert habe, jedoch vergessen habe, dass sich durch das zusätzliche argument buchstabe die position der datei im argv um 1 verändert hat und auf argv[2] steht.

    deshalb hatte ich auch keine ausgabe, funktioniert jetzt aber einwandfrei.

    danke für die schnelle hilfe.


  • Mod

    Vermutlich magst du dir mal GNU Getopt angucken, dann brauchst du diese Standardaufgabe nicht jedes Mal neu selber zu implementieren. Die Kommandozeile muss dafür (im Gegensatz zu deinem Beispiel) im Unix-Stil sein, aber dieser Stil hat durchaus einige Vorteile und außerdem ist dieser Stil weit verbreitet und daher konsistent mit vielen anderen Programmen.



  • nur meine persönliche, bescheidene Meinung, aber:
    Für Anfänger (dazu zähle ich mich natürlich auch) ist es meiner Meinung nach immer sinnvoller (unter fachkundiger Anleitung, damit man nicht von Grund auf falsch "lernt", die Funktionalität hinter selbst banalen, schon gegebenen Funktionen zu kennen.

    Wenn man eine eigene, funktionierende, brauchbare (also auch halbwegs performante) "Bibliothek" an eigenen Funktionen aufgebaut hat, die sich im Test auch bewähren konnten, ist man soweit, sich auf die Jahrzehnte lang erprobten Funktionen anderer verlassen zu können, ohne sich vorwerfen lassen zu müssen, man führe Auto ohne Führerschein.

    Sicherlich ist es für den Hausgebrauch okay, zu wissen, dass strcmp auf irgendeine Art und weise "Strings compared", aber der Teufel steckt (wie einige Posts unter diesem Thread zu lesen ist) manchmal im Detail und man fährt auf Dauer womöglich besser, wenn man weiß, was man tut 😉

    Also ich parse die Aufrufargumente meiner Programme immer selbst und mit dem entsprechenden Codeblock kann ich ein Grundgerüst für alle zukünftigen C-Programme hernehmen. Bin damit mehr als zufrieden und die Portabilität wird sicherlich nicht vernachlässigt.


  • Mod

    getopt ist jedoch nicht trivial. Einmal ein paar einfache Argumente parsen ist leicht, das sollte man einmal gemacht haben. Aber wenn es etwas komplizierter werden darf, z.B.:

    [b]ps --help[/b]
    ********* simple selection *********  ********* selection by list *********
    -A all processes                      -C by command name
    -N negate selection                   -G by real group ID (supports names)
    -a all w/ tty except session leaders  -U by real user ID (supports names)
    -d all except session leaders         -g by session OR by effective group name
    -e all processes                      -p by process ID
    T  all processes on this terminal     -s processes in the sessions given
    a  all w/ tty, including other users  -t by tty
    g  OBSOLETE -- DO NOT USE             -u by effective user ID (supports names)
    r  only running processes             U  processes for specified users
    x  processes w/o controlling ttys     t  by tty
    *********** output format **********  *********** long options ***********
    -o,o user-defined  -f full            --Group --User --pid --cols --ppid
    -j,j job control   s  signal          --group --user --sid --rows --info
    -O,O preloaded -o  v  virtual memory  --cumulative --format --deselect
    -l,l long          u  user-oriented   --sort --tty --forest --version
    -F   extra full    X  registers       --heading --no-heading --context
                        ********* misc options *********
    -V,V  show version      L  list format codes  f  ASCII art forest
    -m,m,-L,-T,H  threads   S  children in sum    -y change -l format
    -M,Z  security data     c  true command name  -c scheduling class
    -w,w  wide output       n  numeric WCHAN,UID  -H process hierarchy
    

    Dann wird das schon ziemlich komplex, jede Möglichkeit abzudecken. Man möchte dem User schließlich nicht zu stark vorschreiben, wie er seine Argumente schreiben soll. Was bedeutet das vielgenutzte ps aux ? Das kann ich als Mensch ja kaum parsen*. Das Problem ist dabei nicht die Anzahl möglicher Parameter (damit hat ein Computerprogramm kein Problem), sondern die vielen unterschiedlichen Schreibweisen. Es gibt einfache Argumente, kurze Argumente, lange Argumente, Argumente mit verpflichtender Zusatzangabe, Argumente mit optionaler zusatzangabe, Argumente ganz ohne Zusatzangabe, Zusatzangaben die ohne vorherige Option kommen, optionale Zusatzangaben, verpflichtende Zusatzangaben, Zusatzangaben bei denen die Reihenfolge wichtig ist, Argumente bei denen die Reihenfolge wichtig ist, Argumente bei denen die Reihenfolge unwichtig ist, ...

    Und das ist nicht die Ausnahme sondern recht normal, sobald man ein komplexeres Kommandozeilentool baut. Man kann sich ja mit der Erfahrung vom einfachen Parser denken, wie man das wohl programmieren würde, aber eine Bibliotheken kategorisch abzulehnen wäre einfach nur krank.

    *: Wenn du glaubst, die Lösung (ohne zu schummeln) nur mit der hier abgebildeten Hilfe in weniger als 20 Minuten gefunden zu haben, dann ist die Lösung vermutlich falsch.



  • Gut, jetzt passt ps natürlich auch nicht so recht ins getopt-Schema. Da steckt viel Historie drin, die man bei Neuentwicklungen um Himmels Willen nicht nachbauen sollte.

    Die Lösung ist übrigens, dass

    a all w/ tty, including other users
    x processes w/o controlling ttys

    ausgewählt und

    u user-oriented

    angezeigt werden. Die Falle ist, dass nicht

    -a all w/ tty except session leaders
    -u by effective user ID (supports names)

    verwendet werden, weil kein Bindestrich davorsteht. ps -aux ist dementsprechend etwas anderes (zeigt alle Prozesse, die durch -a ausgewählt werden und alle Prozesse, die einem Benutzer namens "x" gehören).


  • Mod

    seldon schrieb:

    Gut, jetzt passt ps natürlich auch nicht so recht ins getopt-Schema.

    Stimmt, doofes Beispiel. Punkt ist, dass man schon ein paar Tage Programmieren müsste, um einen Parser vergleichbarer Qualität und Wiederverwendbarkeit zu programmieren.


Anmelden zum Antworten