Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

portage de sun à linux

20 réponses
Avatar
Elodie
Bonjour,

Au boulot, je dois porter tout un tas de programme en C de sun à Linux. Bien
sûr ce n'est pas moi qui ait écrit ces programmes et je ne connais pas le c.

Pour le moment, dans la majorité des programmes j'ai fait les modifs
suivantes :

- virer le module fp.h et compiler avec gcc -lm
- remplacer void main(int argc, char* argv[]) par
main(argc,argv)
int argc;
char *argv[];
(ne me demandez pas pkoi)

A la compilation pas de problème mais à l'exécution j'ai une erreur de
segmentation. Une idée ?

Merci d'avance pour votre aide.

Elodie

PS : un des codes :


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*#include <fp.h>*/
#include "../include/herve.h"

#define FICHIER 0
#define UV 1

FILE *fp1,*fp2;

void lecture_ligne(int);

main(argc,argv)
int argc;
char *argv[];
{
char entree[80],sortie[80];
float u,v,ff;
int rep,dd,nb,type;

if (argc==3)
{
if (strlen(argv[1])<=5)
{
type=UV;
u=atof(argv[1]);
v=atof(argv[2]);
}
else
{
type=FICHIER;
strcpy(entree,argv[1]);
nb=atoi(argv[2]);
}
}
else
{
printf("Conversion des coordonnees (u,v) d'un vent en (dd,ff)\n");
printf("-----------------------------------------------------\n");
printf("1 => Saisie d'un couple (u,v)\n");
printf("2 => Traitement sur un fichier de donnees ?\n");
scanf("%d",&rep);
if (rep!=1 && rep!=2) exit(-1);

if (rep==1)
{
type=UV;
printf("Coordonnee u ? ");
scanf("%f",&u);
printf("Coordonnee v ? ");
scanf("%f",&v);
}
else
{
type=FICHIER;
printf("Nom du fichier a traiter ? ");
scanf("%s",&entree);
printf("Nombre de couples (u,v) par enregistrement ? ");
scanf("%d",&nb);
}
}

if (type==UV)
{
vent_uv_ddff(u,v,&dd,&ff);
printf("dd=%d ff=%.1f\n",dd,ff);
}
else
{
fp1=fopen(entree,"r");
if (fp1==NULL)
{
printf("%s n'existe pas!\n",entree);
exit(0);
}
sprintf(sortie,"%s.res",entree);
fp2=fopen(sortie,"w");
while (!(feof(fp1))) lecture_ligne(nb);
fclose(fp1);
fclose(fp2);
}
}


void lecture_ligne(int nb)
{
char chaine[160];
float u,v,ff;
int n,dd;

fgets(chaine,160,fp1);
if (!(feof(fp1)))
{
fprintf(fp2,"%s;",strtok(chaine,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));

for (n=1;n<=nb;n++)
{
u=atof(strtok(NULL,";"));
v=atof(strtok(NULL,";"));

vent_uv_ddff(u,v,&dd,&ff);
fprintf(fp2,"%d;%.2f;",dd,ff);
}
fprintf(fp2,"\n");
}
}

10 réponses

1 2
Avatar
Anthony Fleury
Elodie wrote:

Bonjour,



Bonjour,

Pour le moment, dans la majorité des programmes j'ai fait les modifs
suivantes :
- virer le module fp.h et compiler avec gcc -lm


fp.h je ne sais pas mais le -lm ajoute le support de la librairie
mathématique, util quand on inclut <math.h>

- remplacer void main(int argc, char* argv[]) par
main(argc,argv)
int argc;
char *argv[];
(ne me demandez pas pkoi)


Quand on fait des modifications il est bien de savoir pourquoi en fait :-).
Surtout que la deuxième est fortement déconseillée. En fait, cette notation
de C ancien pré ANSI n'est plus utilisée, il faut lui préférer :
int main(int argc, char* argv[])

D'une part il n'est pas conseillé de s'amuser avec le type int implicite
comme type de retour, et de deuxième part la notation qui consiste à mettre
les types des variables en dehors des () est à ma connaissance dépreciée
même si elle est encore supportée.


A la compilation pas de problème mais à l'exécution j'ai une erreur de
segmentation. Une idée ?


Un segmentation fault (ou erreur de segmentation) est une utilisation d'un
espace mémoire sur lequel on a pas vraiment l'autorisation de faire ce
qu'on veut y faire... Voyons le code.

[...]

void lecture_ligne(int nb)
{
char chaine[160];
float u,v,ff;
int n,dd;

fgets(chaine,160,fp1);
if (!(feof(fp1)))


Attention à feof [ même si dans ce cas il est précédé d'une lecture il aura
donc le comportement attendu ], mieux vaut mieux tester le retour de fgets,
si fgets retourne NULL alors la fin de fichier est atteinte ou un autre
problème est survenu, et si une recherche de n dans la chaine ne donne
rien, alors la lecture s'est stoppée "anormalement" (car tout fichier
normal sous linux se termine par une ligne vide en général)

{
fprintf(fp2,"%s;",strtok(chaine,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));

for (n=1;n<=nb;n++)
{
u=atof(strtok(NULL,";"));
v=atof(strtok(NULL,";"));


C'est la seule source de problème que j'ai vu dans le bout de code donné.
si la chaine est mal formattée, strtok va renvoyer NULL à un moment, et le
fprintf va donc poser un problème. Hormis ca je ne vois pas. En clair il
est à mon avis préférable de tester le retour de strtok avant de le donner
à fprintf et à atof (qui est aussi déprécié si mes souvenirs sont bons,
mieux vaut utiliser strtod() qui en plus détecte les erreurs qui pourraient
survenir)


vent_uv_ddff(u,v,&dd,&ff);


Nous n'avons pas vent_uv_ddff()

En clair, je ne vois pas de problème ici (quelque chose de bien gros m'a
peut etre échappé), et un test avec un fichier bien formatté donne une
execution des plus normales sous linux chez moi.

Il faudrait plus de précision et plus cibler le problème, ca peut aider...
(notamment ou est le segfault ? l'utilisation d'un debugger le dira et
aussi dans quelles conditions intervient-il ? )

Anthony
--
"You could be my unintended, choice to live my life extended
You should be the one I'll always love, I'll be there as soon as I can
But I'm busy mending broken pieces of the life I had before"
(C) Muse - Unintended

Avatar
Régis Troadec
"Elodie" a écrit dans le message de
news:c8d5po$tvt$
Bonjour,


Salut,


Au boulot, je dois porter tout un tas de programme en C de sun à Linux.
Bien

sûr ce n'est pas moi qui ait écrit ces programmes et je ne connais pas le
c.


Pour le moment, dans la majorité des programmes j'ai fait les modifs
suivantes :

- virer le module fp.h et compiler avec gcc -lm
- remplacer void main(int argc, char* argv[]) par
main(argc,argv)
int argc;
char *argv[];
(ne me demandez pas pkoi)
_________________________________________________


Disons que c'est la forme traditionnelle K&R, mais qui n'est plus très
utilisée depuis pas mal de temps déjà.
Remplacer void main() par main(), c'est déjà mieux mais le retour int reste
implicite.
Tu peux faire int main(int argc, char*argv) { /*code*/ }, c'est la forme
conseillée par le standard (depuis C90).
_________________________________________________


A la compilation pas de problème mais à l'exécution j'ai une erreur de
segmentation. Une idée ?

Merci d'avance pour votre aide.

Elodie

PS : un des codes :


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*#include <fp.h>*/
#include "../include/herve.h"

#define FICHIER 0
#define UV 1

FILE *fp1,*fp2;


_________________________________________________

Ce n'est pas joli les variables globales, mieux vaut que définisse
clairement où seront utilisés fp1 et fp2 et que tu passes des pointeurs aux
fontions qui s'en serviront.
_________________________________________________


void lecture_ligne(int);

main(argc,argv)
int argc;
char *argv[];
_________________________________________________


int main(int argc, char * argv[])
_________________________________________________

{
char entree[80],sortie[80];
float u,v,ff;
int rep,dd,nb,type;

if (argc==3)
{
if (strlen(argv[1])<=5)
{
type=UV;
u=atof(argv[1]);
v=atof(argv[2]);


_________________________________________________

Regarder aussi la fonction strtod() pour ce genre de conversion (contrôle
d'erreur plus rigoureux), c'est dans stdlib.h
_________________________________________________

}
else
{
type=FICHIER;
strcpy(entree,argv[1]);
_________________________________________________


Attention si strlen(argv[1]) >= 80

memset(entree, 0, sizeof entree);
strncpy(entree, argv[1], 80-1);
_________________________________________________

nb=atoi(argv[2]);
_________________________________________________


Regarder aussi la fonction strtol() pour ce genre de conversion (contrôle
d'erreur plus rigoureux), c'est dans stdlib.h
_________________________________________________

}
}
else
{
printf("Conversion des coordonnees (u,v) d'un vent en (dd,ff)n");
printf("-----------------------------------------------------n");
printf("1 => Saisie d'un couple (u,v)n");
printf("2 => Traitement sur un fichier de donnees ?n");
scanf("%d",&rep);
if (rep!=1 && rep!=2) exit(-1);
_________________________________________________


Attention, les valeurs retournées à l'environnement d'execution *valides
(définies par la norme)* sont 0, EXIT_SUCCESS et EXIT_FAILURE.
_________________________________________________


if (rep==1)
{
type=UV;
printf("Coordonnee u ? ");
scanf("%f",&u);
printf("Coordonnee v ? ");
scanf("%f",&v);
}
else
{
type=FICHIER;
printf("Nom du fichier a traiter ? ");
scanf("%s",&entree);
printf("Nombre de couples (u,v) par enregistrement ? ");
scanf("%d",&nb);
}
}

if (type==UV)
{
vent_uv_ddff(u,v,&dd,&ff);
printf("dd=%d ff=%.1fn",dd,ff);
}
else
{
fp1=fopen(entree,"r");
if (fp1==NULL)
{
printf("%s n'existe pas!n",entree);
exit(0);
_________________________________________________


Renvoyer 0 est par convention synonyme de réussite du programme, choisir une
autre valeur ou exit(EXIT_FAILURE);
_________________________________________________

}
sprintf(sortie,"%s.res",entree);
_________________________________________________


Et boum ! sortie a de quoi contenir 80 char, mais ce n'est à priori pas une
chaine, si il n'y a pas de '' (caractère de fin de chaine)quelquepart
dedans.
La solution, remplir sortie de zéros (ce qu'est '') avec memset par
exemple:
memset(sortie, 0, sizeof sortie);
sprintf(sortie,"%s.res", entree);
_________________________________________________

fp2=fopen(sortie,"w");
_________________________________________________


Manque test f2 mais il ne m'a pas l'air utilisé dans main()

Tu peux procéder comme avant,
if (f2 ==NULL)
{
fprintf(stderr,"Impossible d'ouvrir le fichier %sn", sortie);
exit(EXIT_FAILURE);
}
_________________________________________________

while (!(feof(fp1))) lecture_ligne(nb);
_________________________________________________


AMA, problème de conception, ce n'est pas judicieux de tester la fin d'un
fichier en condition de while pour réaliser une lecture ligne par ligne dans
une fonction. La lecture du fichier doit se faire en un seul tenant.
Le mieux serait ici de passer f1 et f2 à une fonction qui lise f1 pour
écrire dans f2.
Du genre :

void TraitementVentFicVersFic(FILE * f_src, FILE * f_dst);

TraitementVentFicVersFic(f1, f2); /* enlever */
_________________________________________________

fclose(fp1);
fclose(fp2);
}
}


void lecture_ligne(int nb)


void TraitementVentFicVersFic(FILE * f_src, FILE * f_dst)

{
char chaine[160];
float u,v,ff;
int n,dd;

fgets(chaine,160,fp1);
_________________________________________________


Tu peux ici utiliser directement le retour de fgets en lieu et place de
feof() et realiser le traitement ligne par ligne avec le while ici :
(dans le même temps, tu peux mettre f1 et f2 dans le main au lieu de les
laisser en globales)

while (fgets(chaine,160,fp1) != NULL)
{
/* saute les lignes vides*/
if (chaine[0] == n) continue;

/* virer le bloc if feof() */
_________________________________________________

if (!(feof(fp1)))
{
fprintf(fp2,"%s;",strtok(chaine,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));

for (n=1;n<=nb;n++)
{
u=atof(strtok(NULL,";"));
v=atof(strtok(NULL,";"));
_________________________________________________


Voir aussi strtod()
_________________________________________________


vent_uv_ddff(u,v,&dd,&ff);
fprintf(fp2,"%d;%.2f;",dd,ff);
}
fprintf(fp2,"n");
}
}



Voilà tout. Le code était bien indenté, ca m'a donné envie de le regarder et
d'y apporter mes suggestions. Dans tous les cas, et surtout pour un portage,
se conformer au standard du langage C facilitera la tâche et plus tard la
maintenence du code.

Regis

Avatar
Olivier
Elodie wrote:

Bonjour,

Au boulot, je dois porter tout un tas de programme en C de sun à Linux. Bien
sûr ce n'est pas moi qui ait écrit ces programmes et je ne connais pas le c.

Pour le moment, dans la majorité des programmes j'ai fait les modifs
suivantes :

- virer le module fp.h et compiler avec gcc -lm
- remplacer void main(int argc, char* argv[]) par
main(argc,argv)
int argc;
char *argv[];
(ne me demandez pas pkoi)

A la compilation pas de problème mais à l'exécution j'ai une erreur de
segmentation. Une idée ?

Merci d'avance pour votre aide.


Marrant, on dirait un stagiaire...

Elodie


et qui prend l'identité d'une fille pour que les mâles se montrent
galants en plus !!!!!

oliv

Avatar
Régis Troadec
"Régis Troadec" a écrit dans le message de
news:c8di6e$ogs$

Errata...

"Elodie" a écrit dans le message de
news:c8d5po$tvt$


[coupé]


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*#include <fp.h>*/
#include "../include/herve.h"

#define FICHIER 0
#define UV 1

FILE *fp1,*fp2;


_________________________________________________

Ce n'est pas joli les variables globales, mieux vaut que définisse


Fallait lire "que tu définisses"

clairement où seront utilisés fp1 et fp2 et que tu passes des pointeurs
aux

fontions qui s'en serviront.


fonctions


while (!(feof(fp1))) lecture_ligne(nb);
_________________________________________________


AMA, problème de conception, ce n'est pas judicieux de tester la fin d'un
fichier en condition de while pour réaliser une lecture ligne par ligne
dans

une fonction. La lecture du fichier doit se faire en un seul tenant.
Le mieux serait ici de passer f1 et f2 à une fonction qui lise f1 pour
écrire dans f2.
Du genre :

void TraitementVentFicVersFic(FILE * f_src, FILE * f_dst);

TraitementVentFicVersFic(f1, f2); /* enlever */


Je n'avais pas terminé le commentaire:
/* enlever l'affreuse boucle while (!(feof(fp1))) lecture_ligne(nb); */
TraitementVentFicVersFic(f1, f2);


void TraitementVentFicVersFic(FILE * f_src, FILE * f_dst)

{
char chaine[160];
float u,v,ff;
int n,dd;

fgets(chaine,160,fp1);
_________________________________________________


Tu peux ici utiliser directement le retour de fgets en lieu et place de
feof() et realiser le traitement ligne par ligne avec le while ici :
(dans le même temps, tu peux mettre f1 et f2 dans le main au lieu de les
laisser en globales)

while (fgets(chaine,160,fp1) != NULL)
{
/* saute les lignes vides*/
if (chaine[0] == n) continue;


Du coup ce n'est plus f1 et f2 mais f_src et f_dst qu'il faudrait bien sûr
utiliser dans TraitementVentFicVersFic().

while (fgets(chaine,160,f_src) != NULL)
{
if (chaine[0] == n) continue;

/* et remplacer f2 par f_dst dans le reste de code */

[coupé]


Avatar
Elodie
Eh non même pas stagiaire mais récemment arrivée j'avoue ! Et en plus je
suis une vraie fille (incroyable non ?), et vraiment susceptible aussi !!

En tous cas, merci beaucoup à Anthony et Régis. Je n'ai pas encore eu le
temps de tout regarder mais voici ce que donne le debugger :

Program received signal SIGSEGV, Segmentation fault.
0x42031d51 in __strtod_internal () from /lib/tls/libc.so.6

Et le plantage intervient juste après la saisie du nombre de couple (u,v)

Elodie

"Olivier" a écrit dans le message de
news:40aa789b$0$10189$
Elodie wrote:

Bonjour,

Au boulot, je dois porter tout un tas de programme en C de sun à Linux.
Bien


sûr ce n'est pas moi qui ait écrit ces programmes et je ne connais pas
le c.



Pour le moment, dans la majorité des programmes j'ai fait les modifs
suivantes :

- virer le module fp.h et compiler avec gcc -lm
- remplacer void main(int argc, char* argv[]) par
main(argc,argv)
int argc;
char *argv[];
(ne me demandez pas pkoi)

A la compilation pas de problème mais à l'exécution j'ai une erreur de
segmentation. Une idée ?

Merci d'avance pour votre aide.


Marrant, on dirait un stagiaire...

Elodie


et qui prend l'identité d'une fille pour que les mâles se montrent
galants en plus !!!!!

oliv



Avatar
Vincent Guichard
sprintf(sortie,"%s.res",entree);
Et boum ! sortie a de quoi contenir 80 char, mais ce n'est à priori pas une

chaine, si il n'y a pas de '' (caractère de fin de chaine)quelquepart
dedans.
La solution, remplir sortie de zéros (ce qu'est '') avec memset par
exemple:
memset(sortie, 0, sizeof sortie);
sprintf(sortie,"%s.res", entree);


d'après la norme (§ 7.19.6.6)

<Quote>
The sprintf function is equivalent to fprintf, except that the output is
written into an array (specified by the argument s) rather than to a
stream. _A null character_ is written at the end of the characters
written; it is not counted as part of the returned value. If copying
takes place between objects that overlap, the behavior is undefined.
</Quote>

Donc ca risque de faire boom, mais pas parce que le '' manque.
L'appel à memset ne sert à rien (sauf à perdre du temps).

Vincent Guichard


Avatar
Denis Fournier
On se souviendra toujours du Tue, 18 May 2004 16:15:21 +0200 quand
"Elodie" (Elodie) prit sa plume electronique pour
nous ecrire :



main(argc,argv)
int argc;
char *argv[];
{
char entree[80],sortie[80];
float u,v,ff;
int rep,dd,nb,type;

<....>

else
{
type=FICHIER;
printf("Nom du fichier a traiter ? ");
scanf("%s",&entree);


j'ai regardé vite fait, mais ici tu as un problème.

entree est un pointeur.

scanf("%s",entree) devrait le faire.


Denis





--
-- Betisier des News : http://www.teaser.fr/~dfournier/betisier.html

Avatar
Elodie
Encore merci pour votre aide.

Je n'ai pas trop eu le temps bosser la dessus aujourd'hui et je pars en
vacances mais je reviendrais surement à la charge à mon retour ;)

Elodie

"Elodie" a écrit dans le message de
news:c8d5po$tvt$
Bonjour,

Au boulot, je dois porter tout un tas de programme en C de sun à Linux.
Bien

sûr ce n'est pas moi qui ait écrit ces programmes et je ne connais pas le
c.


Pour le moment, dans la majorité des programmes j'ai fait les modifs
suivantes :

- virer le module fp.h et compiler avec gcc -lm
- remplacer void main(int argc, char* argv[]) par
main(argc,argv)
int argc;
char *argv[];
(ne me demandez pas pkoi)

A la compilation pas de problème mais à l'exécution j'ai une erreur de
segmentation. Une idée ?

Merci d'avance pour votre aide.

Elodie

PS : un des codes :


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*#include <fp.h>*/
#include "../include/herve.h"

#define FICHIER 0
#define UV 1

FILE *fp1,*fp2;

void lecture_ligne(int);

main(argc,argv)
int argc;
char *argv[];
{
char entree[80],sortie[80];
float u,v,ff;
int rep,dd,nb,type;

if (argc==3)
{
if (strlen(argv[1])<=5)
{
type=UV;
u=atof(argv[1]);
v=atof(argv[2]);
}
else
{
type=FICHIER;
strcpy(entree,argv[1]);
nb=atoi(argv[2]);
}
}
else
{
printf("Conversion des coordonnees (u,v) d'un vent en (dd,ff)n");
printf("-----------------------------------------------------n");
printf("1 => Saisie d'un couple (u,v)n");
printf("2 => Traitement sur un fichier de donnees ?n");
scanf("%d",&rep);
if (rep!=1 && rep!=2) exit(-1);

if (rep==1)
{
type=UV;
printf("Coordonnee u ? ");
scanf("%f",&u);
printf("Coordonnee v ? ");
scanf("%f",&v);
}
else
{
type=FICHIER;
printf("Nom du fichier a traiter ? ");
scanf("%s",&entree);
printf("Nombre de couples (u,v) par enregistrement ? ");
scanf("%d",&nb);
}
}

if (type==UV)
{
vent_uv_ddff(u,v,&dd,&ff);
printf("dd=%d ff=%.1fn",dd,ff);
}
else
{
fp1=fopen(entree,"r");
if (fp1==NULL)
{
printf("%s n'existe pas!n",entree);
exit(0);
}
sprintf(sortie,"%s.res",entree);
fp2=fopen(sortie,"w");
while (!(feof(fp1))) lecture_ligne(nb);
fclose(fp1);
fclose(fp2);
}
}


void lecture_ligne(int nb)
{
char chaine[160];
float u,v,ff;
int n,dd;

fgets(chaine,160,fp1);
if (!(feof(fp1)))
{
fprintf(fp2,"%s;",strtok(chaine,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));
fprintf(fp2,"%s;",strtok(NULL,";"));

for (n=1;n<=nb;n++)
{
u=atof(strtok(NULL,";"));
v=atof(strtok(NULL,";"));

vent_uv_ddff(u,v,&dd,&ff);
fprintf(fp2,"%d;%.2f;",dd,ff);
}
fprintf(fp2,"n");
}
}






Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Elodie" wrote:

Je n'ai pas trop eu le temps bosser la dessus aujourd'hui et je pars en
vacances mais je reviendrais surement à la charge à mon retour ;)


A peine arrivée, et déjà partie en vacances...

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Olivier
Elodie wrote:

Eh non même pas stagiaire mais récemment arrivée j'avoue ! Et en plus je
suis une vraie fille (incroyable non ?), et vraiment susceptible aussi !!


Incroyable en effet une fille qui code ! Sinon, il ne fallait pas
mal prendre mon message, chère demoiselle, il n'avait pas d'autre
but que de vous taquiner un peu.

En tous cas, merci beaucoup à Anthony et Régis. Je n'ai pas encore eu le
temps de tout regarder mais voici ce que donne le debugger :

Program received signal SIGSEGV, Segmentation fault.
0x42031d51 in __strtod_internal () from /lib/tls/libc.so.6

Et le plantage intervient juste après la saisie du nombre de couple (u,v)


Quel paramètres ont été donnés à strtod ? quel bout de code l'appelle ?

oliv

1 2