Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Mise à jour de la FAQ C :
Avec désormais 181 réponses à vos questions, pour mieux apprendre le langage C

Le , par Malick

20PARTAGES

9  0 
Chers membres du club,

j'ai l'immense plaisir de vous annoncer la mise à jour de la FAQ C avec une sélection des cent quatre-vingt-une meilleures réponses à vos questions pour apprendre la programmation avec ce langage.

Les nouveaux Q/R portent essentiellement sur les nouveautés de C11 par rapport à C99.



Le chargement des données d'un fichier texte dans une structure



Ce nombre est appelé à évoluer avec vos différentes contributions.

Nous remercions LittleWhite, Matt_Houston et Winjerome pour leur engagement dans la rédaction et la relecture technique. Nos reconnaissances également à Claude LELOUP pour les corrections orthographiques.

Vous pouvez aussi contacter l'équipe de rédaction
.

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de sambia39
Membre chevronné https://www.developpez.com
Le 20/02/2017 à 19:02
Bonsoir
Dans la section FAQ C Comment charger les données d'un fichier texte dans une structure ? pourquoi utiliser un assert ?
Enfin (rien ne vous oblige), mais personnellement, je trouve qu’il n’est pas correct d’utiliser assert dans le cas présent surtout si l’objectif du FAQ est de fournir une réponse correspondant la questions récurrentes posées.

Je suis d’avis à connaître la raison d’un échec d’appel d’une fonction, mais de là a utilisé une fonction qui a pour rôle ou un des rôles la détection d’erreur de programmation lors de débogage et interrompre le programme en renvoyant une terminaison anormale du programme en question; est excessive.

Je pense qu’il est préférable d’utiliser un retour d’erreur que assert. Je m’explique : le retour d’erreur met en évidence une mauvaise utilisation de la fonction à cause d’un paramètre erroné (Exemple à cause d’une ouverture de fichier qui a échoué, ou autres, etc..), ce qui permet alors de prendre les mesures nécessaires pour traiter l’erreur et terminer le programme proprement.
"assert" est utilisé (dans mon cas) quand on se rend compte de l’instabilité du programme ou lorsque l’on fait du débogage en clair "assert" doit être utilisé que pour des circonstances ne devant jamais ce produire durant l’exécution normale d’un programme c’est un outil de débogage et non une méthode, routine ou fonction de sortie d’erreur de plus la gestion d’erreur doivent impérativement être faites uniquement par le programme Dans l’exemple fournir il ne s’agit strictement pas d’un bogue..
Admettant que l’on compile avec -DNDEBUG pensez-vous que le programme final soit correct (et portable) ?.

Ceci dit la mise à jour de la FAQ était essentielle
à bientôt
4  0 
Avatar de picodev
Membre émérite https://www.developpez.com
Le 19/02/2017 à 18:27
Bonjour,
concernant les «implémentations» complètes de C11 il faut citer les couples compilateurs/bibliothèque standard.
Le couple gcc/musl est une implémentation de C11, au même titre que gcc/glibc (aux threads près si je ne me trompe pas).

En tout cas bravo pour la mise à jour qui était nécessaire
2  0 
Avatar de Matt_Houston
Expert confirmé https://www.developpez.com
Le 20/02/2017 à 20:06
Effectivement l'assert ne devrait pas être utilisé pour traiter un échec de fopen, bien vu sambia.

Je ne suis pas totalement d'accord - c'est mineur, mais la FAQ C est précisément l'endroit pour chipoter ! - avec la solution de remplacement proposée par picodev :

Citation Envoyé par picodev Voir le message
Code : Sélectionner tout
1
2
3
4
if (f==NULL) {
  perror("fopen");
  exit(EXIT_FAILURE);
}
Ce qui me chiffonne c'est l'usage d'exit : il n'y a pas de raison de « paniquer » ici, de plus nous sommes dans main où l'on peut lui préférer un simple et élégant return. On voit déjà cet appel utilisé à tort et à travers dans les programmes de débutants, autant ne pas encourager cette pratique.

Citation Envoyé par picodev Voir le message
Comme on est en C11 on peut aussi utiliser les designated init :

au lieu de :
Code : Sélectionner tout
t_capteur c = { 0, "", 0.0f };
on pourra préférer
Code : Sélectionner tout
t_capteur c = { .id=0, .nom="", .valeur=0.0f };
Ça c'est plus une préférence personnelle mais je ne suis pas non plus d'avis d'user et abuser de cette syntaxe, certes souvent pratique mais inutilement grevante lorsqu'il n'y a pas d'ambiguïté comme ici.
2  0 
Avatar de picodev
Membre émérite https://www.developpez.com
Le 25/02/2017 à 16:49
Citation Envoyé par Bktero Voir le message
L'objectif de cette entrée n'est pas d'expliquer comment bien ouvrir un fichier mais de comment charger des données. Une assertion correspond bien à ce que ce bout de code : il doit s'assurer que le descripteur est valide. J'aurais pu mettre le reste du code d'un if(!NULL). Il n'y a pas de contexte au chargement des données, c'est vraiment un snippet à adapter, gestion d'erreur y compris.
Utiliser assert pour vérifier une erreur runtime est une mauvaise pratique, elle est même fautive car si la macro NDEBUG est définie alors assert ne fait rien.
Une assertion ne doit servir que lors du développement pour s'assurer qu'on utilise une API correctement par exemple, jamais pour s'assurer une allocation de ressources.
J'imagine que l'objectif est aussi de ne pas donner de mauvaises habitudes.
Citation Envoyé par Bktero Voir le message
Il n'est pas précisé qu'on est en C11 dans cette entrée donc pas de designated initializers.
Et du coup on passera en C99 quand la norme C2x sortira ?
2  0 
Avatar de picodev
Membre émérite https://www.developpez.com
Le 20/02/2017 à 19:16
@sambia39: tout à fait. assert = à utiliser uniquement lors du développement pour traquer les erreurs d'utilisations de l'API par exemple, à ne jamais utiliser en version release pour traquer les erreurs runtime.
Un exemple plus correct remplacera l'assertion
Code : Sélectionner tout
assert(f != NULL);
par un
Code : Sélectionner tout
1
2
3
4
if (f==NULL) {
  perror("fopen");
  exit(EXIT_FAILURE);
}

Comme on est en C11 on peut aussi utiliser les designated init :

au lieu de :
Code : Sélectionner tout
t_capteur c = { 0, "", 0.0f };
on pourra préférer
Code : Sélectionner tout
t_capteur c = { .id=0, .nom="", .valeur=0.0f };
Dans compte = fscanf(f, "%d-%[^:s]:%f\n", &(c.id), c.nom, &(c.valeur)); le parenthésage n'est pas nécessaire la priorité de l'opérateur . étant supérieure à celle de l'opérateur & unaire. Mais bon ce n'est qu'un détail.
1  0 
Avatar de picodev
Membre émérite https://www.developpez.com
Le 20/02/2017 à 20:22
Citation Envoyé par Matt_Houston Voir le message
Ce qui me chiffonne c'est l'usage d'exit : il n'y a pas de raison de « paniquer » ici, de plus nous sommes dans main où l'on peut lui préférer un simple et élégant return. On voit déjà cet appel utilisé à tort et à travers dans les programmes de débutants, autant ne pas encourager cette pratique.
...
Oui c'est vrai ... un if else c'est mieux. L'important étant sans doute l'utilisation de perror.


Ça c'est plus une préférence personnelle mais je ne suis pas non plus d'avis d'user et abuser de cette syntaxe, certes souvent pratique mais inutilement grevante lorsqu'il n'y a pas d'ambiguïté comme ici.
C'est effectivement surtout utile dans la phase de développement où la composition de structures peut être modifiée, cela permet entre autre d'avoir des warnings pour des structures non complètement initialisée, et d'être certain que «la bonne partie» sera initialisée. Cela permet d'augmenter la lisibilité aussi dans certains cas : un truc = {20,1000,0}; est moins clair qu'un truc = { .temperature=20, .pression=1000, .echantillon=0}; ; pas la peine de retourner voir la définition pour savoir quoi correspond à quoi.
C'est vrai que c'est verbeux pour un programme de 15 lignes, mais dès qu'on doit chercher loin pour avoir la définition c'est mieux.
1  0 
Avatar de sambia39
Membre chevronné https://www.developpez.com
Le 20/02/2017 à 21:55
Citation Envoyé par Matt_Houston Voir le message

Ce qui me chiffonne c'est l'usage d'exit : il n'y a pas de raison de « paniquer » ici, de plus nous sommes dans main où l'on peut lui préférer un simple et élégant return. On voit déjà cet appel utilisé à tort et à travers dans les programmes de débutants, autant ne pas encourager cette pratique.
Disant que le choix entre return et exit est plutôt d’ordre préférentiel, mais je l’admets tout de même qu’on l’utilise à tort. Personnellement, j’utilise la fonction exit uniquement dans le cas où j’ai une erreur irrécupérable qui s’est produite où quand un return de l’information de cette erreur excède plus de 3 niveaux de profondeur de fonction.

à bientôt
1  0 
Avatar de Winjerome
Modérateur https://www.developpez.com
Le 26/02/2017 à 7:58
Bonjour,

Je partage l'avis de picodev sur l'utilisation d'assert.
Je constate en même temps un « s » en trop dans le format de fscanf :
Code : Sélectionner tout
compte = fscanf(f, "%d-%[^:s]:%f\n", &(c.id), c.nom, &(c.valeur));
qui n'a rien à voir avec le format de chaîne %s, mais qui comme les deux points, s'arrête au premier « s » rencontré. Et je rajouterais volontiers la taille afin de se protéger contre les éventuelles chaînes trop longues occasionnant des dépassements.
1  0 
Avatar de Bktero
Modérateur https://www.developpez.com
Le 26/02/2017 à 11:36
Je crois que j'ai la flemme de développer une réponse quant a l'assertion et encore plus sur le C2x.

Effectivement pour le s, c'est une erreur !
1  0 
Avatar de picodev
Membre émérite https://www.developpez.com
Le 26/02/2017 à 12:02
Citation Envoyé par Bktero Voir le message
L'objectif de cette entrée n'est pas d'expliquer comment bien ouvrir un fichier mais de comment charger des données.
Citation Envoyé par Bktero Voir le message
Je crois que j'ai la flemme de développer une réponse quant a l'assertion et encore plus sur le C2x.

Effectivement pour le s, c'est une erreur !
Dans ce cas, autant faire comme en amour : vieux vaut ne rien faire que de ne le faire qu'à moitié.
Je propose simplement la suppression de l'assertion.
1  0