Langage C

Discutez d'informatique ici !
joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 25 Nov 2013, 20:33

Dlzlogic a écrit:Concernant le fgets, je crois que je n'ai jamais fait de saisie avec stdin, j'ai toujours travaillé avec des fichiers, donc, je vois pas trop d'où peut venir ce point d'interrogation.
Concernant la chaine lue, elle doit aller dans un buffer. Celui-ci doit exister avec une longueur suffisante. Sinon, on ne sait pas du tout ce qui se passe.
Il y a un point à signaler qui me parait important : sous Unix et linux, le caractère fin de ligne est le caractère '0x0D', alors que sous Windows, c'est '0x0D'+'0x0A'.
Cela fait que si on affiche un texte provenant de Linux avec Windows, il n'y a pas de CRFL détecté et toutes les lignes sont accolées, sur une seule ligne.
Ce genre de détail fait partie des joies de l'informatique.
Si je ne me trompe pas, le problème est transparent pour le C, lorsqu'on ouvre le fichier texte (et non pas un fichier binaire). En texte on traite le '\n' qu'il soit physiquement un CR ou un CR,LF.



Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 12:39

par Dlzlogic » 25 Nov 2013, 21:10

Je ne serais pas affirmatif sur tous les points.
Le C est un langage qui compile et lie un projet.
Si on crée un fichier exe sous Windows, ce sera un binaire exécutable sous Windows. Si ce binaire est un éditeur de texte, à moins d'avoir pris la précaution de tester CR différemment de CRLF et d'en tirer les conséquences, il listera le fichier comme il est écrit c'est à dire avec retour à la ligne ou pas.
J'ai fait un petit utilitaire qui me permettait justement d'éviter ce problème lorsque je lis un fichier en provenance d'Unix ou de Linux.
Je peux t'assurer qu'il s'agit d'un problème réel, mais je ne voudrais pas m'aventurer sur des détails que je n'ai pas vérifié.
Ceci peut d'ailleurs faire l'objet d'un sujet intéressant, comment les développeurs et utilisateurs ont traité le problème.
Pour être franc, le sujet est clair dans sa généralité, par contre pour les détails, il faudrait que je me rafraichisse la mémoire.
Bonne soirée.

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 25 Nov 2013, 23:17

Dlzlogic a écrit:Je ne serais pas affirmatif sur tous les points.
Le C est un langage qui compile et lie un projet.
Si on crée un fichier exe sous Windows, ce sera un binaire exécutable sous Windows. Si ce binaire est un éditeur de texte, à moins d'avoir pris la précaution de tester CR différemment de CRLF et d'en tirer les conséquences, il listera le fichier comme il est écrit c'est à dire avec retour à la ligne ou pas.
J'ai fait un petit utilitaire qui me permettait justement d'éviter ce problème lorsque je lis un fichier en provenance d'Unix ou de Linux.
Je peux t'assurer qu'il s'agit d'un problème réel, mais je ne voudrais pas m'aventurer sur des détails que je n'ai pas vérifié.
Ceci peut d'ailleurs faire l'objet d'un sujet intéressant, comment les développeurs et utilisateurs ont traité le problème.
Pour être franc, le sujet est clair dans sa généralité, par contre pour les détails, il faudrait que je me rafraichisse la mémoire.
Bonne soirée.
Je disais juste qu'en C, le problème de fin de ligne entre Linux et Windows n'existe pas tant qu'on ouvrait un fichier en mode texte. Je suppose qu'un éditeur de texte "bien fait" en C, livre des lignes de texte au système complétées par des \n qui sont interprétés par ce système en CR ou CRLF.
Je pense, mais je n'en suis pas très sur dans les faits, qu'un éditeur qui fait apparaître les CR ou les CRLF dans le texte doit dater de Mathusalem. Qu'est-ce que ça doit donner avec Unicode.

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 12:39

par Dlzlogic » 26 Nov 2013, 00:20

Bonsoir,
Effectivement la question mérite qu'on la résolve.
Je pense que le fait que le langage servant à créer l'exe n'a rien à voir. Si on l'a prévu, ça marche, sinon, ça marche pas.
Ca vaut le coup de créer un nouveau sujet, ce soir il est trop tard. Tu l'ouvres le premier, ou moi, mais dans tous les cas il faudra poser le problème de façon précise dès le départ.
Question idiote, je suppose que que tu travailles sous linux, sinon, des fichiers linux il faudra en cherger, mais ce sera pas un problème.
A demain ... non, on est déjà aujourd'hui !!!

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 26 Nov 2013, 14:22

Je devrais pouvoir récupérer le code à partir de demain soir et ainsi pouvoir vous le montrer.


Autre question sans réel rapport avec le langage du moins je ne pense pas.

J'ai un type structuré T_etu contenant 4 champs
Code: Tout sélectionner
char nom[19]
char prenom[19]
char adresse[39]
int notes[5]


L'on me demande quelle est "la taille" d'une variable de ce type; je ne comprends pas vraiment ce qui est demandé par là. Le nombre d'octet alloué pour chacune des variables ? Si oui comment peut on le connaître ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 26 Nov 2013, 14:37

Rockleader a écrit:J
J'ai un type structuré T_etu contenant 4 champs
Code: Tout sélectionner
char nom[19]
char prenom[19]
char adresse[39]
int notes[5]


L'on me demande quelle est "la taille" d'une variable de ce type; je ne comprends pas vraiment ce qui est demandé par là. Le nombre d'octet alloué pour chacune des variables ? Si oui comment peut on le connaître ?

Avec sizeof de la variable. La taille de la structure ne sera sans doute pas la somme des tailles de chaque chanp de cette sructure à cause des alignements des champs.

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 26 Nov 2013, 15:27

à cause des alignements des champs.

+1 octet de base parce que c est une structure
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 26 Nov 2013, 15:33

Donc si j'ai bien compris la question; les tableaux notes et chaines de caractères nom;prénom;adresse étant des pointeur; il compte chacun pour une seule variable.

Donc la réponse à la question serait sizeof(T_etu.nom[0]) + ... pour tous les champs de la structure (+ 1 pour la structure elle même). ?


EDIT:

Par ailleurs; je commence à regarder du coté des fichiers et par conséquent les fonctions fprintf et fscanf.

Dans mon début d'explication de TP; l'on me donne cette structure là.

1.2 Lecture dans le fichier
La fonction fscanf, analogue `a scanf, permet de lire des donn´ees dans un fichier. Sa syntaxe
est semblable `a celle de scanf :
fscanf(nom interne,”chaˆ;)ne de contrˆole”,argument-1,...,argument-n)
Les sp´ecifications de format sont ici les mˆemes que celles de la fonction scanf.

1.3 Ecriture dans le fichier
La fonction fprintf, analogue `a printf, permet d’´ecrire des donn´ees dans un fichier. Sa syntaxe
est :
fprintf(nom interne,”chaˆ;)ne de contrˆole”,expression-1, ..., expression-n)
· Les sp´ecifications de format utilis´ees pour la fonction fprintf sont les mˆemes que pour printf.
· rend le nb d’octets ´ecrits, ou EOF si erreur.
· Les \n sont transform´es en CR/LF.


Je voulais savoir ce que l'on entend par nom interne. Pour le reste je suppose que chaine de contrle représente les %d %c etc etc et l'expression le nom de la variable.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 26 Nov 2013, 20:02

Rockleader a écrit:Donc si j'ai bien compris la question; les tableaux notes et chaines de caractères nom;prénom;adresse étant des pointeur; il compte chacun pour une seule variable.
Non, ce sont des tableaux donc
nom[19] => 19 octets
prenom[19] 19 octets ...

Je voulais savoir ce que l'on entend par nom interne. Pour le reste je suppose que chaine de contrle représente les %d %c etc etc et l'expression le nom de la variable.
c'est le nom la variable FILE *
Code: Tout sélectionner
FILE* f = fopen("toto.txt", "rt");
f est le nom interne.

Attention à l'utilisation de fscanf (tout comme d'ailleurs scanf) ce sont des fonctions TREEEEESSSSSS difficiles à utiliser (bien tester le retour de fscanf et scanf). Garde à l'esprit qu'on peut lire aisement un fichier àvec fscanf si on l'a d'abord écrit avec fprintf, sinon on galère, il faut bien connaitre son contenu.

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 12:39

par Dlzlogic » 26 Nov 2013, 20:23

Attention à l'utilisation de fscanf (tout comme d'ailleurs scanf) ce sont des fonctions TREEEEESSSSSS difficiles à utiliser (bien tester le retour de fscanf et scanf). Garde à l'esprit qu'on peut lire aisement un fichier àvec fscanf si on l'a d'abord écrit avec fprintf, sinon on galère, il faut bien connaitre son contenu.
Tout à fait d'accord. Moi j'utilise toujours fget et Cie et sscanf. C'est à dire, je lis une chaine et je la décode ensuite.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 26 Nov 2013, 21:03

Merci pour vos conseils; mais dans le cadre de ce tp; le fichier en question sera créer et donc on va l'écrire avec fprintf; donc à priori il ne devrait pas y avoir de soucis.

Mais j'ai bien pris note de ce que vous avez dit. Je suppose que au fil des travaux que l'on aura à faire l'on nous montrera les défauts de ces fonctions mais pour le moment ce sont les seules que l'on nous as montré.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 12:39

par Dlzlogic » 26 Nov 2013, 21:13

Ce n'est pas que la fonction fscanf ait des défauts, c'est la même que scanf, c'est juste le programmeur qui n'est pas parfait, et les fichiers non plus d'ailleurs.
sscanf, c'est la même chose, sauf que si on est consciencieux, on ne risque plus rien.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Déc 2013, 15:52

Bonjour; je "teste" la partie modulaire; et j'ai donc voulu séparer mon fichier avec des headers comme nous l'avions évoqué plus haut.

J'ai tout d'abord vérifié en mettant tout dans mon main que le programme fonctionne; puis j'ai découpé dans les différentes parties.

Au final; voici ce que j'ai:

Il s'agit donc du main annuaire.c

Code: Tout sélectionner
# include
# include
# include
# define LISTE "/home/christo/Bureau/C-C++/tp8/liste.txt"
# include "proto.h"


int main()
{
   execution();
   return 0;
}



le header proto.h
Code: Tout sélectionner
#ifndef PROTO_H
#define PROTO_H

typedef struct /*cette structure ne sert pas pour le moment*/
{
char nom[21] ;
char capitale[21] ;
int indicatif ;
} T_pays ;

int choixMenu(void);
void execution(void);

#endif


Le fichier source des fonctions proto.c

Code: Tout sélectionner
#include "proto.h"

int choixMenu(void)
{
   int choix;
   printf("1. Verifier si un pays est dans la base\n");
   printf("2. Ajouter un pays à la base\n");
   printf("3. Trouver l’indicatif d’un pays\n");
   printf("4. Quitter le programme\n");
   printf("Votre choix:");scanf("%d",&choix);
   return choix;
}

void execution(void)
{
   switch(choixMenu())
   {
      case 1:
         printf("Vérification du pays dans la base\n");
      break;
      case 2:
         printf("Ajout d'un pays dans la base\n");
      break;
      case 3:
         printf("Recherche de l'inficatif dans la base\n");
      break;
      case 4:
         printf("Fin du programme\n");
      break;
      default:
         printf("Choix invalide !!!\n");
         execution();
      break;
   }
}



Lorsque je compile dans ma console j'obtiens le message d'erreur suivant:

Code: Tout sélectionner
/tmp/cczfZYWb.o: dans la fonction « main »:
annuaire.c:(.text+0x5): référence indéfinie vers « execution »
collect2: error: ld returned 1 exit status



Aurais je mal construis l'arborescence ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 07 Déc 2013, 16:37

Code: Tout sélectionner
a.c:
#include "a.h"
int val(){
 return 1;
}
a.h:
#ifndef a_h_
#define a_h_
int val();
#endif
main.c:
#include "a.h"
int main(){
  return val();
}

Code: Tout sélectionner
gcc main.c a.c && ./a.out ; echo $?
//affiche 1
la vie est une fête :)

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 07 Déc 2013, 16:52

Bonjour,

Comment as-tu compilé ton projet ?

Comme fatal-error a pu te le dire, tu as besoin de rajouter dans tous les fichiers .c dans ta compilation.

Code: Tout sélectionner
gcc -c main.c proto.c -o test -W -Wall -pedantic

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Déc 2013, 16:55

J'ai utilisé l'instruction suivante

Code: Tout sélectionner
gcc - Wall annuaire.c -o annuaire


je me doute que ce n'est pas la bonne méthode; mais s'il faut rajouter tous les fichier, sur de gros projets ça doit vite devenir "chiant".

J'ai également entendu parler vaguement d'un "makefile" qui permettrait de tout compiler ?

EDIT

En fait; je me demandais simplement comment faire ce type de makefile pour tout compiler; mais au final c'est tout bête ça reviendrais à écrire un script ou on écrirait les commandes pour compiler non ? Ce qui éviterait de retaper une liste de fichier énorme à chaque fois.


Donc pour linux ça marcherait ainsi; mais si je codais sous windows, il aurait fallu que je fasse un script sous windows pour compiler l'ensemble des fichiers ? x) vive le bordel ^^ finalement c'est pas plus mal que je sois définitivement passé à Linux :zen:


J'ai donc pu compiler en faisant mon

gcc - Wall liste_fichier.c -o nom_exe


(Au passage j'en profite pour poser une question anodine; sous linux on ne peut pas générer de fichier éxécutable j'entend par là avec l'extension exe; donc comment s’appelle les fichiers de types applications au niveau de l'extension ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 07 Déc 2013, 17:54

il n'y a pas de d'extension ni de noms spécifiques pour les fichiers de type application.
Si tu veux les nommer .exe c'est ton choix.

Généralement les fichiers de type application sont rendus executables par leur execution flag (quand tu fais chmod +x..genre le troisieme bit).

Pour savoir de quel type est un fichier, tu utilises le mime type.
De mémoire fileinfo ou file --mime-type tonfichier

ps: windows c'est quand même bien pour les jeux, les drivers (et encore), dotnet et les virus.
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Déc 2013, 18:03

fatal_error a écrit:
ps: windows c'est quand même bien pour les jeux, les drivers (et encore), dotnet et les virus.



C'est sur qu'il faut pas espérer jouer à un mmorpg sur du linux :ptdr:

Pour les virus avec windows; je sais pas si c'est moi ou pas mais j'avais l'impression que les antivirus les attiraient tous; du coup je les avais tous supprimé de mon pc et depuis je n'avais eu aucun soucis...du moment que l'on fouille pas de site dangereux je vois pas comment choper un virus...bref on s'écarte là ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 15:31

par joel76 » 07 Déc 2013, 18:58

fatal_error a écrit: ps: windows c'est quand même bien pour les jeux, les drivers (et encore), dotnet et les virus.
Vaux mieux lire ça que d'être aveugle :stupid:

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 07 Déc 2013, 21:40

Rebonsoir ;)

Je pense être arrivé à manipuler mes fichiers comme il faut désormais, cela dit; je ne peux toujours pas exécuter mon code --:)

Il compile sans erreur.

Mais à l'exécution j'ai une erreur de segmentation. (core dumped ? si j'ai pas mal traduit)


Il s'agirait donc d'une erreur de ma part lorsque je fais mes affectations de .nom et .capitale; mais je ne vois pas du tout quoi changer.

Pouvez vous m'expliquer d'où vient le problème :lol3:


Code: Tout sélectionner
typedef struct
{
char* nom[21] ;
char* capitale[21] ;
int indicatif ;
} T_pays ;



void initRep(void)
{
   T_pays *france = NULL,*italie = NULL,*espagne = NULL; /*seuls ces 3 pays figureront dans l'archive de départ*/
   FILE *registre;
   registre=fopen(LISTE,"w"); /* "w" on crée ou efface le fichier puis on le remplit*/
   printf("test1\n"); /*ce test s'affiche on ouvre donc bien le fichier ?*/
      (*italie).nom[21]="ITALIE"; printf("test1\n"); /*ne s'affiche pas*/   (*italie).capitale[21]="ROME";(*italie).indicatif=39;
      (*espagne).nom[21]="ESPAGNE";(*espagne).capitale[21]="MADRID";(*espagne).indicatif=34;
      (*france).nom[21]="FRANCE";(*france).capitale[21]="PARIS";(*france).indicatif=33;
      fprintf(registre,"%s    %s    %d",(*italie).nom[21],(*italie).capitale[21],(*italie).indicatif); /*pour seulement 3 pays on ne surcharge pas avec un tableau de structure*/
      fprintf(registre,"%s    %s    %d",(*espagne).nom[21],(*espagne).capitale[21],(*espagne).indicatif);
      fprintf(registre,"%s    %s    %d",(*france).nom[21],(*france).capitale[21],(*france).indicatif);
   fclose(registre);
}

Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 3 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite