2011-12-27 4 views
2

У меня есть функция для преобразования первых трех букв месяца в число (Jan = 1, Feb = 2 и т. Д.).Функция C не возвращает правильную вещь?

int convertDate(char date[3]) 
    { 
     printf("%s", date); 
     if(date == 'Ian') 
      return 1; 
     else 
     if(date == 'Feb') 
      return 2; 
     else 
     if(date == 'Mar') 
      return 3; 
     else 
     if(date == 'Apr') 
      return 4; 
     else 
     if(date == 'Mai') 
      return 5; 
     else 
     if(date == 'Iun') 
      return 6; 
     else 
     if(date == 'Iul') 
      return 7; 
     else 
     if(date == 'Aug') 
      return 8; 
     else 
     if(date == 'Sep') 
      return 9; 
     else 
     if(date == 'Oct') 
      return 10; 
     else 
     if(date == 'Noi') 
      return 11; 
     else 
     if(date == 'Dec') 
      return 12; 
     else return 0; 
    } 

Но, в основном(), когда я использую:

printf("%d", convertDate("Ian")); 

возвращает 0 вместо 1. То же самое для любого другого месяца. Любое предложение?

+0

'date [3]' слишком короткий для «Jan» или любой 3-буквенной строки. 'date [4]' или больше в порядке. – pmg

ответ

5

Использование strcmp() при сравнении char*.

if (date == "Sep") сравнивает базовый адрес char*.

+0

проклятый, глупый, спасибо! – FinalDestiny

2

Поскольку переменные строки C имеют тип char *, то сравнение строк, как и вы, фактически сравнивает указательные адреса. Используйте вместо этого strcmp().

Кроме того, вы можете использовать stricmp() для сравнения строк insenstive case. Обратите внимание, что вы могли бы реализовать функцию также с петлей, определяя все двенадцать фиксированных строк в массив (используя strncmp(), чтобы гарантировать, что мы на самом деле сравнивать только 3-х символов)

int convertDate(char date[3]) 
{ 
    const char date_names[12][4] = { 
     "Ian", "Feb", "Mar", /* etc. */ }; 
    int i; 

    for(i = 0; i < 12; ++i) 
    { 
     if (strncmp(date_names[i], date, 3) == 0) 
      return i+1; 
    } 

    return 0; 
} 
+0

проклятый, глупый я, спасибо! – FinalDestiny

+0

Нет, строки не имеют типа 'char *'. Значение 'char *' может быть * указателем * на строку. Сама строка представляет собой последовательность символов, заканчивающихся и включающих нулевой символ '' \ 0''. –

+0

Да, вы правы, но я не сказал, что строки имеют тип char *; Я сказал, что переменные, используемые для строк, имеют тип char *, поэтому действительно являются указателями на адрес, где хранится первый символ строки. – catchmeifyoutry

1

Вы не можете сравнить массив символов с использованием оператора. Посмотрите на функцию strcmp.

+0

проклятый, глупый, спасибо! – FinalDestiny

0

Вы выполняете сравнение указателей, а не сравнение строк. Используйте strcmp().

1

Вы не можете сравнивать такие строки, кроме как в особых обстоятельствах (не беспокойтесь об этом).

Вы должны использовать strncmp, «сравнение строк». Например .:

#include <string.h> 

затем

if(strncmp(date, "Ian", 3) == 0) 
      return 1; 

Примечание использованием " вместо '. Использование ' полностью отличается и может создавать многобайтовое значение int в стеке, которое вам не нужно.

+0

'import' должен быть' # include'. Нет смысла использовать 'strncmp', а не' strcmp'. –

+0

Угадайте, кто писал слишком много Python ... Использовал только strncmp, потому что OP знал, что это 3 символа. – Joe

+0

По-прежнему нет никакой пользы в использовании 'strncmp', а не' strcmp'. И это меняет смысл кода; рассмотрим 'convertDate (« Ianxyz »)'. (Параметр 'date' на самом деле является' char * ',' 3' игнорируется.) –

1

Это не должно даже компилироваться. Вы сравниваете значение char* (date) с величиной int ('Ian').

Это:

'Ian' 

не строковым. Это многосимвольная символьная константа, и ее значение определяется реализацией. Едва ли имеет смысл использовать его.

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

Как уже говорилось, при сравнении строк вам необходимо использовать strcmp(), а не == - это означает, что вы не можете использовать оператор switch.

Вы также должны знать, что объявление параметра

char date[3] 

в точности эквивалентно

char *date 

The 3 спокойно игнорировать, и, если вы звоните dateCompare("Ianxyzfoobar"), date будет указывать на строку с длина 12.

+0

'date' является указателем, сравнение указателей с целыми числами не является ошибкой. Однако нужно получить большое толстое предупреждение. –

+0

@ DanielFischer: Да, это ошибка. За исключением специального случая константы нулевого указателя, применение оператора '==' к значению указателя и целочисленному значению является нарушением ограничения. (Как и любая такая ошибка, стандарту требуется только диагностика, которая может быть предупреждением, не несущественным). См. [Стандарт C99] (http://www.open-std.org/jtc1/sc22/wg14/www/ docs/n1256.pdf), раздел 6.5.9, пункт 2. У старого стандарта C90 было то же правило. –

+0

Ах, да, спасибо. Нужно, чтобы бросок был законным. –

Смежные вопросы