9
votes

La valeur GetOpt reste null

Je passe mes intrants de programme et je pouvais les voir dans ARGV mais GetOpt ne semble pas avoir l'argument que je m'attends.

C'est comme ça que je gère mon PROG :./my_prog -x -f FileName P >

<snip>
while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
    switch (opt) {
       case 'X':
       case 'f':
                if (optarg == NULL)
                fput("no point of living", fp);         << for debugging

</snip>


4 commentaires

Voyez-vous votre message de débogage pour -x ou pour -f ?


Mais êtes-vous sûr qu'il est le -f et pas seulement une chute à partir de -x ?


sur "-x" Je ne veux rien faire. Tomber à "-f" et capturez le nom de fichier. possible?


Si vous ne voulez rien faire sur -x puis mettre un break juste après son cas .


4 Réponses :


12
votes

Votre chaîne d'argumption n'a pas de: après le x (par exemple X: F), Optarg sera toujours null.

Je ferai également remarquer que dans une déclaration de commutation, vous voudrez une pause après chaque cas (généralement, pas toujours, mais lors de l'analyse généralement des arguments), donc: xxx


6 commentaires

ne devrait pas que le nom de fichier soit Optarg pour -f ??


J'ai "XF" et non "X: F", alors Optarg pour "-x" sera toujours nul, mais pourquoi est-ce null pour "-f" ?? Est-ce parce que je ne brise pas après x ??


Basé sur votre code, je m'attendrais à ce que Optarg ne soit pas nulle lorsque vous évaluez OPT == 'F'. Cela devrait être "nom de fichier". Peut-être poster plus de code?


@hari es-tu en train de dire que cela imprime "Aucun point de vie" deux fois lorsque vous l'exécutez comme ./MY_PROG -X -F FileName? Si tel est le cas, quelque chose d'autre est faux, affichez donc le code d'un exemple compilable complet qui montre ce comportement.


@nos Nope. Il imprime "Aucun point de vie" pour "-f" - ce qui est faux afaik. Il devrait avoir Optarg comme "nom de fichier". Optarg ne devrait pas être nul pour "-f".


Je viens de devoir casser après "x". Merci à tous.



2
votes

Pour qui d'autre arriver à cette page: De http://www.gnu.org/ Logiciel / libc / manuel / html_node / à l'aide-getopt.html # à l'aide-getopt : Un caractère d'option dans cette chaîne peut être suivi d'un colon (':') pour indiquer qu'il faut un argument requis. Si un caractère d'option est suivi de deux colons ('::'), son argument est facultatif; Ceci est une extension GNU.

Donc, dans votre argument, vous pouvez utiliser: "X: F: E: E: D: D:"

avait le même problème.


0 commentaires

2
votes

Je viens de traiter cette question et il apparaît que cette question n'a jamais été entièrement répondue.

Vous devez vous assurer que vous définissez la variable libc externe opterr = 0 code> avant d'appeler getopt code>; Si vous ne le réinitialisez pas et getopt code> avait déjà eu une erreur dans une autre application n'importe où dans votre système qui l'utilisait, il échouera pour l'argument. Je réitérerai également le point existant que, parce que vous n'avez pas de déclaration de pause après case 'x': code> c'est un signe sûr d'un problème car il va tomber. P>

getopt code> ne traite qu'un argument à la fois, de la chute de cas x code> dans la case f code> est une mauvaise chose à faire. Vous devez toujours avoir une pause dans chaque instruction de cas d'un commutateur code> code> sauf si vous êtes absolument certain qu'il devrait tomber (ce qui est très rare dans mon expérience). Comme un autre morceau d'une bonne pratique générale, vous devez toujours entourer des blocs de code dans {} (faire référence à votre conditionnel) à moins que ce ne soit un code> Retour code> instruction ou break code> ou quelque chose qui cause la Débit de programme vers la sortie de la portée du bloc actuel ou parent ou d'entrer une nouvelle portée via une fonction ou un appel de méthode. P>

Je pense que votre option String XF: Ee: DD est bien. Cela indique que: p>

1) Ce qui suit sera simplement des indicateurs d'option qui ont toujours un argument null: xedd p>

2) Les options suivantes nécessiteront un argument: Fe P>

S'il s'agit de la fonctionnalité que vous recherchez, la chaîne d'option donnée convient parfaitement. Si vous utilisez GNU Libc, par l'autre réponse ci-dessus, vous pouvez utiliser :: Après une option de la chaîne d'option pour indiquer que l'option peut avoir un argument, mais ne doit pas avoir à. P>

Donc, en haut de votre fichier, assurez-vous que vous avez au moins: P> xxx pré>

puis juste avant d'appeler getopt code> pour la première fois de votre code, SET OPTERR CODE> à 0. P>

EG P>

opterr = 0;

while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
    switch (opt) {
       case 'X':
       case 'f':
                if (optarg == NULL)
                fput("no point of living", fp);         << for debugging


2 commentaires

Merci d'avoir posté ceci. Je tire mes cheveux en essayant de faire travailler mon code et OPTERR = 0 corrigé.


Si heureux cela vous a aidé. Je me souviens quand je traitais cela depuis longtemps et tout cela me conduisit totalement fou pendant des heures.



0
votes

Je sais que c'est vieux mais j'ai récemment remarqué que j'ai changé de comportement dans la façon dont j'avais l'habitude d'utiliser getopt ans il y a des années. Peut-être que c'était un environnement différent mais je trouve que l'utilisation d'aujourd'hui nécessite que l'optarg soit directement après le drapeau (sans espace) sinon optarg est null.

Utilisation de votre exemple, remplacez ./ MY_PROG -X -F FileName avec ./ my_prog -x -ffilename

Je trouve cela fonctionne bien, même si cela se passe tort. J'espère que cela aide quelqu'un d'autre plus tard. Assurez-vous de l'essayer à la fois.


0 commentaires