2015-06-09 2 views
3

Являются ли функции stricmp() и strnicmp() удаленными в C99? Я всегда получаю предупреждение неявное объявление funtion stricmp() (а также strnicmp()), когда я пытаюсь скомпилировать его с C99. Например, простой код ниже дает мне это предупреждение.C99 удалить stricmp() и strnicmp()?

#include<string.h> 
#include<stdio.h> 

char arr[100]="hello"; 
char arr2[100]="hEllo"; 

int main() 
{ 
    int n=-1; 
    printf("%d\n",n); 
    n=strnicmp(arr,arr2,3); // the same when use the function stricmp(); 
    printf("%d\n",n); 

    getchar(); 
    return 0; 
} 

Когда я пытаюсь скомпилировать этот кусок кода против C99 (gcc -Wall -std=c99 main.c -o main), я понимаю, что предупреждение. Но когда я скомпилирую его без -std=c99, никаких предупреждений не будет. Однако, несмотря на то, что есть предупреждение о неявной декларации, мой код все еще работает правильно.

Почему? Это ошибка? Если не ошибка, то какова именно смена C99, которая делает это предупреждение?

+0

try '-std = gnu99' –

+4

Эти функции имеют * никогда не было в стандарте C, на самом деле в стандарте C нет функций сравнения строк без учета регистра. Функции 'stricmp',' strcasecmp' и т. Д. Являются всеми расширениями или определяются другими стандартами (POSIX, WIndows и т. Д.) –

+0

См. [G ++ error: «stricmp» не был объявлен в этой области (но ОК для «strcmp») ] (http://stackoverflow.com/q/1784767/1708801) –

ответ

6

Когда код компилируется с C99, он соответствует стандарту C99, который не имеет stricmp(). Когда код компилируется без коммутатора C99, он соответствует неизвестному стандарту, который реализует stricmp(). (С учетом gcc без -std=c99, скорее всего, компилирует к стандартному wihich C89/90 позволяет неявных декларации.)

В @Joachim Pileborg комментировал, нечувствителен сравнивает не являются частью стандарта C.

С неявными функциями C99 требуется диагностика (предупреждение в этом случае). Без C99 неявное использование функции не генерирует никаких предупреждений. Эти функции существуют в библиотеке компилятора . Речь идет только о функциях, объявленных перед использованием.

Легко достаточно, чтобы сделать свой собственный:

int wal_stricmp(const char *a, const char *b) { 
    int ca, cb; 
    do { 
    ca = (unsigned char) *a++; 
    cb = (unsigned char) *b++; 
    ca = tolower(toupper(ca)); 
    cb = tolower(toupper(cb)); 
    } while (ca == cb && ca != '\0'); 
    return ca - cb; 
} 

Примечание: При кодировании и пытается сделать A-Z матч a-z, строка нечувствительны сравнить процедуры, как правило, работают одинаково хорошо. Но, пытаясь до заказать струны, вещи быстро выходят из-под контроля. «abc» vs. «_bc» может появляться до или после другого в зависимости от того, было ли сострадание сделано как верхний или нижний регистр. '_', в ASCII, существует между буквами верхнего и нижнего регистра. В условиях интернационализации и локализации ситуация становится более сложной. В моем примере кода используется обратная конверсия, чтобы справиться с проблемами, когда число прописных букв char не имеет сопоставления 1 к 1 с строчными. IMO сложность сильных нечувствительных к регистру ошибок не требует использования кодировки UTF и определения ее случая.

+0

Для небольшого повышения производительности: 'ca = * a; A ++; if (islower (ca)) {ca = toupper (ca); } 'и т. д. Сохраняет некоторые дополнительные проверки. – Lundin

+0

Прошу прощения, я не могу точно понять, почему вы используете «toupper()» и «tolower()» в своей функции, хотя это работает довольно хорошо. – walkerlala

+0

@walkerlala 'toupper()' является стандартной функцией C, которая преобразует 'int' соответствует его эквиваленту в верхнем регистре. '' a'' -> '' A'', '' A'' -> '' A'', ''0'' ->' '0'' и т. д. Он хорошо определен для всех 'unsigned char' и' EOF'. В зависимости от _locale_ вы также можете получить '' ä'' -> '' Ä'' и т. Д. 'Tolower()' эквивалентно нижнему регистру. – chux

1

stricmp и strincmp являются нестандартными функциями. Они никогда не были частью стандарта C.

+0

Если это не часть стандарта c, то почему я получаю только предупреждение, а не ошибку? – walkerlala

+0

Я имею в виду, что предупреждение - это неявное объявление, а не ошибка, эта функция действительно объявлена ​​каким-то ненормальным способом, правильно? – walkerlala

+1

@walkerlala: поскольку люди GCC решили сделать (или оставить) неявное объявление функций предупреждением, а не ошибкой. Используйте '-pedantic-errors' или более конкретно' -Werror = implicit-function-declaration'. – cremno