Flux rss
Collection CommentÇaMarche.net
Rechercher : dans
Par :

[C] Maudites structures.....

kilian, le vendredi 10 juin 2005 à 19:32:20 
 Signaler ce message aux modérateurs

Bonjour,

J'ai un soucis depuis ce matin en utilisant les structures. J'ai tout le temps une erreur de syntaxe en affectant une valeur dans une variable structurée.

J'ai une structure définie comme ceci:

struct db_integers{  // Octets
	 
	 char *boolean;		       // 1 bit
	 char *octet;		          // 1
	 char *word;		         // 2
	 char *db_word;		     // 3
	 char *long_word;	   // 4
	 char *six_four_word;   // 8
	 
};

Puis un raccourcis pour la déclarer plus tard:
typedef struct db_integers integers;

Et enfin l'affectation d'une variable structurée:
integers mysql_integers;

mysql_integers->boolean="BOOL";
mysql_integers->octet="TINYINT";
mysql_integers->word="SMALLINT";
mysql_integers->db_word="MEDIUMINT";
mysql_integers->long_word="INT";
mysql_integers->six_four_word="BIGINT";


Et j'ai cette erreur lors de la compilation:
mysql_types.h:4: error: erreur de syntaxe before '->' token

Mais là je ne vois vraiment pas où est le problème, cette ligne concerne:
mysql_integers->boolean="BOOL";

Si je la supprime il me fera cette erreur pour les suivantes affectations aussi.
Idem lorsque je fais une affectation vers un champs d'une structure qui n'est pas un pointeur (c'est à dire avec un point au lieu d'une flêche)...

Si vous avez une idée là dessus, merci d'avance parce que là mes neuronnes debuggeuses n'ont plus d'imagination
Configuration: Gcc 3.3.5

1

lami20j, le vendredi 10 juin 2005 à 22:27:53

Salut,

J'ai simplifié un peut ton code (j'ai enlevé typedef)

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

main()
 {
  struct db_integers{  // Octets
    char *boolean;                // 1 bit
    char *octet;                     // 1
 };

 struct db_integers *mysql_integers;  // pointeur
 mysql_integers=malloc(sizeof(struct db_integers));

 mysql_integers->boolean="BOOL";
 mysql_integers->octet="TINYINT";

 printf("%s\n",mysql_integers->boolean);
 printf("%s\n",mysql_integers->octet);
}

Répondre à lami20j

2

lami20j, le vendredi 10 juin 2005 à 22:45:06

Et avec typedef

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

main()
{
 struct db_integers{  // Octets
     char *boolean;                // 1 bit
     char *octet;                     // 1
 };

 typedef struct db_integers integers;
 integers *mysql_integers;  //pointeur
 mysql_integers=malloc(sizeof(integers));
 
 mysql_integers->boolean="BOOL";
 mysql_integers->octet="TINYINT";

 printf("%s\n",mysql_integers->boolean);
 printf("%s\n",mysql_integers->octet);
}


Et ça marche.
J'ai ajouté malloc puisque à l'éxécution j'avais le message Erreur de segmentation

Répondre à lami20j

3

Yakurena, le vendredi 10 juin 2005 à 22:45:33

En C, tu ne peux pas affecter des chaînes de caractères avec l'opérateur " = ". Tu es obligé de passer par une fonction de la bibliothèque string.h : strcpy(chaine_destinataire,chaine_source)
Ici,tu dois donc utiliser l'instruction :
strcpy(mysql_integers->boolean,"BOOL")
Idem pour tous les autres champs de ta structure...

Répondre à Yakurena

8

sam3000, le samedi 11 juin 2005 à 12:06:16

Si il fait ça, il devra aussi allouer de l'espace pour chaque chaîne de sa structure avat le strcpy,
lui il fait de l'affectation de pointeurs avec "=" et ça marche dans ce cas!
@* Invité bienvenue, Membre t'es un(e) ami(e),
Profil rempli on t'aime, tu parle SMS tu vas dehors!

Répondre à sam3000

4

kilian, le samedi 11 juin 2005 à 00:59:14

Ok, alors j'ai essayé vos conseils.

Tout ceci se trouve dans des fichiers headers en fait, qui sont inclut dans le fichier c principal. Si je continue sur ce principe, ça ne fonctionne toujours pas (avec une ribambelle d'erreurs dans la compilation) même avec la methode de lami20j.

Par contre dans le main, la methode de lami20j marche très bien.
Je ne sais pas pourquoi.... Et je ne comprends pas non plus pourquoi il faut déclarer mysql_integers en pointeur, pourquoi le faire pointer vers un malloc et pourquoi avec tout ça je n'ai pas d'erreur comme avant....

Sinon, Yakurena, apparemment je n'ai pas besoin d'utiliser strcpy(), ça marche bien comme ça.... Enfin, du moins dans mon cas...

Merci.

Répondre à kilian

5

kilian, le samedi 11 juin 2005 à 01:05:43

De même quand j'essaie la methode lami20j dans le fichier c principal mais avant le main() j'ai aussi des erreurs:

champollion.c:11: error: conflicting types for `mysql_integers'
champollion.c:10: error: previous declaration of `mysql_integers'
champollion.c:11: attention : data definition has no type or storage class
champollion.c:13: error: erreur de syntaxe before '->' token

Par contre dans le main() ça passe....

Ce langage va me rendre fou O_o

Répondre à kilian

6

kilian, le samedi 11 juin 2005 à 01:34:27

Ah déjà pour l'histoire de strcpy() je comprends mieux :-)
http://c.developpez.com/faq/c/?page=strings#STRINGS_string_i­nit

Répondre à kilian

7

lami20j, le samedi 11 juin 2005 à 09:13:21

Salut,

Concernant strcpy Yakurena a raison, de toute façon tu as vu aussi dans les faqs de devoloppez.com.
Maintenant que le code que je t'ai donné fonctionne (malheureusement seul) peut être l'erreur ne viens pas de là.

Voilà j'ai divisé le code dans 2 fichiers : a.c et b.c

//a.c
#include <stdio.h>
#include <stdlib.h>
main()
{
test();
}

---------------------------------------------------------
//b.c
test()
{
  struct db_integers
   {  // Octets
         char *boolean;                // 1 bit
         char *octet;                     // 1
   };
typedef struct db_integers integers;

integers *mysql_integers;
mysql_integers=malloc(sizeof(integers));

mysql_integers->boolean="BOOL";
mysql_integers->octet="TINYINT";

printf("%s\n",mysql_integers->boolean);
printf("%s\n",mysql_integers->octet);
}


après je l'ai compilé
gcc -c a.c
gcc -c b.c
gcc -o ab a.o b.o

Répondre à lami20j

9

kilian, le samedi 11 juin 2005 à 16:03:22

Salut Lami20j,

Ca marche bien, extremement bien....
J'ai adapté à mon cas parce que j'ai bien d'autres structures, mais tout passe bien...

Au lieu de déclarer test() je l'ai déclaré comme ceci:
void test(void)

Mais ça marche très bien... Le seul soucis c'est que je ne comprends pas bien pourquoi :-)

Merci à tous encore une fois....

Répondre à kilian

10

kilian, le dimanche 12 juin 2005 à 05:02:59

Qui plus est ça m'arrangerais de déclarer ces variables structurées de manière globale. Si je les déclare dans une fonction, la variable sera locale et donc je ne pourrais pas l'utiliser dans une autre fonction...

Répondre à kilian

11

kilian, le lundi 13 juin 2005 à 16:53:00

J'ai en quelque sortes résolu le problème..

J'ai déclar mes structures de manière globale (en dehors de toute fonction). Par contre pour affecter les valeurs dans mes structures, je traite ça dans des fonctions.

Mais je me demande tout de même pourquoi je ne peux pas affecter de valeur dans des structures en dehors de toute fonction.

Répondre à kilian

12

lami20j, le lundi 13 juin 2005 à 19:20:27

Bonsoir kilian,

toujours en galère je vois.

Je ne sais pas si ça peut t'aider mais voilà ce que j'ai trouvé pour l'opérateur -> , c'est une sorte de définition si tu veut.

L'opérateur flèche -> est un opérateur monadique ([PROG] Caractérise une fonction ou une procédure dont la valeur de retour dépend d'un seul paramètres.) qui ne peut être surchargé que par une fonction membre non statique sans paramètre. 

Répondre à lami20j

13

mamiemando, le lundi 13 juin 2005 à 20:27:25

Pour la première version de son programme ca ne marchait pas car il utilisait des -> au lieu d'utiliser l'opérateur '.' :

typedef struct db_integers integers;
integers mysql_integers;
mysql_integers.boolean="BOOL";


1) L'opérateur . permet d'accéder au champ d'une structure.
2) L'opérateur * permet d'accéder au contenu d'une zone pointe (*add_mystructj équivaut à mystruct)
3) Rq : (son opérateur inverse est & : &mystruct équivaut à add_mystrcut).
4) L'opérateur -> est une combinaison des deux opérateurs '*' et '.' .

(*add_mystruct).champ équivaut add_struct->champ

Simple non ?

Répondre à mamiemando

14

kilian, le mardi 14 juin 2005 à 00:18:37

Ok ok, merci à tous....

Mais le soucis n'est pas là. Que ce soit un point ou une flêche, Gcc n'accepte pas que l'affectation dans une structure se fasse de manière globale.

Par exemple ceci ne marche pas:

struct machin{
        int a;
        double b;
};

struct machin var_machin;
var_machin.a=3;

int main()
{
}

Mais ça, ça passe:
struct machin{
        int a;
        double b;
};

struct machin var_machin;

void initialize_var_machin(void)
{
            var_machin.a=3;
}

int main()
{
	initialize_var_machin();
}


Pour le premier j'ai cette erreur:
essai.c:8: error: erreur de syntaxe before '.' token

Bizzare vous ne trouvez pas?

Répondre à kilian

15

mamiemando, le mardi 14 juin 2005 à 00:40:34

Mouais c'est vrai que c'est bizarre. En même temps les variables globales c'est mal... Et à la limite faire une fonction qui initialise ta structure c'est une bonne chose :

1) c'est plus propre
2) le jour ou tu feras du c++/java tu verras immédiatement à quoi sert un constructeur.

L'idéal pour programmer proprement c'est de faire ca :

mystruct.h

#ifndef MYSTRUCT
#define MYSTUCT

typedef struct machin * pstruct;

pstruct new_struct();
void set_a(pstruct s,int val);
void set_b(pstruct s,double vall);
void del_struct(pstruct s);

#endif

mystruct.c
#include "mystruct.h"

struct machin{
int a; 
double b;
};
//....


etc...

Répondre à mamiemando

16

kilian, le mardi 14 juin 2005 à 01:09:50

C'est vrai, c'est pas mal comme ça.
Du moins, une seule fonction pour attribuer toutes les valeurs ça peut être bien (pour mon cas).
Je pense que je vais faire comme ça.

En quoi c'est mieux finalement de passer l'adresse d'une structure dans les arguments d'une fonction pour en modifier la valeur plutôt que de modifier la structure dans la fonction à partir de son nom global?

Répondre à kilian

17

mamiemando, le mardi 14 juin 2005 à 08:25:50

En C tu ne peux pas modifier un paramètre (plus exactement, à l'appel de la fonction, tu empiles une copie des paramètres, dont la durée de vie est l'appel de cette fonction).

C'est pourquoi tu passes le pointeur (car la copie et l'original pointe tous deux sur la structure que tu veux corriger).

Répondre à mamiemando

18

kilian, le mardi 14 juin 2005 à 11:14:16

Ok, mais si tu utilises, dans une fonction, le nom d'une structure déclarée en globale, et que tu fais des modification sur cette structure dans la fonction, les changements seront toujours pris en compte après l'appel de la fonction.

Répondre à kilian

19

lami20j, le mardi 14 juin 2005 à 19:24:17

Bonsoir kilian et mamiemando,

kilian ça marche mais l'affectation de la variable tu doit la faire à l'intérieur de la procédure. (c'est pour ça que tu as eu le message essai.c:8: error: erreur de syntaxe before '.' token)

#include <stdio.h>
struct machin{
       int a;
};
struct machin var_machin;
main()
{
var_machin.a=3;
printf("%d\n",var_machin.a);
}

Répondre à lami20j

20

lami20j, le mardi 14 juin 2005 à 20:10:01

Re,

Pardonne pour moi, je n'ai pas fait attention Gcc n'accepte pas que l'affectation dans une structure se fasse de manière globale.
Cependant tu peut faire une affectation globale d'une structure en C de cette manière :

#include <stdio.h>
struct machin{
       int a;
       char nom[10];
};
/*affectation globale */
struct machin var_machin ={ 3, "kilian" };

main()
{
 printf("%d\n",var_machin.a);
 printf("%s\n",var_machin.nom);
}

Répondre à lami20j

21

 kilian, le mardi 14 juin 2005 à 20:18:38

Aaah d'accord. Merci pour l'astuce :-)

Répondre à kilian
Langage C - Les structures conditionnelles Qu'est-ce qu'une structure conditionnelle ? On appelle structure conditionnelle les instructions qui permettent de tester si une condition est vraie ou non. Ces structures conditionnelles peuvent être associées à des structures qui se répètent... www.commentcamarche.net/contents/c/ccond.php3
Les structures en langage C Différence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de... www.commentcamarche.net/contents/c/cstruct.php3
Les files en langage CLes files - Premier Entré Premier Sorti Requis I. INTRODUCTION II. Définition III. La construction du prototype d'un élément de la file IV. Opérations sur les files A. Initialisation B. Insertion d'un élément dans la file C. Oter un... www.commentcamarche.net/faq/sujet-8282-les-files-en-langage-c
Les piles en langage CLes piles Requis I. INTRODUCTION II. Définition III. La construction du prototype d'un élément de la pile IV. Opérations sur les piles A. Initialisation B. Insertion d'un élément dans la pile C. Ôter un élément de la pile D. Affichage... www.commentcamarche.net/faq/sujet-8283-les-piles-en-langage-c
Structure logique d'un disque durStructure logique d'un disque dur Introduction Lorsque vous utilisez votre ordinateur, vos données sont organisées sous forme de fichiers et de répertoires, selon une structure arborescente et ces éléments sont stockés sur votre disque dur. C'est... www.commentcamarche.net/faq/sujet-6034-structure-logique-d-un-disque-dur
Algorithme langage c et structure des données (Résolu)Bonjour, je ne trouve pas ou je puisse appliquer tout se que j'ai sur algorithme et langage c ainsi les structure des donnés svp je veux des exercices ainsi c est corrigées et des travaux pratiques et des mini projets corrigées merci d'avance www.commentcamarche.net/forum/affich-7335991-algorithme-langage-c-et-structure-des-donnees
Pointeur de structure dans fonction C (Résolu)Salut à tous, j'ai une fonction InsereDansListe rien de plus normal qui doit commme son nom l'indique inserer un pointeur vers un element dans une liste. Le probleme c'est que lorsque je passe un pointeur sur une liste vide ou même pleine et que... www.commentcamarche.net/forum/affich-2513913-pointeur-de-structure-dans-fonction-c
[C] Passage d'une structure en paramètre (Résolu)Bonsoir, J'ai crée un petit programme, dont une fonction a du mal à compiler, et après plusieurs recherches, je ne trouve pas la solution. Mais je sais que ça doit être quelque chose de simple. Voici la partie du main concernée: (Je crée une... www.commentcamarche.net/forum/affich-4676181-c-passage-d-une-structure-en-parametre
Télécharger Visual C++ 2008 ExpressVisual C++ Express est une version "gratuite" et allégée de Visual Studio ; l'utilisation requiert l'inscription sur le site de Microsoft. Cet environnement de développement permet de créer des application Win32 ou du .NET C. www.commentcamarche.net/telecharger/telecharger-34056350-visual-c-2008-express
Télécharger Dev-C++Dev-C++ est un environnement de développement intégré (IDE) en C/C++. Son compilateur est basé sur Mingw de GCC, mais il peut également être utilisé avec CygWin. www.commentcamarche.net/telecharger/telecharger-59-dev-c
Les structures en langage C++Différence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de... www.commentcamarche.net/contents/cpp/cppstruct.php3
Langage C++ - Les structures conditionnellesQu'est-ce qu'une structure conditionnelle ? On appelle structure conditionnelle les instructions qui permettent de tester si une condition est vraie ou non. Ces structures conditionnelles peuvent être associées à des structures qui se répètent... www.commentcamarche.net/contents/cpp/cppcond.php3
Langage C - Les tableauxType de données complexes Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois. Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient beaucoup trop lourdes... www.commentcamarche.net/contents/c/ctab.php3