Mini Excel – système de donnée en grille - C - Programmation
Marsh Posté le 28-07-2015 à 00:39:04
À mon avis un simple tableau à deux dimensions est bien plus adapté et simple... Enfin je dis "deux dimensions", si tu veux sauvegarder des chaînes de caractères c'est plutôt trois dimensions, m'enfin peu importe.
Marsh Posté le 28-07-2015 à 09:53:20
Excel, c'est avant tout un tableur plus qu'un "tableau". Ca veut dire que ça fait du calcul. Est-ce que tu as prévus de pouvoir faire un système de formule dans ton mini Excel ?
Parce que si c'est juste pour afficher des chaînes de caractères dans une grille, un tableau 2D de char*, ça suffit effectivement. Mais si y'a des formules, là, ça va se compliquer beaucoup plus puisqu'il faudra gérer les références à des adresses d'autres cellules.
Marsh Posté le 28-07-2015 à 12:53:50
Non, je pense que je peux mettre des formules mais ça serais beaucoup trop compliqué .
Avec un tableau c'est possible de connaitre l'emplacement de chaque valeur et de pouvoir les modifiées à cette emplacement?
Je vais demandé à mon professeur si je suis obligé d'utilisé une liste chainée et si je dois être capable de faire des calculs entre les différentes cases.
Marsh Posté le 28-07-2015 à 14:00:08
rufo a écrit : Excel, c'est avant tout un tableur plus qu'un "tableau". Ca veut dire que ça fait du calcul. Est-ce que tu as prévus de pouvoir faire un système de formule dans ton mini Excel ? |
Oui, les formules ça demande un peu plus de boulot. En particulier pour interdire la création de dépendances croisées entre formules. Mais bon, de mon temps, c'était du niveau de la première année de spécialisation en info, ce genre de projet, tant que les formules restaient simples (histoire de pas perdre de temps sur le parsing en lecture/écriture de formules complexes et se concentrer sur la bonne manipulation des données dans la grille) .
A+,
Marsh Posté le 30-07-2015 à 13:09:37
Mon professeur m'a indiqué que j'était obliger de faire cette grille en liste chainée, ça complique encore plus la chose...
Marsh Posté le 30-07-2015 à 14:09:19
Bon ben ton exercice est plus sur la manipulation de cette structure que sur autre chose alors.
Tu as une structure grille qui a deux champs, lignes et colonnes, qui sont des listes chainées.
Le champ lignes va chainer des éléments tête de ligne, qui vont avoir pour contenu un entier (le numéro de ligne) et un pointeur sur la première case non vide de cette ligne.
Le champ colonnes va chainer des éléments tête de colonne, qui vont avoir pour contenu un entier (le numéro de colonne) et un pointeur sur la première case non vide de cette colonne.
Une case non vide de la ligne va donc être dans une double liste chaînée, celle des cases de sa ligne et celle des cases de sa colonne. Elle va avoir de plus un contenu (a priori un pointeur sur une structure qui va être une structure classique: un record dont le premier champ est le type de la case (nombre, chaîne...) et le second, une union d'objets paramétrés par le type du premier champ.) Dans un premier temps, tu peux faire avec un contenu de case tant de type int, et modifier ensuite.
Pour des raisons d'efficacité, il vaut mieux utiliser un double chaînage pour les lignes et colonnes, ou alors stocker le numéro de ligne et de colonne dans la case (mais cette deuxième solution plus simple au départ, risque de poser des problèmes plus tard si on veut implémenter une opération d'insertion de ligne/colonne). Une autre solution peut être d'avoir un chaînage simple, et deux champs pointant sur la tête de ligne et tête de colonne pour chaque case de la grille.
Tu vas donc avoir à gérer:
- La création d'une grille et sa destruction.
- L'insertion d'une case
- L'ajout/modification/lecture du contenu d'une case
- La destruction d'une case
- l'impression du contenu de la grille
...
L'insertion et la destruction d'une case (qui peuvent aboutir aussi a l'insertion/destruction d'une ligne/colonne et donc à celle de l'élément tête de ligne/colonne) vont mettre en œuvre des manipulations de listes (doublement?) chaînes complexes, probablement un des buts de ton exo.
A+,
Marsh Posté le 30-07-2015 à 16:57:58
Waw va falloir que je m'exerce avec d'autre exercices et cours sur le net alors parce que je me sens pas capable du tout de faire ça pour l'instant.
Tu aurais des liens ou des vidéos de cours ou d'exercice qui pourrais m'aider a m'améliorer pour être capable de faire ce projet?
Histoire que je ne perde pas trop de temps à apprendre des choses qui me serais inutile pour cette application, car j'ai 13 examens à repasser pour la 18 aout qui n'on rien a voir avec le langage C, je dois donc être le plus rapide possible.
Marsh Posté le 02-08-2015 à 18:55:33
J'ai fait des recherches sur internet et quelqu'un parle de faire ça comme ça :
"On pourrait envisager une liste chainée double composée d'éléments à 4 pointeurs : Haut Bas Gauche Droite, ce qui permet une navigation en ligne et en colonnes.C'est certainement le plus simple et le plus efficace."
Ca serais pas plus simple comme ça?
Marsh Posté le 02-08-2015 à 19:15:03
C'est pas plus simple, puisque grosso modo, c'est ce que je vous ai indiqué, en entrant dans les détails, ce que ne fait pas une approche aussi succincte que la phrase que vous citez (qui omet par exemple de préciser que pour un tableur, on ne met dans la grille que les cases non vides, et c'est ce qui fait la difficulté de l'implémentation de la structure, entre autres).
A+,
Marsh Posté le 02-08-2015 à 20:16:41
Dit moi ce que t'en pense de mon schéma théorique :
En voulant faire un tableau excel 10X10
Donc ça serai une liste chainée de case qui correspondrais chacune à une colonne entière de A à J et dans chaque case se trouverais 10 valeurs qui correspondrais au 10 lignes.
Je ne sais pas si c'est ce que tu m'a proposer car je n'ai pas tout compris vu que je pense manqué encore de certaines notions.
Est-ce que ça a l'air d'une bonne base que j'améliorerai après? est-ce qu'il est possible de naviguer d'une case à une autre?
Marsh Posté le 03-08-2015 à 03:34:27
Il y a de l'idée dans ton 2e crobard, sauf que ça va pas être aussi régulier si tu n'as comme cases que celles vraiment remplies.
A+,
Marsh Posté le 03-08-2015 à 10:12:48
Je peux remplir dès le départ celle qui sont vide par une valeur = 0
Marsh Posté le 03-08-2015 à 12:19:16
Non, justement pas, si tu as une grille avec deux cellules, une en (1,1) et l'autre en (30 000, 30 000), ça t'oblige a créer une structure avec 30 000 * 30 000 cases, soit 900 000 000, toutes à 0 sauf 2, ce qui n'est pas bon.
Vaut mieux créer une table a 2 cases (6 si on tient compte des cases lignes et colonnes)
Un exemple avec 5 cases du type de structure chaîne à gérer. Cliquer pour agrandir l'image
A+,
Marsh Posté le 03-08-2015 à 14:45:00
Que veulent dire les petites masses que tu as dessinées?
Marsh Posté le 03-08-2015 à 14:45:34
Bonjour,
dans un 1er temps je voudrais simplifier grandement la chose en faisant une série de listes chainées que je mettre l'une en dessous de l'autre avec des valeurs du même nombre de chiffre (ex: 0000|0001|1235|0025|) et donc je voulais crée la grille de départ avec des 0 partout mais le problème c'est que avec des int si j’écris 0000 et que je fait un printf il me ressort 0 donc je dois transformer le champs nombre en chaine de caractère, ça fonctionne pour l'initialisation mais quand j'ajoute une case ça ne fonctionne pas.
Je vous met mon code de départ en int et le code que j'ai essayer de transformer en char
(les commentaires c'est parce que je commence à peine à comprendre comment fonctionne une liste chainée)
Code :
|
Marsh Posté le 03-08-2015 à 15:02:44
Voici le code que j'ai essayer de transformer en caractère mais dont la fonction insertion début de liste ne fonctionne pas (la fonction initialisation fonctionne)
Code :
|
Marsh Posté le 03-08-2015 à 16:22:17
joachimssj a écrit : Que veulent dire les petites masses que tu as dessinées? |
C'est une convention courante pour indiquer qu'un pointeur est à NULL.
A+,
Marsh Posté le 03-08-2015 à 16:36:28
J'essai de faire le menu, j'ai essayer avec un switch case mais ça ne marche pas alors je me suis dit que j'allais faire une série de condition si mais quand j'encode ça ca ne marche pas
Code :
|
Quand l'utilisateur encode a1 ça ne fait rien du tout, il y a t-il une manipulation spéciale à faire quand on fait une condition avec des caractères?
Marsh Posté le 03-08-2015 à 16:45:00
Faut mettre char caseselectionner[3] il me semble car là, t'as pas la place de mettre 2 caractères plus celui de fin de chaîne
Marsh Posté le 03-08-2015 à 16:59:56
C'est juste mais ça ne marche quand même pas, ça n'affiche rien
donc là j'ai
Code :
|
Marsh Posté le 03-08-2015 à 17:15:22
> char chainecaract[5];
...
> sprintf(element->chainecaract,"00000" );
La chaine "00000" fait 6 caractères (tu n'as pas compté le \0 final), donc ça va pas marcher comme tu le supposes.
> nouvelelement->chainecaract[5]=nvchainecaract[5];
C'est pas comme ça qu'on copie une chaîne de caractères en C.
En reprenant ton code:
Code :
|
C'est pas testé, car j'ai désinstallé mon compilo C il y a qques jours et pas encore réinstallé une version à jour, mais ça te donne une idée.
Ne fais pas faire plusieurs choses à une fonction, sinon on finit par ne plus savoir qui fait quoi:
Si une fonction a pour role d'insérer, en cas d'échec, il faut lui faire signaler l'échec, en général avec sa valeur de retour, mais son role n'est pas de sortir du programme: Bref une fonction insertion n'est pas une fonction insertion ou sortie du programme.
Quand tu as des champs de taille fixe, n'utilises jamais sprintf et strcpy, mais utilises les variantes qui tiennent compte de la taille, snprintf et strncpy.
EDIT: bon, comme d'hab, le formatage du forum bouffe mon indentation
EDIT2: bon, j'ai installé vite fait mingw et ce code marche.
A+,
Marsh Posté le 03-08-2015 à 17:20:02
Finalement je suis revenu sur des variable en int, en faisant un mettant %05d dans mon printf je peut afficher 5 chiffre a chaque fois.
j'en suis là dans mon code, j’essaie de réaliser le menu, je test les condition sur des chaine de caractère car il faudra désigné une case comme par ex a1 mais je n'y arrive pas.
Je n'arrive pas à utiliser les condition avec des chaines de caractère.
[cpp][/cpp]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Element Element; // Creation d'une structure Element qui possede un champs nombre et un pointeur vers l'element suivant //
struct Element
{
int nombre;
Element *suivant;
};
typedef struct Liste Liste;
struct Liste
{
Element *premier; // une structure de type liste (C'est la case qui pointe vers le 1ère element) avec un pointeur qui pointe vers le premier element
};
Liste *initialisation() // Fontion pour initialiser un premiere element et la case de controle liste//
{
Liste *liste = malloc(sizeof(*liste)); // on alloue de la memoire pour un element et pour une case liste (celui qui pointe vers le 1er element)
Element *element = malloc(sizeof(*element));
if (liste == NULL || element == NULL) // on verifie que les alloc dyn on fonctionné//
{
exit(EXIT_FAILURE);
}
element->nombre=0; // On attribue au champs nombre du 1er element la valeur 0, on fait pointer le pointeur suivant de l'element vers NULL//
element->suivant=NULL; // On fait pointer le pointeur de la case liste vers le nouvel element //
liste->premier=element;
return liste;
}
void inssertiondebutdliste(Liste *liste,int nvnombre) // Fonction qui va inséré un nouvel élement en début de liste//
{
Element *nouvelelement = malloc(sizeof(*nouvelelement)); // on allou la memeoire pour le nouvel element//
if (liste == NULL || nouvelelement == NULL)
{
exit(EXIT_FAILURE);
}
nouvelelement->nombre=nvnombre; // on attribue au champs nombre la valeur nvnombre//
nouvelelement->suivant=liste->premier; // on fait pointer le pointeur suivant du nouvel ellement vers le meme endroit que le ponteur de la case liste(qui pointe vers le 1er element actuel//
liste->premier= nouvelelement; // et on fait pointer la case liste vers le nouveau premier element//
}
void suprimer1erelement(Liste *liste) // fonction qui supprime le 1er element de la liste//
{
if (liste == NULL)
{
exit(EXIT_FAILURE);
}
if (liste->premier != NULL) // si le 1er element n'est pas nul//
{
Element *asuprimer = liste->premier; // on cré un pointeur de type element qui va pointer la ou pointe la case liste qui est le 1er element actuel//
liste->premier=liste->premier->suivant; // on fait que le pointeur de la case liste ne pointe plus vers le 1er element actuel met l'elmenent vers lequel le 1er element pointe cad le 2eme element qui sera le nouveau premier element//
free(asuprimer); // on efface de la memoire ce que notre pointeur pointe cad le 1er element actuel//
}
}
void afficherlistechainer(Liste *liste) // fonction qui affiche la liste chainée //
{
if (liste == NULL)
{
exit(EXIT_FAILURE);
}
Element *actuel= liste->premier; // on crée un element appelé element actuel qui vaut le premier de la liste//
while(actuel != NULL) // on commence par afficher le nombre de l'element actuel qui est le 1er element, puis on passe a l'element suivant et on le parcours, on le fait tant qu'on est pas arriver a la fin de la liste chainé qui vaut NULL//
{
printf("%05d|",actuel->nombre);
actuel=actuel->suivant;
}
}
void initialisationgrille()
{
Liste *malistedecolonne=initialisation();
inssertiondebutdliste(malistedecolonne,4);
inssertiondebutdliste(malistedecolonne,3);
inssertiondebutdliste(malistedecolonne,2);
inssertiondebutdliste(malistedecolonne,1);
inssertiondebutdliste(malistedecolonne,0);
malistedecolonne->premier->suivant->suivant->suivant->suivant->suivant->nombre=5;
Liste *maliste1=initialisation();
inssertiondebutdliste(maliste1,0000);
inssertiondebutdliste(maliste1,0000);
inssertiondebutdliste(maliste1,0000);
inssertiondebutdliste(maliste1,0000);
inssertiondebutdliste(maliste1,0000);
Liste *maliste2=initialisation();
inssertiondebutdliste(maliste2,0000);
inssertiondebutdliste(maliste2,0000);
inssertiondebutdliste(maliste2,0000);
inssertiondebutdliste(maliste2,0000);
inssertiondebutdliste(maliste2,0000);
Liste *maliste3=initialisation();
inssertiondebutdliste(maliste3,0000);
inssertiondebutdliste(maliste3,0000);
inssertiondebutdliste(maliste3,0000);
inssertiondebutdliste(maliste3,0000);
inssertiondebutdliste(maliste3,0000);
Liste *maliste4=initialisation();
inssertiondebutdliste(maliste4,0000);
inssertiondebutdliste(maliste4,0000);
inssertiondebutdliste(maliste4,0000);
inssertiondebutdliste(maliste4,0000);
inssertiondebutdliste(maliste4,0000);
Liste *maliste5=initialisation();
inssertiondebutdliste(maliste5,0000);
inssertiondebutdliste(maliste5,0000);
inssertiondebutdliste(maliste5,0000);
inssertiondebutdliste(maliste5,0000);
inssertiondebutdliste(maliste5,0000);
Liste *maliste6=initialisation();
inssertiondebutdliste(maliste6,0000);
inssertiondebutdliste(maliste6,0000);
inssertiondebutdliste(maliste6,0000);
inssertiondebutdliste(maliste6,0000);
inssertiondebutdliste(maliste6,0000);
Liste *maliste7=initialisation();
inssertiondebutdliste(maliste7,0000);
inssertiondebutdliste(maliste7,0000);
inssertiondebutdliste(maliste7,0000);
inssertiondebutdliste(maliste7,0000);
inssertiondebutdliste(maliste7,0000);
Liste *maliste8=initialisation();
inssertiondebutdliste(maliste8,0000);
inssertiondebutdliste(maliste8,0000);
inssertiondebutdliste(maliste8,0000);
inssertiondebutdliste(maliste8,0000);
inssertiondebutdliste(maliste8,0000);
Liste *maliste9=initialisation();
inssertiondebutdliste(maliste9,0000);
inssertiondebutdliste(maliste9,0000);
inssertiondebutdliste(maliste9,0000);
inssertiondebutdliste(maliste9,0000);
inssertiondebutdliste(maliste9,0000);
Liste *maliste10=initialisation();
inssertiondebutdliste(maliste10,0000);
inssertiondebutdliste(maliste10,0000);
inssertiondebutdliste(maliste10,0000);
inssertiondebutdliste(maliste10,0000);
inssertiondebutdliste(maliste10,0000);
printf("\nN: " );
afficherlistechainer(malistedecolonne);
printf("\na: " );
afficherlistechainer(maliste1);
printf("\nb: " );
afficherlistechainer(maliste2);
printf("\nc: " );
afficherlistechainer(maliste3);
printf("\nd: " );
afficherlistechainer(maliste4);
printf("\ne: " );
afficherlistechainer(maliste5);
printf("\nf: " );
afficherlistechainer(maliste6);
printf("\ng: " );
afficherlistechainer(maliste7);
printf("\nh: " );
afficherlistechainer(maliste8);
printf("\ni: " );
afficherlistechainer(maliste9);
printf("\nj: " );
afficherlistechainer(maliste10);
return 0;
}
int main()
{
initialisationgrille();
char caseselectionner[3];
printf("\n\nchoisissez une case :" );
scanf("%s",caseselectionner);
if(caseselectionner=="a1" ){printf("cava" );}
}
Marsh Posté le 03-08-2015 à 17:50:02
> j'en suis là dans mon code, j’essaie de réaliser le menu
C'est peut être prématuré, la tu es bien loin de gérer une structure grille, pour le moment, le bout de code que tu as donné ne sait que créer une liste simplement chaînée et lui ajouter/supprimer un élément en tête.
A+,
Marsh Posté le 03-08-2015 à 18:53:14
Oui plutôt que de faire ce que comme prévue j'ai pris une facilité en faisant une série de liste chainée l'une en dessous de l'autre , je vais le présenter comme ça a mon professeur, si ça passe tant mieux et si ça passe pas j'aurai droit à une prolongation de session et là j'aurai bien le temps de le faire comme il faut.
Mais là je suis bloqué je n'arrive pas à faire une faire une condition avec une chaine de caractère.µ
Qu'est-ce qui ne va pas dans ce petit code??
Code :
|
Marsh Posté le 03-08-2015 à 19:00:45
ah oui je pense que je dois utilisé la fonction strcmp, je vais essayer comme ça
Marsh Posté le 04-08-2015 à 13:07:59
Bon voila j'ai terminer mon code, c'est un simple liste chainée mais bon au moins ça marche.
Code :
|
Marsh Posté le 27-07-2015 à 19:28:50
Bonjour,
Je dois réaliser une grille excel pour mon cours d'informatique.
J'ai appris les base en début d'année (printf, scanf, boucle,...) et la j'ai appris récemment sur internet les base un peu plus complexe que je ne maitrise pas encore tout à fait ( liste chainée, chaine de caractères, pointeurs, allocation dynamique, prototype, ...).
Je me dit qu'il fraudais réaliser une liste chainée ou chaque élément (chaque case) possèdent un pointeur de l’élément précédant et 3 autre pointeurs vers d'autres élément afin de pouvoir aller d'une case vers le haut, vers la gauche, vers la droite.
Un printf qui affiche toutes les cases mais disposés au bons emplacement et un menu pour encoder, effacer ou modifier des valeurs.
Qu'en pensez est-ce la manière la plus simple de procédé.