petite questions de la part d'un "débutant"
2 participants
Page 1 sur 1
petite questions de la part d'un "débutant"
Bonjour, j'aimerais vous poser une question.
J'ai une première fonction qui permet de créer un fichier .dat elle s'appelle fdat
j'ai une autre fonction qui taite ce fichier .dat elle s'appelle ftrait
les deux fonctions sont de type void pour le moment et je mets donc moi même le nom du fichier dans la fonction ftrait.
Ce que j'aimerais, c'est dans ma fonction fdat retourne ce nom de fichier que je passerai en paramètre à ma deuxième fonction ftrait.
Ceci me permettra d'automatiser tout ça.
Comment puis-je faire ? Ce qui me gene c'est de retourner le nom du fichier je n'y arrive pas.
Par avance, merci
edit : je vais préciser, la chaine que je passe en paramètre dans ma fonction fdat je doit la concaténer à une chaine contenant l'extension.
en gros si je passe la chaine test en parametre dans ma fonction fdat je doit concaténer cette chaine "test" avec une chaine ".dat"
et c'est cette chaine concaténée que je vais renvoyer (test.dat donc)
J'ai une première fonction qui permet de créer un fichier .dat elle s'appelle fdat
j'ai une autre fonction qui taite ce fichier .dat elle s'appelle ftrait
les deux fonctions sont de type void pour le moment et je mets donc moi même le nom du fichier dans la fonction ftrait.
Ce que j'aimerais, c'est dans ma fonction fdat retourne ce nom de fichier que je passerai en paramètre à ma deuxième fonction ftrait.
Ceci me permettra d'automatiser tout ça.
Comment puis-je faire ? Ce qui me gene c'est de retourner le nom du fichier je n'y arrive pas.
Par avance, merci
edit : je vais préciser, la chaine que je passe en paramètre dans ma fonction fdat je doit la concaténer à une chaine contenant l'extension.
en gros si je passe la chaine test en parametre dans ma fonction fdat je doit concaténer cette chaine "test" avec une chaine ".dat"
et c'est cette chaine concaténée que je vais renvoyer (test.dat donc)
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Si j'ai bien compris la situation, tu veux ceci :flo a écrit:
J'ai une première fonction qui permet de créer un fichier .dat elle s'appelle fdat
j'ai une autre fonction qui traite ce fichier .dat elle s'appelle ftrait
les deux fonctions sont de type void pour le moment et je mets donc moi même le nom du fichier dans la fonction ftrait.
Ce que j'aimerais, c'est dans ma fonction fdat retourne ce nom de fichier que je passerai en paramètre à ma deuxième fonction ftrait.
Ceci me permettra d'automatiser tout ça.
Comment puis-je faire ? Ce qui me gêne c'est de retourner le nom du fichier je n'y arrive pas.
Par avance, merci
edit : je vais préciser, la chaine que je passe en paramètre dans ma fonction fdat je doit la concaténer à une chaine contenant l'extension.
en gros si je passe la chaine test en parametre dans ma fonction fdat je doit concaténer cette chaine "test" avec une chaine ".dat"
et c'est cette chaine concaténée que je vais renvoyer (test.dat donc)
- Code:
/* ajuster la taille selon les besoins réels ou utiliser l'allocation dynamique */
char const fname[128] = "test";
strcat (fname, ".dat");
fdat (fname);
ftrait (fname);
Re: petite questions de la part d'un "débutant"
Bonjour,
En fait le strcat se fait dans la fonction fdat.
Voici le prototype de ma fonction fdat (il est peut être faux) :
je l'utilise comme ceci
J'espère que c'est plus clair, mon premier message ne l'était pas je m'en rends compte après relecture.
Si vous avez besoin de plus de précisions ou éclaircissements je les donnerai.
Mais en gros j'ai une chaine de caractere que je passe en paramètre à fdat qui va la concaténer avec une autre chaine représentant l'extension et retourner cette chaine concaténée qui sera elle meme passée en paramètre à ftrait.
En fait le strcat se fait dans la fonction fdat.
Voici le prototype de ma fonction fdat (il est peut être faux) :
- Code:
char *fdat(char *fname);
je l'utilise comme ceci
- Code:
int main()
{
char nom_fichier[20]= "test";
fdat(nom_fichier);
//ensuite j'aimerais que ma fonction ftrait prenne en paramètre la chaîne de caractères
//retournée par la fonction fdat
}
//Ma fonction fdat que j'ai dû mal à implémenter
char *fdat(char *fname)
{
char extension[5]=".dat";
//La concaténation que je n'arrive pas à faire
fopen(nom_du_fichier_apres_concatenation, "w")
/* traitements du fichier */
return nom_du_fichier_apres_concatenation // soit test.dat dans notre cas
}
J'espère que c'est plus clair, mon premier message ne l'était pas je m'en rends compte après relecture.
Si vous avez besoin de plus de précisions ou éclaircissements je les donnerai.
Mais en gros j'ai une chaine de caractere que je passe en paramètre à fdat qui va la concaténer avec une autre chaine représentant l'extension et retourner cette chaine concaténée qui sera elle meme passée en paramètre à ftrait.
Dernière édition par flo le Jeu 5 Juin 2008 - 13:12, édité 1 fois
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
C'est pas une bonne idée...flo a écrit:Bonjour,
En fait le strcat se fait dans la fonction fdat.
Eh oui, tout le problème est là. Tu n'as pas le droit de retourner l'adresse d'un variable locale, car elle n'existe plus après exécution de la fonction. J'ai donné une solution. Elle ne va pas ?
Voici le prototype de ma fonction fdat (il est peut être faux) :
- Code:
char *fdat(char *fname);
je l'utilise comme ceci
- Code:
int main()
{
char nom_fichier[20]= "test";
fdat(nom_fichier);
}
//Ma fonction fdat que j'ai dû mal à implémenter
char *fdat(char *fname)
{
char extension[5]=".dat";
//La concaténation que je n'arrive pas à faire et le return
return ?
}
Re: petite questions de la part d'un "débutant"
Je teste et je vous dis.
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Oui ca marche très bien vous avez raison.
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Il est un principe de bonne conception qui veut que l'on sépare les traitements.flo a écrit:Oui ca marche très bien vous avez raison.
Unix rules : "Do one thing, but do it well"
Re: petite questions de la part d'un "débutant"
Bonjour, j'ai à nouveau une question à vous poser. Il s'agit de compatibilé Windows et Linux pour un programme.
J'utilise le logiciel gnuplot pour générer des graphiques au format png.
Ce logiciel est multi-plateforme.
Pour le moment j'ai pris la version Windows donc avec l'exécutable.
Voilà la façon dont j'appelle mon programme gnuplot.
Cependant sous Linux cela ne marchera pas. Pour appeler gnuplot sous linux il faut faire dans le shell gnuplot monfichier.gnu.
Est-ce que un system("gnuplot monfichier.gnu"); marche sous Linux ? je suis sous une distribution Xp et je n'ai pas accès à une distribution Linux je n'ai pas de logiciel de virtualisation disponible....
Si oui comment faire pour tester l'OS dans lequel on est ?
Il suffirait donc de faire un simple test d'OS puis d'appeler gnuplot de deux façons différentes après avoir passé tous les chemins absolus en relatifs bien sûr.
Merci pour vos réponses.
PS: une petite question annexe.
Je dois me connecter à une base de données Oracle.
l'entreprise dans laquelle je me trouve utilise le PRO*C.
j'ai vu qu'il existait une librairie OCILIB qui permettait de se connecter également à une base Oracle.
Les deux façons se valent-elles ou l'une est-elle meilleur que l'autre ?
J'utilise le logiciel gnuplot pour générer des graphiques au format png.
Ce logiciel est multi-plateforme.
Pour le moment j'ai pris la version Windows donc avec l'exécutable.
Voilà la façon dont j'appelle mon programme gnuplot.
- Code:
char commande[150];
const char *nomfichier = "histo.gnu";
const char *cheminexe = "C:\\gnuplot\\bin\\wgnuplot.exe"; //A passer en chemin relatif par la suite
int i=0;
fichier = fopen(nomfichier, "w");
if (fichier2 != NULL)
{
fprintf(fichier, "le script gnuplot....");
sprintf(commande,"start \ %s %s", cheminexe, nomfichier);
system(commande);
}
//Si ce programme vous parait moyen ou peut être amélioré dites le moi.
Cependant sous Linux cela ne marchera pas. Pour appeler gnuplot sous linux il faut faire dans le shell gnuplot monfichier.gnu.
Est-ce que un system("gnuplot monfichier.gnu"); marche sous Linux ? je suis sous une distribution Xp et je n'ai pas accès à une distribution Linux je n'ai pas de logiciel de virtualisation disponible....
Si oui comment faire pour tester l'OS dans lequel on est ?
Il suffirait donc de faire un simple test d'OS puis d'appeler gnuplot de deux façons différentes après avoir passé tous les chemins absolus en relatifs bien sûr.
Merci pour vos réponses.
PS: une petite question annexe.
Je dois me connecter à une base de données Oracle.
l'entreprise dans laquelle je me trouve utilise le PRO*C.
j'ai vu qu'il existait une librairie OCILIB qui permettait de se connecter également à une base Oracle.
Les deux façons se valent-elles ou l'une est-elle meilleur que l'autre ?
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Le '\' dans la chaine n'a aucun sens, car '\ ' n'est pas une séquence standard. Si tu veux ce caractère, c'est '\\'.flo a écrit:Bonjour, j'ai à nouveau une question à vous poser. Il s'agit de compatibilé Windows et Linux pour un programme.
J'utilise le logiciel gnuplot pour générer des graphiques au format png.
Ce logiciel est multi-plateforme.
Pour le moment j'ai pris la version Windows donc avec l'exécutable.
Voilà la façon dont j'appelle mon programme gnuplot.
- Code:
char commande[150];
const char *nomfichier = "histo.gnu";
const char *cheminexe = "C:\\gnuplot\\bin\\wgnuplot.exe"; //A passer en chemin relatif par la suite
int i=0;
fichier = fopen(nomfichier, "w");
if (fichier2 != NULL)
{
fprintf(fichier, "le script gnuplot....");
sprintf(commande,"start \ %s %s", cheminexe, nomfichier);
system(commande);
}
//Si ce programme vous parait moyen ou peut être amélioré dites le moi.
De plus, je ne comprends pas pourquoi tu ouvres le fichier. Il semble que tu confondes 2 choses. Soit tu manipules le fichier directement dans ton programme C et tu utilises effectivement fopen(), les fonctions d'écriture qui vont bien et fclose(), soit tu confies ce travail à une application externe (ici, gnuplot) et dans ce cas tu te contentes de forger la ligne de commande qui va bien. En principe, Windows reconnait le séparateur de chemins '/'
Le 'start' est inutile. Il suffit de faire :
- Code:
char commande[150];
const char *nomfichier = "histo.gnu";
const char *cheminexe = "C:/gnuplot/bin/wgnuplot.exe";
sprintf(commande,"%s %s", cheminexe, nomfichier);
system(commande);
Oui, il suffit de changer la commande en fonction de l'OS. Comme le code est recompilé, il suffit d'une compilation conditionnelle :
Cela marche bien et me crée mon image png à partir du graphique (option propre à gnuplot).
Cependant sous Linux cela ne marchera pas. Pour appeler gnuplot sous linux il faut faire dans le shell gnuplot monfichier.gnu.
Est-ce que un system("gnuplot monfichier.gnu"); marche sous Linux ? je suis sous une distribution Xp et je n'ai pas accès à une distribution Linux je n'ai pas de logiciel de virtualisation disponible....
Si oui comment faire pour tester l'OS dans lequel on est ?
Il suffirait donc de faire un simple test d'OS puis d'appeler gnuplot de deux façons différentes après avoir passé tous les chemins absolus en relatifs bien sûr.
- Code:
char commande[150];
const char *nomfichier = "histo.gnu";
#if defined (WIN32)
const char *cheminexe = "C:/gnuplot/bin/wgnuplot.exe";
#elif defined (linux)
const char *cheminexe = "gnuplot";
#else
#error undefined for this system
#endif
sprintf(commande,"%s %s", cheminexe, nomfichier);
system(commande);
Désolé, je n'ai aucune expérience probante dans ce domaine. Il y a un forum consacré à la programmation des BD sur Developpez.
Je dois me connecter à une base de données Oracle.
l'entreprise dans laquelle je me trouve utilise le PRO*C.
j'ai vu qu'il existait une librairie OCILIB qui permettait de se connecter également à une base Oracle.
Les deux façons se valent-elles ou l'une est-elle meilleur que l'autre ?
Re: petite questions de la part d'un "débutant"
En fait il manque la fermeture du fichier lorsque j'ai fait le copier/coller de mon code.-ed a écrit:
De plus, je ne comprends pas pourquoi tu ouvres le fichier. Il semble que tu confondes 2 choses. Soit tu manipules le fichier directement dans ton programme C et tu utilises effectivement fopen(), les fonctions d'écriture qui vont bien et fclose(), soit tu confies ce travail à une application externe (ici, gnuplot) et dans ce cas tu te contentes de forger la ligne de commande qui va bien. En principe, Windows reconnait le séparateur de chemins '/'
J'ouvre le fichier car il va contenir mon script gnuplot.
Je crée un fichier .gnu qui contiendra mon script puis j'appelle gnuplot.
Voila le code en entier.
- Code:
fichier = fopen(nomfichier, "w");
if (fichier != NULL)
{
fprintf(fichier, "set terminal png transparent\n");
fprintf(fichier, "set title \"Courbe evolutive ville de %s\" font \"Arial,16\" tc rgbcolor \"dark-blue\"\n", nom_ville);
fprintf(fichier, "set output \"courbe.png\"\n"
"set xlabel \"Evolution en Heures\" tc lt 4\n"
"set ylabel \"Concentration en ug/m3\" tc lt 4\n"
"set xtics nomirror rotate by -45 font \"Arial,9\"\n"
"set ytics nomirror\n"
"set key inside horizontal c t box lw 1.2\n"
"set style data histogram\nset xtics (");
fprintf(fichier, "plot \"test.dat\" u 1:2 w filledcurv x1 lt 2, '' u 1:2:4 w filledcur above lt 1\n");
fclose(fichier);//je ferme mon fichier, il contient maintenant mon script gnu
fichier = NULL;
sprintf(commande,"start \ %s %s", cheminexe, nomfichier);//je lance gnuplot pour qu'il crée mon image
system(commande);
}
Merci pour votre réponse je vais tester ça sous le serveur Linux si j'arrive à avoir l'accès.
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
OK, je te laisse faire les essais. Attention à poster du code complet, c'est plus clair...
Re: petite questions de la part d'un "débutant"
Ca marche encore une fois. merci beaucoup.
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Bonjour, c'est encore moi.
j'ai un petit problème avec une allocation mémoire et l'utilisation du realloc.
J'utilise tout ceci dans du Pro*C mais le problème est un problème C.
Je vais poster le code et essayer d'expliquer ce que je souhaite faire
En fait je crée un tableau statique de float dans la déclaration oracle de 10 colonnes.
Le résultat de ma requete me renvoie 66 enregistrement.
Donc que se passe-t-il ?
Mon curseur une fois ouvert va exécuter la requete et enregistrer les 10 premières données dans le tableau lati[]
Puis comme il y a encore des données (sqlca.sqlcode != 1403) le fetch va prendre les 10 enregistrements suivants et les mettre à nouveau dans le tableau lati[] en écrasant les données. Pour éviter de les perdre il faut donc les copier dans un tableau dynamique à chaque fois, c'est mon tableau float *latitude.
Je souhaite donc augmenter la taille de mon tableau à chaque tour de fetch.
Si mon tableau initial est de 10 et que j'ai 66 enregistrements alors il y aura 7 tours de fetch.
et la réallocation plante et j'ai une erreur de segmentation....
Si je prends un tableau initial de 100 (lati[100]) il n'y aura qu'un tour de fetch car 100>66 enregistrements et là ca ne plante pas et ca copie bien.
Cependant dans mon cas j'ai 66 enregistrements mais peut être que lorsque le programme sera lancé il y en aura plus.
Le problème vient donc du realloc à chaque tour de fetch je pensais pourtant qu'il ferait un bloc de 10 puis 20 etc...
Si vous avez besoinde plus d'explications n'hésitez pas.
merci
j'ai un petit problème avec une allocation mémoire et l'utilisation du realloc.
J'utilise tout ceci dans du Pro*C mais le problème est un problème C.
Je vais poster le code et essayer d'expliquer ce que je souhaite faire
- Code:
/***
déclaration d'un entête Oracle avant le main
***/
#define NB_MAX_MES 10
EXEC SQL BEGIN DECLARE SECTION;
float lati[NB_MAX_MES];
//je ne mets pas la requete qui est lourde et plutot inutile
EXEC SQL END DECLARE SECTION;
//dans le main
int main()
{
size_t taille= 1;
float *latitude = malloc (taille * sizeof * latitude);//j'alloue un bloc de taille 1 est-ce bon ?
float *longitude;
float *derniere_valeur;
char **nom_mesure;
char **libelle;
char **nom_court;
numret=0;
EXEC SQL WHENEVER NOT FOUND GOTO pas_trouve;
EXEC SQL WHENEVER SQLERROR GOTO error_export_ge;
EXEC SQL OPEN tout_station;//ouverture d'un curseur contenant la requête
while(1)//Boucle infinie
{
EXEC SQL FETCH tout_station //On effectue le fetch
INTO :lati; //qu'on insère dans notre tableau
//gestion des erreurs
pas_trouve :
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 1403) finBoucle = TRUE; //S'il le fetch ne renvoie rien on sort de la boucle. code : 1403
printf("%d\n", sqlca.sqlerrd[2]);//sqlca.sqlerrd[2] aura pour valeur 10 puis 20 puis 30 puis 40 puis 50 puis 60 puis 66
realloc(latitude, sqlca.sqlerrd[2]* sizeof * latitude);
//realloc(latitude, sqlca.sqlerrd[2]); donne la meme chose
for ( i = 0 ; i < sqlca.sqlerrd[2]-numret; i++)
{
latitude[i+numret]=lati[i];
printf(" %f \n", latitude[i+numret]);
}
numret = sqlca.sqlerrd[2];
if (finBoucle == TRUE) break;
}
error_export_ge:
En fait je crée un tableau statique de float dans la déclaration oracle de 10 colonnes.
Le résultat de ma requete me renvoie 66 enregistrement.
Donc que se passe-t-il ?
Mon curseur une fois ouvert va exécuter la requete et enregistrer les 10 premières données dans le tableau lati[]
Puis comme il y a encore des données (sqlca.sqlcode != 1403) le fetch va prendre les 10 enregistrements suivants et les mettre à nouveau dans le tableau lati[] en écrasant les données. Pour éviter de les perdre il faut donc les copier dans un tableau dynamique à chaque fois, c'est mon tableau float *latitude.
Je souhaite donc augmenter la taille de mon tableau à chaque tour de fetch.
Si mon tableau initial est de 10 et que j'ai 66 enregistrements alors il y aura 7 tours de fetch.
et la réallocation plante et j'ai une erreur de segmentation....
Si je prends un tableau initial de 100 (lati[100]) il n'y aura qu'un tour de fetch car 100>66 enregistrements et là ca ne plante pas et ca copie bien.
Cependant dans mon cas j'ai 66 enregistrements mais peut être que lorsque le programme sera lancé il y en aura plus.
Le problème vient donc du realloc à chaque tour de fetch je pensais pourtant qu'il ferait un bloc de 10 puis 20 etc...
Si vous avez besoinde plus d'explications n'hésitez pas.
merci
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Je vais essayer d'analyser le problème de façon générale et non en fonction de Pro*C que je ne connais pas.flo a écrit:j'ai un petit problème avec une allocation mémoire et l'utilisation du realloc.
Je vais poster le code et essayer d'expliquer ce que je souhaite faire
<...>
En fait je crée un tableau statique de float dans la déclaration oracle de 10 colonnes.
Le résultat de ma requete me renvoie 66 enregistrement.
Donc que se passe-t-il ?
En fait, il s'agit de lire une fichier contenant des valeurs et de créer un tableau dynamique en fonciton du nombre de valeurs lues.
Comme tu l'as noté, les 2 données importantes sont :
- l'adresse du tableau alloué
- le nombre d'éléments du tableau
Je conseille donc de mettre ces données dans une structure unique :
- Code:
struct tab
{
size_t nb;
float *tab;
};
- Code:
struct tab
{
size_t nb;
size_t i_ecr;
float *tab;
};
- Code:
struct tab latitude;
latitude.i_ecr = 0;
latitude.nb= 1;
latitude.i_ecr = malloc(sizeof *latitude.tab * latitude.nb);
if (latitude.i_ecr != NULL)
{
etc.
- Code:
latitude.tab[latitude.i_ecr] = get_float();
latitude.i_ecr++;
if (latitude.i_ecr == latitude.nb)
{
void *p = realloc (latitude.tab , sizeof *latitude.tab * latitude.nb * 2);
if (latitude.i_ecr != NULL)
{
latitude.tab = p;
latitude.nb *= 2;
etc.
http://mapage.noos.fr/emdel/clib.htm
Module FARR
Re: petite questions de la part d'un "débutant"
j'ai réussi à l'appliquer à mon programme, c'était pas de la tarte surtout avec les tableaux de caractères à deux dimensions.
mais votre exemple "généraliste" m'a bien aidé merci.
mais votre exemple "généraliste" m'a bien aidé merci.
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Re: petite questions de la part d'un "débutant"
Oui, mais je pense que c'est comme ça qu'on progresse...flo a écrit:j'ai réussi à l'appliquer à mon programme, c'était pas de la tarte surtout avec les tableaux de caractères à deux dimensions.
Re: petite questions de la part d'un "débutant"
Oui c'est sûr, si on ne réfléchit jamais on n'avance pas.
flo- Bavard
- Messages : 11
Date d'inscription : 04/06/2008
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
|
|