gratifiant > comp.lang.* > comp.lang.c

Mousta2016 (12/03/2018, 04h48)
Bonjour, je voudrai savoir comment saisir et afficher l'élément E:
struct ensemble{
int m_max;
int m_cardinal;
int * m_éléments;
};
typedef struct ensemble ENSEMBLE;
ENSEMBLE *E;
Merci cordialement
Marc Espie (12/03/2018, 08h32)
In article <Yq6dneSSEuvwdzjHnZ2dnUU7983NnZ2d>,
Mousta2016 <nospam_soryk03> wrote:
>Bonjour, je voudrai savoir comment saisir et afficher l'élément E:
>struct ensemble{
>int m_max;
>int m_cardinal;
>int * m_éléments;
>};
>typedef struct ensemble ENSEMBLE;
>ENSEMBLE *E;
>Merci cordialement


Deja, les accents dans les noms de variable, ca va poser un souci.

Ensuite, je ne sais pas si tu as decide tout seul de mettre des
typedefs en MAJUSCULE, ou si c'est dans ton cours, mais c'est
totalement loufoque... on reserve les majuscules pour les macros.

Pour finir, depuis la derniere fois, sais-tu lire proprement
un nombre sur l'entree standard ?...

parce que je soupconne qu'on te demande de:
- lire la taille de l'ensemble
- puis chacun des elements
- et de trouver le max.

En gros, des fonctions:

void saisis_ensemble(struct ensemble *e);
int trouve_max(struct ensemble *e);
void affiche_ensemble(const struct ensemble *e);
Lucas Levrel (12/03/2018, 10h38)
Le 12 mars 2018, à 06:32, Marc Espie a écrit :

> In article <Yq6dneSSEuvwdzjHnZ2dnUU7983NnZ2d>,
> Mousta2016 <nospam_soryk03> wrote:
> Deja, les accents dans les noms de variable, ca va poser un souci.
> Ensuite, je ne sais pas si tu as decide tout seul de mettre des
> typedefs en MAJUSCULE, ou si c'est dans ton cours, mais c'est
> totalement loufoque... on reserve les majuscules pour les macros.
> Pour finir, depuis la derniere fois, sais-tu lire proprement
> un nombre sur l'entree standard ?...


À mon avis ce n'est pas le même. L'autre avait essayé d'implémenter la
saisie et l'affichage... Ça sent plutôt le prof qui a fait un mode
d'emploi de la demande d'aide sur Usenet, avec abonnement à giganews,
comment obfusquer son adresse mail, formule de politesse... Il a juste
oublié de dire qu'il fallait suivre le fil, répondre aux questions et dire
merci !

Faudrait voir sur Stackoverflow s'il n'y a pas des questions corrélées :-)
Pascal J. Bourguignon (12/03/2018, 13h23)
espie (Marc Espie) writes:

> In article <Yq6dneSSEuvwdzjHnZ2dnUU7983NnZ2d>,
> Mousta2016 <nospam_soryk03> wrote:
> Deja, les accents dans les noms de variable, ca va poser un souci.


IIRC, c'est possible en C11, mais il va falloir les écrire comme ça:

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

struct ensemble {
int m_max;
int m_cardinal;
int * m_\u00e9l\u00e9ments;
};
typedef struct ensemble ENSEMBLE;
ENSEMBLE *E;

int f(ENSEMBLE* e){
if(e->m_max<1){
return 0; }
e->m_cardinal=1;
e->m_\u00e9l\u00e9ments[0]=42;
return 1; }

void* check_memory(void* block){
if(0==block){
fprintf(stderr,"Out of memory\n");
exit(EX_OSERR);}
return block;}

int main(){
E=check_memory(malloc(sizeof(E)));
E->m_max=10;
E->m_cardinal=0;
E->m_\u00e9l\u00e9ments=check_memory(malloc(sizeof (E->m_\u00e9l\u00e9ments[0])*E->m_max));
return (0==f(E))
? EX_SOFTWARE
: EX_OK;}

Rien n'empêche d'utiliser un éditeur qui affiche les séquences \uXXXX
comme leur caractère unicode, et vice-versa, qui encode les caractères
hors du jeu ASCII en utilisant ces séquences.

> Ensuite, je ne sais pas si tu as decide tout seul de mettre des
> typedefs en MAJUSCULE, ou si c'est dans ton cours, mais c'est
> totalement loufoque... on reserve les majuscules pour les macros.
> Pour finir, depuis la derniere fois, sais-tu lire proprement
> un nombre sur l'entree standard ?...
> parce que je soupconne qu'on te demande de:


Non, tu soupçonnes.
[..]
mousta2016 (12/03/2018, 13h42)
Le lundi 12 Mars 2018 à 07:32 par espie :
[..]
> void saisis_ensemble(struct ensemble *e);
> int trouve_max(struct ensemble *e);
> void affiche_ensemble(const struct ensemble *e);

Merci espi votre suggestion très pertinente
Pascal J. Bourguignon (12/03/2018, 15h46)
Mousta2016 <nospam_soryk03> writes:

> Bonjour, je voudrai savoir comment saisir et afficher l'élémentE:
> struct ensemble{
> int m_max;
> int m_cardinal;
> int * m_éléments;
> };
> typedef struct ensemble ENSEMBLE;
> ENSEMBLE *E;
> Merci cordialement


Le langage C ne fourni pas d'opération de sérialisation et de
désérialisation automatique. Alors il faut le faire soi-même.

En particulier, il faut décider sur un format de fichier, c'est àdire
une syntaxe.

Comme tu utilises les mots "saisir" et "afficher", on peut supposer que
tu veux définir un format lisible par un être humain.

Comme il s'agit d'une structure de donnée appelée "ensemble", on peut
supposer qu'il serait approprié d'utiliser la syntaxe des ensembles
mathématiques:

ensemble ::= '{' [ elements ] '}' .
elements ::= element [ ',' elements ] .

Par exemple: {1,2,3}

Il faut aussi définir la syntaxe d'un élément, ici un entier(peut-il
être signé ? Positif ou négatif ?), ainsi que des éléments lexicaux :
peut-on insérer des espaces, des passages à la ligne, dans quellebase
les entiers sont écrits ? Peut-on insérer des séparateurs demilliers ?

{ 123 456 789, 10 234,
42 }
ou:

{ 123456789, 10234,
42 }
etc.

Une fois que tu auras écrit toutes ces spécifications, il sera temps de
considérer comment les implanter. Une solution, lorsqu'on a des règles
de syntaxe et lexicales un peu complexes, est d'utiliser un générateur
d'analyseur lexical et d'analyseur syntaxique.

Par exemple:

# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# Makefile
# ensemble.bison
# ensemble.c
# ensemble.flex
# ensemble.h
# list.c
# list.h
# main.c
# tokens.h
# util.c
# util.h
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
XSOURCES=main.c ensemble.c util.c list.c ensemble_bison.c ensemble_flex.c
XOBJECTS=$(SOURCES:.c=.o)
XINCLUDES = -I.
XCFLAGS=$(INCLUDES)
X
Xall:ensemble
X
Xensemble_flex.c: ensemble.flex
X flex -o $@ $<
X
Xensemble_bison.c: ensemble.bison
X bison -o $@ $<
X
Xensemble_flex.o: ensemble_flex.c util.h
Xensemble_bison.o: ensemble_bison.c ensemble.h list.h util.h
Xutil.o:util.c util.h
Xlist.o:list.c list.h util.h
Xensemble.o:ensemble.c ensemble.h util.h
Xmain.o:main.c ensemble.h
X
Xensemble:$(OBJECTS)
X $(CC) -o $@ $(OBJECTS)
X
Xclean:
X -rm -rf $(OBJECTS)
X -rm -rf ensemble_flex.c ensemble_bison.c
X -rm -rf ensemble
X
X
Xtest:ensemble
X @echo 'Empty set test:'
X echo '{}' | ./ensemble
X @echo 'Simple test:'
X echo '{1,2,3}' | ./ensemble
X @echo 'Space test:'
X echo ' { 1 , 2 , 3 } ' | ./ensemble
X @echo 'Multi-line test:'
X (echo '{11111,';echo '22222,';echo '33333}') | ./ensemble
X @echo 'Signed test:'
X echo '{-1000000000,-2000000,-3000,-4,-0,0,+0,+4,+3000,+2000000,+1000000000}' | ./ensemble
END-of-Makefile
echo x - ensemble.bison
sed 's/^X//' >ensemble.bison << 'END-of-ensemble.bison'
X%{
X
X#include <stdlib.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <list.h>
X#include <util.h>
X#include <ensemble.h>
X
X int yylex(void);
X int yyvalue;
X
X void yyerror(char const * message){
X error("%s",message);}
X
X typedef union {
X int element;
X list_t* elements;
X ENSEMBLE* set;
X } my_synthetic;
X
X ENSEMBLE* parsed_set;
X
X#define YYSTYPE my_synthetic
X
X// #define DEBUG(e) do{e}while(0)
X#define DEBUG(e) do{}while(0)
X
X%}
X
X/* %define set.value.type {ELEMENT*} */
X/* %define elements.value.type {list_t*} */
X/* %define element.value.type {int} */
X
X%token INTEGER
X%token COMMA
X%token OPEN
X%token CLOSE
X
X%%
X
Xset : OPEN elements CLOSE
X {
X ENSEMBLE* e=ensemble_from_list($2.elements);
X $$.set=parsed_set=e;
X
X } ;
X
Xelements : { $$.elements=NIL; }
X | element { $$.elements=cons($1.element,NIL); }
X | elements COMMA element
X { DEBUG(printf("elements ");list_print($1.elements);printf("element%d\n",yy value);fflush(stdout););
X list_t* list=$1.elements; push($3.element,&list); $$.elements=list; }
X ;
X
Xelement : INTEGER
X { DEBUG(printf("element %d\n",yyvalue);fflush(stdout);); $$.element=yyvalue; } ;
END-of-ensemble.bison
echo x - ensemble.c
sed 's/^X//' >ensemble.c << 'END-of-ensemble.c'
X#include <ensemble.h>
X#include <util.h>
X#include <list.h>
X#include <stdlib.h>
X#include <stdio.h>
X
Xvoid ensemble_print(ENSEMBLE* set){
X printf("{");
X const char* sep="";
X for(int i=0;i<set->m_cardinal;i++){
X printf("%s%d",sep,set->m_elements[i]);
X sep=",";
X }
X printf("}");
X printf("\n");
X}
X
X
XENSEMBLE* ensemble_from_list(list_t* list){
X int count=length(list);
X
X ENSEMBLE* e=check_memory(malloc(sizeof(*e)));
X e->m_max=count;
X e->m_elements=check_memory(malloc(sizeof(e->m_elements[0])*e->m_max));
X e->m_cardinal=0;
X
X list_t* current=list;
X for(int i=0;current;i++,current=cdr(current)){
X e->m_elements[i]=car(current);
X e->m_cardinal++;
X }
X
X return e;}
END-of-ensemble.c
echo x - ensemble.flex
sed 's/^X//' >ensemble.flex << 'END-of-ensemble.flex'
X/* -*- mode:c -*- */
X%{
X
X#include <ctype.h>
X#include <limits.h>
X#include <stdio.h>
X#include <util.h>
X#include <tokens.h>
X
Xint yyvalue;
Xint convert_int(const char*);
X
X// #define DEBUG(e) do{e}while(0)
X#define DEBUG(e) do{}while(0)
X
X%}
X
X%option noyywrap
X
X%%
X
X"," { DEBUG(printf("COMMA\n");); return COMMA; }
X"{" { DEBUG(printf("OPEN\n");); return OPEN; }
X"}" { DEBUG(printf("CLOSE\n");); return CLOSE; }
X
X
X[\-+]{0,1}([1-9][0-9]*|0) { yyvalue=convert_int(yytext); DEBUG(printf("INTEGER %d\n",yyvalue);); return INTEGER; }
X
X
X[ \t\n]+ /* eat up whitespace */
X. error("Unrecognized character: %s\n",yytext);
X
X%%
X
END-of-ensemble.flex
echo x - ensemble.h
sed 's/^X//' >ensemble.h << 'END-of-ensemble.h'
X#ifndef ensemble_h
X#define ensemble_h
X#include <list.h>
X
Xstruct ensemble {
X int m_max;
X int m_cardinal;
X int * m_elements;
X};
Xtypedef struct ensemble ENSEMBLE;
X
Xvoid ensemble_print(ENSEMBLE* set);
XENSEMBLE* ensemble_from_list(list_t* list);
X
X#endif
END-of-ensemble.h
echo x - list.c
sed 's/^X//' >list.c << 'END-of-list.c'
X#include <list.h>
X#include <util.h>
X#include <stdlib.h>
X#include <stdio.h>
X
Xlist_t* make_empty_list(void){
X return NIL; }
X
Xlist_t* cons(int element,list_t* rest){
X list_t* new=check_memory(malloc(sizeof(*new)));
X new->element=element;
X new->next=rest;
X return new;}
X
Xint car(list_t* list){
X return list
X ?list->element
X :0;}
X
Xlist_t* cdr(list_t* list){
X return list
X ?list->next
X :NIL;}
X
Xvoid push(int element,list_t** list){
X (*list)=cons(element,*list);}
X
Xlist_t* nreverse(list_t* list){
X list_t* reversed=NIL;
X while(list){
X list_t* current=list;
X list=cdr(list);
X current->next=reversed;
X reversed=current;}
X return reversed;}
X
Xint length(list_t* list){
X int count=0;
X while(list){
X count++;
X list=cdr(list);}
X return count;}
X
Xvoid list_print(list_t* list){
X if(NIL==list){
X printf("NIL");
X }else{
X printf("(");
X const char* sep="";
X while(list){
X printf("%s%d",sep,car(list));
X sep=",";
X list=cdr(list);}
X printf(")");}}
X
END-of-list.c
echo x - list.h
sed 's/^X//' >list.h << 'END-of-list.h'
X#ifndef list_h
X#define list_h
X
X
Xtypedef struct list_t {
X int element;
X struct list_t* next;
X} list_t;
X
X#define NIL ((void*)0)
X
Xlist_t* make_empty_list(void);
Xlist_t* cons(int element,list_t* rest);
Xint car(list_t* list);
Xlist_t* cdr(list_t* list);
Xvoid push(int element,list_t** list);
Xlist_t* nreverse(list_t* list);
Xint length(list_t* list);
Xvoid list_print(list_t* list);
X
X#endif
END-of-list.h
echo x - main.c
sed 's/^X//' >main.c << 'END-of-main.c'
X#include <ensemble.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <sysexits.h>
X
XENSEMBLE* E;
X
Xint yyparse(void);
XENSEMBLE* parsed_set;
X
Xint main(){
X yyparse();
X E=parsed_set;
X ensemble_print(E);
X return EX_OK;}
END-of-main.c
echo x - tokens.h
sed 's/^X//' >tokens.h << 'END-of-tokens.h'
X#ifndef tokens_h
X#define tokens_h
X
X enum yytokentype
X {
X INTEGER = 258,
X COMMA = 259,
X OPEN = 260,
X CLOSE = 261
X };
X
X#endif
END-of-tokens.h
echo x - util.c
sed 's/^X//' >util.c << 'END-of-util.c'
X#include <util.h>
X#include <ctype.h>
X#include <limits.h>
X#include <stdio.h>
X#include <stdarg.h>
X#include <stdlib.h>
X#include <sysexits.h>
X
Xvoid error(const char* format,...){
X va_list ap;
X va_start(ap,format);
X vfprintf(stderr,format,ap);
X va_end(ap);
X exit(EX_DATAERR);}
X
Xvoid* check_memory(void* block){
X if(0==block){
X error("Out of memory\n");}
X return block;}
X
Xint convert_int(const char* text){
X int sign=1;
X int value=0;
X int i=0;
X switch(text[i]){
X case '-': sign=-1; // fall thru
X case '+': i++;}
X while(text[i]){
X if(INT_MAX/10<value){
X // Note: since we compare with INT_MAX, we exclude INT_MIN.
X error("integer too big: %s",text);}
X value=value*10+digittoint(text[i]);
X i++;}
X return sign*value;}
X
END-of-util.c
echo x - util.h
sed 's/^X//' >util.h << 'END-of-util.h'
X#ifndef util_h
X#define util_h
X
Xvoid error(const char* format,...);
Xvoid* check_memory(void* block);
Xint convert_int(const char* text);
X
X#endif
END-of-util.h
exit

# [pjb@despina :0.0 ensemble]$ shar * > ../ensemble.shar
# [pjb@despina :0.0 ensemble]$ make
cc -I. -c -o main.o main.c
cc -I. -c -o ensemble.o ensemble.c
cc -I. -c -o util.o util.c
cc -I. -c -o list.o list.c
bison -o ensemble_bison.c ensemble.bison
cc -I. -c -o ensemble_bison.o ensemble_bison.c
flex -o ensemble_flex.c ensemble.flex
cc -I. -c -o ensemble_flex.o ensemble_flex.c
cc -o ensemble main.o ensemble.o util.o list.o ensemble_bison.o ensemble_flex.o
# [pjb@despina :0.0 ensemble]$ make test
Empty set test:
echo '{}' | ./ensemble
{}
Simple test:
echo '{1,2,3}' | ./ensemble
{3,2,1}
Space test:
echo ' { 1 , 2 , 3 } ' | ./ensemble
{3,2,1}
Multi-line test:
(echo '{11111,';echo '22222,';echo '33333}') | ./ensemble
{33333,22222,11111}
Signed test:
echo '{-1000000000,-2000000,-3000,-4,-0,0,+0,+4,+3000,+2000000,+1000000000}' | ./ensemble
{1000000000,2000000,3000,4,0,0,0,-4,-3000,-2000000,-1000000000}
# [pjb@despina :0.0 ensemble]$

Note: l'ordre n'a pas été préservé, mais comme il s'agit d'un ensemble,
ça ne devrait pas importer. Par contre, les doublons ne sont pas
éliminer, ça devrait surement être spécifié et implémenté, pour des
ensembles?
Marc Espie (12/03/2018, 18h30)
In article <m2ina1s8xh.fsf>,
Pascal J. Bourguignon <pjb> wrote:
[..]
> ensemble ::= '{' [ elements ] '}' .
> elements ::= element [ ',' elements ] .
>Par exemple: {1,2,3}


[ snip plein de code ]

Avoue Pascal, t'avais du temps a perdre, hein ?

Je doute que ca soit exactement la reponse attendue... ;)
Discussions similaires