Я исправлю, что strcmp эквивалентен (и безопасен) для литералов?

Мы все знаем, что переполнение проблемы может вызвать, и именно поэтому strn * существует - и большую часть времени они имеют смысл. Тем не менее, я видел код, который использует strncmp для сравнения параметров командной строки, например:

if(... strncmp(argv[i], "--help", 6) == 0

Теперь я бы подумал, что это необязательно и, возможно, даже опасно (для более длинных параметров было бы легко исключить символы в литерале).

strncmp останавливается на нулях, а код уже предполагает, что argv [i] имеет нулевое завершение. Любой строковый литерал гарантированно заканчивается на нуль, поэтому почему бы не использовать strcmp?

Возможно, я что-то пропустил, но я видел это несколько раз, и на этот раз он заинтриговал меня достаточно, чтобы спросить.

Ответы

Ответ 1

да, это совершенно безопасно и считается стандартной практикой. Строковые литералы гарантированы для нулевого завершения.

Ответ 2

Вы уверены, что код не предназначен для соответствия "--helpmedosoemthingwithareallylongoptionname"?

Ответ 3

Вы правы.

Кроме того, приведенный вами пример будет соответствовать "--help", но также и всему, что начинается с "--help" (например, "-help-me" ).

Редкий случай, когда чрезмерное == неправильное.

Ответ 4

Насколько я знаю, вы абсолютно правы - нет причин использовать strncmp вместо strcmp. Возможно, люди просто переусердствовали (не обязательно плохо).

Ответ 5

Как говорили другие, strcmp() совершенно безопасен для использования с литералами. Если вы хотите использовать strncmp(), попробуйте следующее:

strncmp(argv[i], "--help", sizeof("--help"))

Пусть компилятор сделает подсчет для вас!

Это будет соответствовать только точной строке "--help". Если вы хотите сопоставить все строки, начинающиеся с "--help" (как это делает ваш код), используйте sizeof() - 1, чтобы не включать последний '\0'.

Ответ 6

Да, наличие литерала ограничивает размер сравниваемых данных до размера литерала. Здесь stncmp избыточен.

Кто-то может сказать, что strncmp - хорошая привычка вступать, но это лишнее из-за проблемы подсчета символов.

Ответ 7

Я бы, наверное, написал что-то вроде этого в C (если я много использовал strncmp и не хотел делать подсчет символов):

if(... strncmp(argv[i], "--help", sizeof("--help") - 1) == 0 

Ответ 8

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

Ответ 9

er... технически не могло произойти подобное?

char *cp1 = "help";
cp1[4] = '!'; // BAD PRACTICE! don't try to mutate a string constant!
// Especially if you remove the terminating null!
  ...
strcmp(some_variable, "help"); 
// if compiler is "smart" enough to use the same memory to implement
// both instances of "help", you are screwed...

Я предполагаю, что это патологический случай и/или мусор, мусор ( "Док, мне больно, когда я ударяю головой о стену!" "Тогда не делай этого!" )...

(p.s. Я просто поднимаю вопрос - если вы чувствуете, что этот пост мутит воды, комментируйте соответствующим образом, и я удалю его)