Почему мой цикл останавливается на первом аргументе (символе argv) в C?

#arrays #c #loops #cs50

Вопрос:

Я не могу понять, почему мой код останавливается на первом символе аргументов командной строки. Я думаю, что проблема в цикле, мне нужно проверить, является ли аргумент командной строки цифрой, поэтому первая и вторая части не важны. Спасибо и извините за беспорядок, я новичок в этом деле.

 int main(int argc, string argv[])
{
    // checking if there is more than one command-line argument
 
    if (argc != 2)
    {
        printf("Usage: ./caesar keyn");
        return 1;
    } 
    else 
    {
       // checking if command-line argument is a number
      for (int i = 0, n = strlen(argv[1]); i < n; i  )
      {
          printf("%cn", argv[1][i]);
          if (isdigit(argv[1][i])) 
          {
              return 0;
          }
          else 
          {
              printf("Usage: ./caesar keyn");
              return 1;
          }
          
      }
      
      
    }
        

    
} 
 

Комментарии:

1. Вы возвращаетесь оттуда main , где заканчивается программа. Вы, конечно, не это имели в виду?

2. нет, это не так, но когда я печатаю argv[1][i] , он печатает только первый символ.

3. Это потому, что вы return в каждом случае if/else . Это означает, что программа завершается каждый раз при первом цикле/символе. Если вы не хотите, чтобы он заканчивался, измените хотя бы одно из return утверждений на что-то другое. Что именно вы хотите isdigit , чтобы сделал настоящий случай?

4. Запоминание argc == 2 означает 1 , что для программы есть аргумент. argv[0] это всегда имя запускаемого исполняемого файла…

Ответ №1:

Вы делаете a return в допустимом случае, поэтому вы проверяете только первый символ argv[1] .

Вы не хотите завершать цикл в допустимом случае, накапливая значение.

Вот несколько переработанных кодов:

 #include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

// so we don't have to include cs50.h ...
typedef char *string;

int
main(int argc, string argv[])
{

    // checking if there is more than one command-line argument
    if (argc != 2) {
        printf("Usage: ./caesar keyn");
        return 1;
    }

    // checking if command-line argument is a number
    int keyval = 0;
    for (char *cp = argv[1];  *cp != 0;    cp) {
        if (! isdigit(*cp)) {
            printf("Usage: ./caesar keyn");
            return 1;
        }

        // accumulate the number as we go along, digit-by-digit
        keyval *= 10;
        keyval  = (*cp - '0');
    }

    printf("keyval=%dn",keyval);

    return 0;
}
 

Вот альтернативный способ:

 #include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

// so we don't have to include cs50.h ...
typedef char *string;

int
main(int argc, string argv[])
{

    // checking if there is more than one command-line argument
    if (argc != 2) {
        printf("Usage: ./caesar keyn");
        return 1;
    }

    // checking if command-line argument is a number
    for (char *cp = argv[1];  *cp != 0;    cp) {
        if (! isdigit(*cp)) {
            printf("Usage: ./caesar keyn");
            return 1;
        }
    }

    // we can use a standard function to get the value
    int keyval = atoi(argv[1]);
    printf("keyval=%dn",keyval);

    return 0;
}
 

Вот еще один способ:

 #include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

// so we don't have to include cs50.h ...
typedef char *string;

int
main(int argc, string argv[])
{

    // checking if there is more than one command-line argument
    if (argc != 2) {
        printf("Usage: ./caesar keyn");
        return 1;
    }

    // checking if command-line argument is a number
    char *cp;
    int keyval = strtol(argv[1],amp;cp,10);

    // invalid digit found
    if (*cp != 0) {
        printf("Usage: ./caesar keyn");
        return 1;
    }

    printf("keyval=%dn",keyval);

    return 0;
}
 

Обратите внимание, что strtol отрицательное значение (например -37 ) будет признано допустимым. Поэтому, если отрицательные значения неприемлемы, нам потребуется дополнительная проверка [непосредственно перед действительными printf ]:

 // negative value found
if (keyval < 0) {
    printf("Usage: ./caesar keyn");
    return 1;
}