2016-11-20 1 views
0

Ma mission est de créer un programme qui demande aux utilisateurs une date puis imprime si c'est valide ou non. Je suis seulement autorisé à utiliser des chaînes et pas int% d.Pourquoi est-ce que je continue d'obtenir des erreurs de compilation avec strtok en C?

Pourquoi mon programme obtient-il tant d'erreurs de compilateur concernant le strtok et appelant la fonction?

Severity Code Description Project File Line Suppression State 
Warning C4024 'getInput': different types for formal and actual parameter 1 dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 26 
Warning C4047 'function': 'char *' differs in levels of indirection from 'char' dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 26 
Warning C4024 'getInput': different types for formal and actual parameter 2 dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 26 
Warning C4024 'getInput': different types for formal and actual parameter 3 dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 26 
Warning C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 19 
Warning C4996 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 21 
Warning C4996 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 22 
Warning C4996 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 24 
Warning C4098 'getInput': 'void' function returning a value dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 90 
Warning C4477 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'int' dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 47 
Warning C4477 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 2 has type 'int' dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 47 
Warning C4477 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 3 has type 'int' dating c:\users\chris\documents\visual studio 2015\projects\dating\dating.c 47 
Error LNK2019 unresolved external symbol [email protected] referenced in function "int __cdecl invoke_main(void)" ([email protected]@YAHXZ) dating c:\Users\Chris\documents\visual studio 2015\Projects\dating\MSVCRTD.lib(exe_winmain.obj) 1 
Error LNK1120 1 unresolved externals dating c:\users\chris\documents\visual 

studio 2015\Projects\dating\Debug\dating.exe 1 

code:

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


//Declares function 
void getInput(char *userInput1, char *userInput2, char *userInput3); 
//Declares variables. 



int main(void) { 
    char userInput[100]; 
    printf("Enter a date in this format : MM/DD/YY:"); 
    //Captures users input 
    scanf("%s", &userInput); 
    //Divides the 3 dates entered into 3 variables. 
    char *userInput1 = strtok(userInput, "/"); 
    char *userInput2 = strtok(NULL, "/"); 
    //Used X to capture the last end of integers entered. 
    char *userInput3 = strtok(NULL, "X"); 
    //Called function. 
    getInput(*userInput1, *userInput2, *userInput3); 

    system("pause"); 
    return 0; 

} 

void getInput(char *userInput1, char *userInput2, char *userInput3) 
{ 
    // If user inputs a valid date this will run. 
    if (0 > *userInput1<12, 0>*userInput2<31, 0>*userInput3 < 99) { 
     // If user month input is this... 
     switch (*userInput1) { 

      //if User month input is 02 this will run 
     case 02: 

      //If user year is a leap year this will run 
      if (*userInput3 % 4 == 0) { 
       //If user day is inbetween 0-29 it will say the date is valid. 
       if (0 > *userInput2 > 29) { 
        printf("You entered a valid date, %s/%s/%s", *userInput1, *userInput2, *userInput3); 
       } 

       // If the day of the February isn't 0-29 it will print it is invalid. 
       else 
        printf("Invalid date."); 
      } 

     case 04: 
      //Their are only 30 days in April, if user Inputs 31 it is invalid. 
      if (*userInput2 == 31) { 
       printf("Invalid date."); 
      } 
      //Every other date should be valid because the main if else statement filters it all out. 
      else { 
       ("You entered a valid date, %s/%s/%s", *userInput1, *userInput2, *userInput3); 
      } 

     case 06: 
      if (*userInput2 == 31) { 
       printf("Invalid date."); 
      } 
      //Every other date should be valid because the main if else statement filters it all out. 
      else { 
       ("You entered a valid date, %s/%s/%s", *userInput1, *userInput2, *userInput3); 
      } 

     case 11: 
      if (*userInput2 == 31) { 
       printf("Invalid date."); 
      } 

      //Every other date should be valid because the main if else statement filters it all out. 
      else { 
       ("You entered a valid date, %s/%s/%s", *userInput1, *userInput2, *userInput3); 
      } 
      break; 
     } 
    } 
    //If the user enters a date that isn't valid , Invalid date prints. 
    else { 
     printf("Invalid date."); 
    } 
    return 0; 

} 
+0

Microsoft essaie juste d'imposer ses versions des fonctions standard. Vous pouvez les utiliser. Il suffit d'éteindre ces avertissements. Lire ici: http://stackoverflow.com/questions/30570382/is-strtok-safe-to-use/30570501#30570501 –

+0

Vous ne recevez pas d'erreurs de compilation pour 'strtok' et d'autres, vous obtenez des avertissements. MSVC a ses propres idées sur la façon dont vous devriez le faire, avec des fonctions non standard de Windows, dont certaines ne sont pas plus "sûres" que celles qu'elles veulent remplacer. –

+1

Dans MSVC si vous placez '#define _CRT_SECURE_NO_WARNINGS' * avant * les fichiers d'en-tête de la bibliothèque' #include <...> 'il supprimera ces avertissements. Ensuite, les avertissements les plus importants tels que votre utilisation du format 'print' avec'% s' auront encore besoin d'attention. –

Répondre

0

Vous passez des caractères au lieu de pointeurs vers getinput():

getInput(*userInput1, *userInput2, *userInput3); 

Essayez ceci:

getInput(userInput1, userInput2, userInput3); 

L'avertissement que vous obtenez du compilateur regar ding scanf() sont des indications de problèmes potentiels:

  • scanf est dangereux: en effet, vous ne limite pas le nombre de caractères pour stocker dans le tableau userInput, et vous ne devriez pas passer l'adresse du tableau, mais l'adresse sa première entrée, et vous devriez vérifier la valeur de retour:

    if (scanf("%99s", userInput) != 1) { 
        /* handle input failure */ 
    } 
    
  • strtok est dangereux d'utiliser dans des contextes imbriqués. Vous ne le faites pas dans le code ci-dessus, mais il est difficile pour le compilateur de vérifier et il serait plus sûr d'utiliser strtok_s ou strtok_r à la place.

Vous avez d'autres problèmes dans la fonction getInput():

  • Vous devriez vérifier si l'un des arguments sont NULL.

  • if (0 > *userInput1<12, 0>*userInput2<31, 0>*userInput3 < 99) { est une expression C valide, mais pas ce que vous avez l'intention de tester. Ecrivez à la place:

    if (*userInput1 > 0 && *userInput1 < 12 
    && *userInput2 > 0 && *userInput2 < 31 
    && *userInput3 > 0 && *userInput3 < 99) { 
        ... 
    } 
    

    Mais notez cependant que vous testez des caractères, pas la valeur décimale encodée dans ces caractères. Vous devez d'abord convertir ces chaînes en nombres avec atoi() ou strtol(), ou utiliser une conversion scanf() différente. Notez que les années bissextiles ne sont pas strictement des multiples de 4, vous devrez peut-être utiliser la règle grégorienne si vous souhaitez gérer des années en dehors de la plage 1901..2099. Je suppose que YY implique 20YY, mais ce serait incorrect si vous demandez des anniversaires.

  • Vous avez manqué que Septembre a aussi 30 jours.

Voici une version corrigée et simplifiée:

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

int check_date(int month, int day, int year); 

int main(void) { 
    char userInput[100]; 
    int day, month, year; 

    printf("Enter a date in this format : MM/DD/YY:"); 
    //Captures users input 
    if (scanf("%d/%d/%d", &month, &day, &year) == 3) { 
     check_date(day, month, year); 
    } else { 
     printf("incorrect input\n"); 
    } 
    system("pause"); 
    return 0; 

} 

int check_date(int month, int day, int year) { 
    int valid = 1; 
    // If user inputs a valid date this will run. 
    if (month <= 0 || month > 12 || day <= 0 || day > 31 || year < 0 || year > 99) { 
     valid = 0; 
    } else { 
     switch (month) { 
      //if User month input is 02 this will run 
      case 02: 
      //If user year is a leap year this will run 
      if (year % 4 == 0) { 
       if (day > 29) 
        valid = 0; 
      } else { 
       if (day <= 28) 
        valid = 0; 
      } 
      break; 
      case 4: 
      case 6: 
      case 9: 
      case 11: 
      if (month > 30) 
       valid = 0; 
      break; 
     } 
    } 
    if (valid) { 
     printf("You entered a valid date, %d/%d/%d\n", month, day, year); 
     return 1; 
    } else { 
     printf("Invalid date\n"); 
     return 0; 
    } 
}