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

Problème bizarre

38 réponses
Avatar
iTRiX
Bonjour
Je suis étudiant en informatique et j'ai un petit programme à faire en C++.
J'ai un problème assez étrange dont je suis incapable de trouver la
solution.

Le problème se situe au niveau de la fonction sepchamps. Son rôle est de
séparer les champs selon les * du fichier trans.txt. Voici son contenu :

020104 * Claude Lesage * Portes CLAP * 203456 * 2 *
200.50
080404 *PAULE Thorin* Serres Bulbes* 056753 *12* 5.80
121003* alain provost * Cimenterie Forte * 208935*20*8.55

Il semblerait que, par exemple, lorsque j'appelle cette fonction avec date,
il écrit également dans nom. Lorsque je la lance avec nom, elle écrit
également dans date. C'est peut-être juste une petite erreur mais je ne la
vois pas.

L'exercice consistera plus tard à faire une mise en forme correcte pour
l'affichage mais je ne suis pas rendu là. Le fichier chn.cpp dont on doit se
servir contient des fonctions semblables à celle de string.h. J'ai inclus
son listing à la fin mais je doute que l'erreur provienne de là.

J'espère avoir été assez clair dans mon problème et merci beaucoup à tous
ceux qui prendront de leur temps pour m'aider!! :-)
Note: On utilise le compilateur Borland C++ 5.0

Voici donc le code de mon programme jusqu'à maintenant:
#include <string.h>
#include "chn.cpp"
#include <iostream.h>
#include <fstream.h>
#include <conio.h>

// Variables globales
int tauxtx,lg;
ifstream f;
char ligne[100], date[10], nom[30], fournisseur[45], produit[60],
quantite[85], prixunit[100];

// Prototypes
void liretx();
void ouv();
void lirel();
void traiter();
void sepchamps(char a[]);
void fermer();

// Fonction principale
void main()
{
liretx();
ouv();
lirel();
traiter();
fermer();
}

// Lire le taux de taxe
void liretx()
{
cout << "Veuillez entrer le taux de taxation a appliquer\n"; cin >> tauxtx;
}

// Ouvrir le fichier
void ouv()
{
f.open("c:\\trans.txt",ios::in);
}

// Lire une ligne du fichier
void lirel()
{
f.getline(ligne,100);
}

// Traiter
void traiter()
{
lg=Ch_Longueur(ligne);
sepchamps(date);
sepchamps(nom);
sepchamps(fournisseur);
sepchamps(produit);
sepchamps(quantite);
sepchamps(prixunit);
cout << nom << "\n" << fournisseur << "\n" << produit << "\n" << quantite <<
"\n" << prixunit << "\n";
getch();
}

// Séparer les champs de la ligne
void sepchamps(char a[])
{
int k;
k=Ch_Rech(ligne,'*');
Ch_Copie_Nb(a,ligne,k-1);

strrev(ligne);
Ch_Copie_Nb(ligne,ligne,lg-k);
strrev(ligne);
}

// Fermer le fichier
void fermer()
{
f.close();
}


LISTING DE CHN.CPP
//Bibliothèques requises
#include <iostream.h>
#include <conio.h>
#include <string.h>

// Protocoles
void Ch_Init_Nb(char X[], char C, int Nb);
int Ch_Lire_Max(char X[], int Max);
int Ch_Longueur(char X[]);
void Ch_Copie(char CR[], char CE[]);
void Ch_Copie_Nb(char CR[], char CE[], int Nb);
void Ch_Concat(char CR[], char CE[]);
void Ch_Concat_Nb(char CR[], char CE[], int Nb);
int Ch_Rech(char X[], char C);

// Fonction pour initialiser selon un caractère particulier
void Ch_Init_Nb(char X[], char C, int Nb)
{
for(int i=0; i<Nb; i++)
X[i] = C;
X[Nb] = '\0';
}

// Fonction pour lire une chaîne selon un max de caractère
int Ch_Lire_Max(char X[], int Max)
{
int i=0;
char tmp;
tmp=getche();
while(i<(Max-1) && tmp!=13)
{
X[i]=tmp;
tmp=getche();
i=i+1;
}

return i;
}

// Fonction pour obtenir la longueur d'une chaîne
int Ch_Longueur(char X[])
{
int i=0;
while(X[i]!='\0')
{
i=i+1;
}
return i;
}

// Fonction pour copier une chaîne d'une variable à une autre
void Ch_Copie(char CR[], char CE[])
{
int i=0;
while(CE[i]!='\0')
{
CR[i]=CE[i];
i++;
}
CR[i]='\0';
}

// Fonction pour copier une partie d'une chaîne dans une autre
void Ch_Copie_Nb(char CR[], char CE[], int Nb)
{
int i=0;
while(CE[i]!='\0' && i<Nb)
{
CR[i]=CE[i];
i++;
}
CR[i]='\0';
}

// Fonction de concaténation
void Ch_Concat(char CR[], char CE[])
{
int k;
k=Ch_Longueur(CR);
Ch_Copie(CR+k,CE);
}

// Fonction de concaténation limitée
void Ch_Concat_Nb(char CR[], char CE[], int Nb)
{
int k;
k=Ch_Longueur(CR);
Ch_Copie_Nb(CR+k,CE,Nb);
}

// Fonction de recherche de caractère
int Ch_Rech(char X[], char C)
{
int Pos=-1;
for(int i=0;i<50;i++)
{
if(X[i]==C)
{
Pos=i;
i=50;
}
}
return (Pos+1); //Valeur réelle
}

10 réponses

1 2 3 4
Avatar
Alexandre
Je pense que vous n'avez pas encore vu les classes, ni même les
structures


apparement... Sinon il FAUT vous en servir, ici.
Les chaînes "à la C" sont à mon avis indiquées pour des histoires de
taille

de champ, non ? Sinon je ne vois pas l'avantage par rapport à
std::string


(que vous n'avez peut-être pas vu encore)


Oui, on a vu les classes et les structures mais il faut utilisez ces
variables car c'est plus "simple" selon lui...


ah... Surprenant. A votre place je ferais le programme en assembleur 8086,
c'est encore plus simple.



// Prototypes
void liretx();
void ouv();
void lirel();
void traiter();
void sepchamps(char a[]);
void fermer();


Ici aussi, les prototypes sont imposés par le prof ? Parce que je
comprends

les variables globales : aucun paramètre aux fonctions, aucune valeur de
retour !!!
Bref, de la programmation à deux balles.


Non, c'est pas imposé mais de la manière qu'il veut ça, c'est des
fonctions

void.


Pas très clair... Que le fonctions ne renvoient rien, passe encore... Mais
qu'il n'y ait pas de paramètres ! la fonction ouv(), par exemple, ouvre quoi
???



Dites, ça fait combien d'heures que le prof a commencé le C++ ? Parce
que


je
trouve que la POO est très absente de votre exercice (au demeurant fort
simple mais très "C" dans l'esprit)
ça ne m'étonnerait pas si votre prof enseignait le C il y a quelques
années... Il a remplacé printf par cout pour faire du C++, apparament !



On a commencé à voir la POO mais le prof "veut" qu'on utilise cette
méthode

pour ce travail. C'est un très vieux prof. Il enseignait à mon père quand
il

était au cégep lui même...


Ce qui n'est pas une raison. Je travaille avec une enseignante de 61 ans qui
utilise des méthodes récentes de programmation.
Il ne devrait pas appeler son cours : "C++" mais "C".



Avatar
Loïc Joly
Fabien LE LEZ wrote:

On Fri, 9 Apr 2004 11:39:00 -0400, "iTRiX" wrote:


En fait, officiellement, c'est un cours de C++ mais des fois il dit C,
d'autres fois, C++.



On va dire que c'est un prof de C+...


Vu que dans ce cas, il ne fait ni du C correct ni du C++ correct, je
dirais qu'il fait plutôt du C-...

--
Loïc


Avatar
iTRiX
"Alexandre" a écrit dans le message de
news:4076e7eb$0$19503$
Je pense que vous n'avez pas encore vu les classes, ni même les
structures


apparement... Sinon il FAUT vous en servir, ici.
Les chaînes "à la C" sont à mon avis indiquées pour des histoires de
taille

de champ, non ? Sinon je ne vois pas l'avantage par rapport à
std::string


(que vous n'avez peut-être pas vu encore)


Oui, on a vu les classes et les structures mais il faut utilisez ces
variables car c'est plus "simple" selon lui...


ah... Surprenant. A votre place je ferais le programme en assembleur 8086,
c'est encore plus simple.



// Prototypes
void liretx();
void ouv();
void lirel();
void traiter();
void sepchamps(char a[]);
void fermer();


Ici aussi, les prototypes sont imposés par le prof ? Parce que je
comprends

les variables globales : aucun paramètre aux fonctions, aucune valeur
de



retour !!!
Bref, de la programmation à deux balles.


Non, c'est pas imposé mais de la manière qu'il veut ça, c'est des
fonctions

void.


Pas très clair... Que le fonctions ne renvoient rien, passe encore... Mais
qu'il n'y ait pas de paramètres ! la fonction ouv(), par exemple, ouvre
quoi

???


Le fichier texte trans.txt




Dites, ça fait combien d'heures que le prof a commencé le C++ ? Parce
que


je
trouve que la POO est très absente de votre exercice (au demeurant
fort



simple mais très "C" dans l'esprit)
ça ne m'étonnerait pas si votre prof enseignait le C il y a quelques
années... Il a remplacé printf par cout pour faire du C++, apparament
!






On a commencé à voir la POO mais le prof "veut" qu'on utilise cette
méthode

pour ce travail. C'est un très vieux prof. Il enseignait à mon père
quand


il
était au cégep lui même...


Ce qui n'est pas une raison. Je travaille avec une enseignante de 61 ans
qui

utilise des méthodes récentes de programmation.
Il ne devrait pas appeler son cours : "C++" mais "C".



Oui, probablement mais ce n'est pas lui qui décide du programme
d'informatique, il doit enseigner du C++, ou du moins, faire comme si.




Avatar
Fabien LE LEZ
On Fri, 9 Apr 2004 20:14:08 +0200, "Alexandre"
wrote:

Il ne devrait pas appeler son cours : "C++" mais "C".


Même pas -- ce n'est pas non plus du C correct. En C, les fonctions
peuvent avoir des paramètres.

--
;-)
FLL, Epagneul Breton

Avatar
Pierre Maurette
"iTRiX" typa:

"Alexandre" a écrit dans le message de
[...]

Il ne devrait pas appeler son cours : "C++" mais "C".



Oui, probablement mais ce n'est pas lui qui décide du programme
d'informatique, il doit enseigner du C++, ou du moins, faire comme si.
Bravo pour votre solidarité, courageuse du fait que vous deviez vous

sentir seul.
Evitez au maximum les allusions à un professeur sur ce groupe, et
surtoput, ne donnez jamais de grain à moudre aux grincheux en postant
du code de ce prof.
Je me suis déjà exprimé au sujet des critiques trollesques
systématiques envers les enseignants par des gens qui ont certainement
subi un traumatisme de la part d'un professeur. Je me contenterai de
remarquer que ceux-là même qui ne veulent aucun C-isme dans un cours
C++ sont également des programmeurs C, ou en tous cas connaissent le
C.
Pour votre problème, il me semble que la solution vous a été donnée.
Le plus simple en "réparation d'urgence" est d'initialiser la chaîne
a[] passée en paramètre à la même valeur que ligne[], soit 100.
Il est clair que votre code manque cruellement de contrôles (y a-t-il
un '' avant la fin de ligne[]?). Commencez par exemple ici par faire
retourner par la fontion le nombre de caractères trouvés et traités
(un simple return k; devrait le faire).
Pour les variables globales, pour ne pas risquer d'erreur en les
déglobalisant (si vous le souhaitez) vous pouvez les réunir dans une
structure que vous déclarez dans main(). Il vous suffit ensuite de
passer à toutes les fonctions où c'est utile l'adresse de cette
structure, ou si c'est suffisant (pas de modification de l'ex variable
globale) un simple champs passé par valeur. Un défaut de ce "pis à
lait" est de regrouper dans une structure des éléments qui n'ont rien
à voir entre eux.
Ce que je fais quand je toilette du code comportant des varianbles
globales (parfois de mon cru!):
- résoudre celles qui n'ont pas de raison d'être globales (par exemple
le ifstream, ce qui vous amènerait reconsidérer le prototype des
fonctions l'utilisant).
- Quand toutes les fonctions travaillent sur un ensemble de données,
on se retrouve en général avec la possibilité de les rassembler en une
structure ayant du sens.
A ce stade, si la structure et ses champs sont bien nommés, ce n'est
pas trop gênant POUR MOI de la laisser globale, mais je ne le fais
pas. Donc, la déclarer dans main() comme expliqué plus haut, ou en
statique dans une fonction qui renverrait le pointeur sur cette
structure. En C++, une classe avec des getters et setters (inline)
vous donnera une solution propre.

Pierre


Avatar
Fabien LE LEZ
On Sat, 10 Apr 2004 13:52:22 +0200, Pierre Maurette
<maurette.pierreATfree.fr@> wrote:

Je me contenterai de
remarquer que ceux-là même qui ne veulent aucun C-isme dans un cours
C++ sont également des programmeurs C, ou en tous cas connaissent le
C.


Yep, c'est dégueulasse. J'ai même connu des programmeurs C++ qui
connaissaient Visual Basic et qui pourtant n'aimaient pas mettre du
code en VB dans leurs programmes C++.

Franchement, je n'ai rien contre le C, mais il faut choisir : soit on
enseigne/étudie le C, soit on enseigne/étudie le C++. Mélanger les
deux (surtout en phase d'apprentissage), c'est un peu comme apprendre
le tricot et la conduite en même temps, ça ne donne rien de bon.

--
;-)
FLL, Epagneul Breton

Avatar
Pierre Maurette
Fabien LE LEZ typa:

On Sat, 10 Apr 2004 13:52:22 +0200, Pierre Maurette
<maurette.pierreATfree.fr@> wrote:

Je me contenterai de
remarquer que ceux-là même qui ne veulent aucun C-isme dans un cours
C++ sont également des programmeurs C, ou en tous cas connaissent le
C.


Yep, c'est dégueulasse. J'ai même connu des programmeurs C++ qui
connaissaient Visual Basic et qui pourtant n'aimaient pas mettre du
code en VB dans leurs programmes C++.
Je pensais mon raccourci plus clair: je voulais simplement dire qu'ils

connaissaient, et même bien (souvent par la pratique antérieure ou
parallèle du C, mais peu importe) les notions de base du C++ dont ils
critiquent l'usage pédagogique, par exemple les chaînes à 0 final.

A partir de cette constatation, je me demande s'ils ne sont pas dans
l'erreur en affirmant (de bonne foi) que de solides bases sur des
notions comme les pointeurs ne sont pas nécessaires à l'apprentissage
du C++. Puisqu'ils ne peuvent se rendre compte sur eux-mêmes des
effets de cette ignorance.

Je me pose cette question même dans l'optique d'une programmation C++
tout à fait Bjarnienne. Alors qu'en réalité, C++ est un langage
versatile, qui par exemple incorpore la bibliothéque standard C dans
sa norme. Ce n'est pas Java, ni même un pur langage objet.

Je n'ai pas les compétences pour être affirmatif, mais il me semble
que l'utilisation des chaînes de caractères "à la C" est une bonne
proposition pour expérimenter rapidement (et visuellement) sur des
notions comme les pointeurs, l'allocation mémoire, etc. L'erreur de
l'OP en est un bon exemple.

En programmation objet, le bout de code que vous êtes en train de
créer est localement séquentiel. Au coeur d'une classe chaîne, il se
trouve un tableau de char qu'il faut bien traiter à bas niveau. Bien
entendu, le travail a déjà été fait dans ce cas précis, mais le
principe reste.

Pour en revenir à l'enseignement, la question qui va se poser, si le
niveau d'entrée est zéro et le temps imparti faible, est de choisir
entre passer le temps qu'il faut sur les fondamentaux et terminer le
programme coute que coute. Il semble qu'on se soit apperçu récemment
que se posait un peu la même question dans l'enseignement général, et
que l'accent a été mis sur le problème posé par un niveau trop faible
en calcul, raisonnement et expression qui pourrissait trop souvent la
suite de la scolarité.

Mais ce ne sont que des opinions, celles de quelqu'un qui n'a pas
d'états d'âme, pour un travail personnel, à faire ou à reprendre un
programme "à la C" mais écrit en C++, et à y incorporer des strings "à
la C++", comme s'il s'agissait d'un type natif du langage, ou même
quelques classes de ma main. Pour l'instant, aucune morale ne me
pousse à m'en abstenir, mais je peux en découvrir des effets néfastes
objectif. C'est arrivé pour d'autres questions.

Franchement, je n'ai rien contre le C, mais il faut choisir : soit on
enseigne/étudie le C, soit on enseigne/étudie le C++. Mélanger les
deux (surtout en phase d'apprentissage), c'est un peu comme apprendre
le tricot et la conduite en même temps, ça ne donne rien de bon.
Il y a toujours un important chapitre "Conduite de l'aiguille" dans

les bons manuels de tricot.

Pierre


Avatar
Fabien LE LEZ
On Sat, 10 Apr 2004 21:42:55 +0200, Pierre Maurette
<maurette.pierreATfree.fr@> wrote:

A partir de cette constatation, je me demande s'ils ne sont pas dans
l'erreur en affirmant (de bonne foi) que de solides bases sur des
notions comme les pointeurs ne sont pas nécessaires à l'apprentissage
du C++.


Oui et non. On ne peut pas prétendre connaître le C++ sans connaître
ces problèmes. Mais AMHA on ne devrait pas les considérer comme la
base du C++.
Je suis d'avis de commencer un enseignement du C++ par les bases, en
considérant que le type "chaîne de caractères" est std::string. Une
fois qu'on a acquis les bases (y compris le fait qu'on doit préférer
un passage par argument à l'usage de variables globales), on commence
à avoir la maturité suffisante pour s'occuper des trucs plus tordus,
comme les char[], le fait que "Hello" fait 6 caractères, etc.

Franchement, je préfère qu'un étudiant apprenne rapidement comment
faire proprement un programme tel que celui qu'est censé faire l'OP,
en utilisant les fonctionnalités de base du C++ telles que C++, que
débuter l'apprentissage de la conduite en bricolant le moteur, comme
le fait l'OP (ou son prof) en utilisant des char[] à tout va.

--
;-)
FLL, Epagneul Breton

Avatar
Michel Michaud
Dans news:, Fabien LE
Franchement, je n'ai rien contre le C, mais il faut choisir : soit
on enseigne/étudie le C, soit on enseigne/étudie le C++. Mélanger
les deux (surtout en phase d'apprentissage), c'est un peu comme
apprendre le tricot et la conduite en même temps, ça ne donne rien
de bon.


C'est une analogie amusante, je vais essayer de la retenir ! Ceci
dit, on peut la tourner de bien des façons dont une qui permettrait
de voir qu'il est possible d'apprendre une partie du C en apprenant
le C++...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Michel Michaud
Dans news:, Pierre
A partir de cette constatation, je me demande s'ils ne sont pas dans
l'erreur en affirmant (de bonne foi) que de solides bases sur des
notions comme les pointeurs ne sont pas nécessaires à
l'apprentissage du C++. Puisqu'ils ne peuvent se rendre compte sur
eux-mêmes des effets de cette ignorance.


Ceux qui l'enseignent ainsi ne sont pas dans l'ignorance. Il est
clair que les pointeurs (et bien d'autres choses) sont présents
et nécessaires dans C++. Mais on peut faire un grand bout de
chemin en C++ sans en avoir besoin, alors que leur usage s'impose
plus rapidement en C. Ainsi, dans mon plus récent livre, on doit
« attendre » 300 pages avant de parler de pointeurs et, en réalité,
on pourrait attendre encore un peu plus. Je n'ai jamais eu de
plainte des élèves d'avoir « attendu » si longtemps :-)

Il faut y arriver et utiliser, un jour, les pointeurs (intelligents
si on veut) si on veut faire un emploi complet des possibilités de
C++. Mais ça ne sera pas du tout dans une optique C. Passer au C
n'est donc pas instantané, même si on connaît les pointeurs et
leur utilisation en C++...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

1 2 3 4