Как проверить, заканчивается ли argv[1] определенным символом?

#c

#c

Вопрос:

Я пытаюсь выяснить, как сравнить argv[1] значение с парой тестовых примеров. Я хотел бы посмотреть argv[1] , заканчивается ли оно определенным значением символа. Пока у меня есть следующий код:

 int main(int argc, char * argv[])
{
char strin[250];
int length;
printf("The argument supplied is %sn", argv[1]);
strcpy(strin,argv[1]);
length = strlen(strin);
printf("Testing: %c",strin[length]);
    if( strin[length] = 'b')
    {
    printf("b in the input");
    }

}
  

Но по какой-то причине всякий раз, когда я вводил какие-либо входные данные, срабатывает оператор print. Как мне проверить, равен ли последний символ в аргументе командной строки символу, которому я установил его равным?

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

1. strin[length] -> strin[length - 1]

2. также используйте == вместо = в вашем тесте

3. назначение: strin[length] = 'b' ; сравнение: strin[length] == 'b'

4. Почему вы отредактировали код?

Ответ №1:

В принципе, все, что вам нужно сделать, это следующее:

 int main(int argc, char * argv[]) {
    // check if there's an argument to test
    if (1 > argc) {
        // extract the position of the last character
        int last_pos = strlen(argv[1])-1;
        // compare the last character with the character "b"
        if (0 <= last_pos amp;amp; 'b' == argv[1][last_pos]) {
            printf("Hoora! The input ends with b!");
            return 0;
        } else {
            printf("Bummer… The input does not end with b :(");
        }
    } else {
        printf("there's no argument to test!");
    }
}
  

Теперь, вот краткое изложение того, что не так:

 int main(int argc, char * argv[])
{
char strin[250];
int length;
printf("The argument supplied is %sn", argv[1]);

// you're doing a copy from the first argument into the
// variable strin. If argv[1] is 251 characters, you'll
// overwrite memory, and will cause a "buffer overflow".
// Whenever you need to do strcpy of data input by a user
// use strncpy().
strcpy(strin,argv[1]);

// you're extracting the /length/ of the string, not the /position/
// of the last character, so when you're trying to access at index
// length, you'll get data from one character beyond the array.
length = strlen(strin);

// so here you're seeing a random value from the memory of your computer
printf("Testing: %c",strin[length]);

// here you made a mistake and you're assigning the value 'b' to the
// value beyond the allocated memory for the array. Basically: 
// Here be dragons.

// To avoid that mistake, always put the value you're comparing against
// in a comparaison on the Left Hand Side, and the value you're comparing
// on the right hand side. Then the compiler will yell at you!
    if( strin[length] = 'b')
    {
    printf("b in the input");
    }

}
  

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

1. Вы забыли проверить, что argv[1] это не длина 0 ( last_pos может быть отрицательной).

2. 0 <= last_pos ;P

3. Но это то, что я написал 😇

Ответ №2:

Массивы C основаны на нулевом индексе. Чтобы получить доступ к первому элементу, который вы делаете array[0] , для доступа к 10-му, который вы делаете array[9] .

 printf("Testing: %c",strin[length]);
  

При этом выводится символ 1 после последнего символа в строке, который является нулевым терминатором . (так работают строки C)

 if( strin[length] = 'b')
{
  printf("b in the input");
}
  

Это не сравнивается, вы должны использовать == вместо этого. Это также страдает от той же проблемы, что и выше.

Итак, измените свой доступ [length - 1] и используйте == .

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

1. Для массивов с нулевой индексацией: Да, но зачем вам проверять argv[0] ввод данных пользователем? Его значение определяется процессом запуска (то есть оболочкой). Чтобы проверить предоставленные пользователем аргументы, вы должны начать с argv[1]

2. @EliasVanOotegem Это была не моя точка зрения, моя точка зрения заключалась в том, что OP, возможно, подумал, что [length] будет указывать на элемент length’th , что не так, это -1 .

Ответ №3:

Строки заканчиваются 0, а индексация начинается с 0. Но strlen() не учитывает терминатор.

Так strin[length] всегда 0-терминатор, вам нужно strin[length - 1] получить последний символ. И, конечно, вы можете сделать это только в том случае, если length > 0 значение true .

Сравнения в C выполняются с использованием == оператора, единственным = является присваивание, которое не является тем, что вы хотите.

Также нет смысла копировать строку, вы можете проверить argv[1] напрямую; и strlen() return size_t , нет int .

Ответ №4:

Как уже говорили другие, последним символом в строке является strlen() — 1 . У вас есть еще одна проблема, потому что вы используете strcpy. Если у вас более 250 символов в строке аргумента, это очень небезопасно. Поэтому вам нужно использовать strncpy для безопасности.

 int main(int argc, char * argv[])
{
char strin[250];
int length;
printf("The argument supplied is %sn", argv[1]);
strncpy(strin,argv[1], 250);
length = strlen(strin);
printf("Testing: %c",strin[length-1]);
    if( strin[length] = 'b')
    {
    printf("b in the inputn");
    }
}
  

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

1. Если он просто хочет проверить последний символ, нет необходимости вообще делать копию.

2. @Barmar Да, но я хотел показать ему, что его код опасен.