J'ai défini une fonction appelée checkrow, qui lit un élément donné d'un tableau char (alimenté par un pointeur vers char) et détermine s'il est égal à certains caractères. Lorsque je compile mon programme global, le compilateur me dit que la ligne 67, qui est (if (* pInput == ('' || '\ t' || '\ n'))) sera ne jamais exécuter. Pourquoi? La logique me semble logique. Ci-dessous le code.
#include <stdio.h>
#include <stdlib.h>
int checkRow(char *pArray);
int main (void){
char c = 0;
int high = 0;
int low = 9;
int checksum = 0;
char input[3000];
char *pInput = input;
FILE *pFile = NULL;
pFile = fopen("foo.txt", "r");
if (pFile == NULL){
printf("failed to open file\n");
return (-1);
}
while((c = fgetc(pFile)) != EOF){
*pInput = c;
++pInput;
}
fclose(pFile);
pFile = NULL;
pInput = input; //point pInput back to the address of the first element of input
//printf("the checksum is %d\n", checksum(pInput));
while(*pInput){
if(checkRow(pInput) == 0){
checksum += (high - low);
++pInput;
continue;
}
else{
if((*pInput - '0') > high && (*pInput - '0') < low){
high = *pInput - '0';
low = *pInput - '0';
++pInput;
continue;
}
else if (*pInput - '0' > high){
high = *pInput - '0';
++pInput;
continue;
}
else if(*pInput - '0' < low){
low = *pInput - '0';
++pInput;
}
}
}
printf("this is the checksum %d\n", checksum);
getchar();
return 0;
}
int checkRow(char *pInput){
int in = 0;
if(*pInput == (' ' || '\t' || '\n'))
in = 0;
else
in = 1;
return in;
}
3 Réponses :
Cela ne veut pas dire que l'instruction ne sera pas exécutée, juste des expressions spécifiques qu'elle contient. Le message d'avertissement ressemble à ceci:
testcompare.c:67:35: warning: code will never be executed [-Wunreachable-code]
if(*pInput == (' ' || '\t' || '\n'))
^~~~
testcompare.c:67:27: warning: code will never be executed [-Wunreachable-code]
if(*pInput == (' ' || '\t' || '\n'))
^~~~
Remarquez les flèches pointant vers '\ n' et '\ t' , voilà ce que il dit ne sera jamais exécuté.
L'opérateur || est un opérateur de court-circuit, il n'exécute l'opérande droit que si l'opérande gauche est faux.
Dans ce cas, puisque le '' est une constante, et il est connu pour être véridique (tout char autre que '\ 0' est la vérité), les deux autres opérandes n'ont pas besoin d'être exécutés pour déterminer le résultat.
Vous devrez réécrire l'expression:
if ( strchr(" \t\n" , *pInput) != NULL)
comme
if(*pInput ==' ' || *pInput =='\t' || *pInput =='\n'))
ou
if(*pInput == (' ' || '\t' || '\n'))
L'opérateur || évalue son deuxième opérande uniquement si le premier opérande vaut 0.
Donc dans '' || '\ t' || '\ n' le dernier opérande n'est jamais évalué car '' || '\ t' est différent de zéro.
D'un autre côté, vous voulez écrire quelque chose comme
while((c = fgetc(pFile)) != EOF){
*pInput = c;
++pInput;
}
fclose(pFile);
pFile = NULL;
*pInput = 0; /* THIS IS IMPORTANT */
pInput = input;
while(*pInput)
Autre erreur que vous avez faite , vous avez oublié d'insérer le 0 final dans la chaîne input
(*pInput == ' ') || (*pInput == '\t') || (*pInput == '\n')
* pInput == ('' || '\ t' || '\ n')ne fait pas du tout ce que vous pensez. Vous devriez rechercher ce que font ces opérateurs.||passe entre des expressions logiques, pas entre des constantes auxquelles vous voulez comparer.@EugeneSh C'est vrai, mais comment se fait-il que la ligne ne soit jamais exécutée? Le compilateur sait que le pointeur ne peut jamais être (probablement) 1? Cela empêcherait l'exécution de la ligne next ...
La bonne façon de faire est de
if ((* pInput == '') || (* Input == '\ t') || (* Input == '\')) {..}@Yunnosch Je pense que l'OP a en quelque sorte déformé l'avertissement d'origine.
@EugeneSh. Possible.
Quel compilateur utilisez-vous et comment compilez-vous? Je ne reçois pas d'avertissement tel qu'il est écrit. (Bien que d'autres aient raison concernant l ' intention de la déclaration est écrite de manière incorrecte).
On dirait que la fonction
isspace ()dans vous serait utileOT: pour faciliter la lisibilité et la compréhension: 1) veuillez indenter systématiquement le code. Retrait après chaque accolade ouvrante '{'. Annuler l'indentation avant chaque accolade fermante '}'. Suggérer que chaque niveau de retrait comporte 4 espaces. 2) blocs de code séparés:
poursielsetandis quefaire ... pendantswitchcasedefaultvia une seule ligne vierge. 3) séparer les fonctions par 2 ou 3 lignes vides (être cohérent)concernant:
while ((c = fgetc (pFile))! = EOF) {la fonction:fgetc ()renvoie unintetEOFest unint. donc la variablecdoit être déclarée comme unint, pas comme unchar. Lors de la compilation, activez toujours les avertissements, puis corrigez ces avertissements. (pourgcc, utilisez au minimum:-Wall -Wextra -Wconversion -pedantic -std = gnu11) Remarque: d'autres compilateurs utilisent des options différentes pour produire la même choseOT: concernant:
printf ("failed to open file \ n");les messages d'erreur doivent être envoyés àstderr, pas àstdoutet lorsque le L'erreur provient d'une fonction de bibliothèque C, alors doit également afficher (dansstderr) le texte de la raison pour laquelle le système pense que l'erreur s'est produite. La fonction:perror ()gère correctement les deux opérations ci-dessus