Je voudrais qu'un utilisateur passe deux paramètres ou le laisse vide. Par exemple:
./program 50 50
ou
./program
Quand j'ai essayé d'utiliser int main(int argc, char *argv[])
, la première chose que j'ai faite a été de changer char *argv[]
En int *argv[]
Mais cela n'a pas fonctionné. Ce que je veux, c'est que l'utilisateur est juste pour entrer deux entiers entre 0 et 1. Donc, si ce n'est pas deux entiers, cela devrait donner une erreur.
J'étais en quelque sorte en train de penser à donner une erreur avec les types (comme j'avais l'habitude de programmer en C #) mais quoi que j'entre, argv [1] serait de type 'char' tout le temps.
Donc ce que j'ai fait c'est
for (int i = 0; i <= 100; i++) {
//printf("%d", i);
if (argv[1] == i) {
argcheck++;
printf("1st one %d\n", i);
}
else if (argv[2] == i) {
argcheck++;
printf("2nd one %d\n", i);
}
Cela ne fonctionne pas aussi bien. De plus, il donne un avertissement lors de la compilation, mais si je change argv
avec atoi(argv[1])
par exemple, alors il donne un défaut de segmentation (core dumped) erreur.
J'ai besoin d'un moyen simple de résoudre ce problème.
ÉDITER:
J'ai donc corrigé avec atoi()
, la raison pour laquelle il donnait un défaut de segmentation était parce que je l'essayais avec une valeur nulle quand je n'ai pas de paramètre. Je l'ai donc corrigé en ajoutant une condition supplémentaire. Mais maintenant, le problème est que si la valeur est disons
./program asd asd
La sortie de atoi(argv[1])
serait alors 0. Existe-t-il un moyen de modifier cette valeur?
N'utilisez pas atoi()
et n'utilisez pas strtol()
. atoi()
n'a pas de vérification d'erreur (comme vous l'avez découvert!) et strtol()
doit être vérifié en utilisant la variable globale errno
, ce qui signifie que vous devez définir errno
à 0, puis appelez strtol()
, puis vérifiez à nouveau errno
pour les erreurs. ne meilleure façon est d'utiliser sscanf()
, qui vous permet également d'analyser n'importe quel type primitif à partir d'une chaîne, pas seulement un entier, et de lire des formats fantaisistes (comme hex).
Par exemple, pour analyser un entier "1435" à partir d'une chaîne:
if (sscanf (argv[1], "%i", &intvar) != 1) {
fprintf(stderr, "error - not an integer");
}
Pour analyser un seul caractère "Z" à partir d'une chaîne
if (sscanf (argv[1], "%c", &charvar)!=1) {
fprintf(stderr, "error - not a char");
}
Pour analyser un flottant "3.1459" à partir d'une chaîne
if (sscanf (argv[1], "%f", &floatvar)!=1) {
fprintf(stderr, "error - not a float");
}
Pour analyser un grand entier hexadécimal non signé "0x332561" à partir d'une chaîne
if (sscanf (argv[1], "%xu", &uintvar)!=1) {
fprintf(stderr, "error - not a hex integer");
}
Si vous avez besoin de plus de gestion des erreurs que cela, utilisez une bibliothèque regex.
Cela fera:
int main(int argc, char*argv[])
{
long a,b;
if (argc > 2)
{
a = strtol(argv[1], NULL, 0);
b = strtol(argv[2], NULL, 0);
printf("%ld %ld", a,b);
}
return 0;
}
Les arguments sont toujours passés sous forme de chaînes, vous ne pouvez pas changer le prototype de main()
. Le système d'exploitation et les machines environnantes passent toujours des chaînes et ne sont pas en mesure de comprendre que vous les avez modifiés.
Vous devez utiliser par exemple strtol()
pour convertir les chaînes en entiers.
Vous voulez vérifier si
sscanf
retournera 0.La logique ci-dessous vous aidera
int main(int argc, char *argv[])
{
int no1 = 0, no2 = 0, ret = 0;
if ((argc != 0) && (argc != 2))
{
return 0;
}
if (2 == argc)
{
ret = sscanf(argv[1], "%d", &no1);
if (ret != 1)return 0;
ret = sscanf(argv[2], "%d", &no2);
if (ret != 1)return 0;
if ((no1 < 0) || (no1 >100)) return 0;
if ((no2 < 0) || (no2 >100)) return 0;
}
//now do your stuff
}
Vous pouvez toujours utiliser atoi, vérifiez simplement si l'argument est d'abord un nombre;)
btw ppl vous dira que goto est evil, mais ils sont généralement soumis à un lavage de cerveau par des non-sensibles "goto is bad", "goto is evil", "goto is le diable " déclarations qui viennent d'être lancées sans être élaborées sur Internet.
Oui, le code spaggethi est moins gérable. Et goto dans ce contexte est d'une époque où il a remplacé les fonctions ...
int r, n, I;
for (I = 0; I < argc; ++I)
{
n = 0;
do
if ( !((argv + I) [n] >= '0' && (argv + I) [n] <= '9') )
{
err:
fprintf(stderr,"ONLY INTEGERS 0-100 ALLOWED AS ARGUMENTS!\n");
return 1;
}
while ((argv + I) [++n] != '\0')
r = atoi(argv[I]);
if (r > 100)
goto err;
}
Les choses que vous avez faites si innocemment sont des erreurs en C. Quoi qu'il en soit, vous devez prendre des chaînes ou des caractères comme arguments et plus tard, vous pouvez faire ce que vous voulez avec eux. Modifiez-les en entier à l'aide de strtol
ou laissez-les être les chaînes et vérifiez chaque caractère de la chaîne dans la plage de 48 to 57
car ce sont les valeurs décimales de char 0 to 9
. Personnellement, ce n'est pas une bonne idée et pas une bonne pratique de codage. Mieux les convertir et vérifier la plage entière que vous souhaitez.