OVH Cloud OVH Cloud

j'ai besoin d'aide

43 réponses
Avatar
Ghislain Tchoudjeu Ngaha
slt a tous,

je ne m'y connais pas du tout en c++ et je dois ecrire un programme qui
qui change les lettres majuscules en minuscules...Comment le faire?

10 réponses

1 2 3 4 5
Avatar
Vincent Jacques
slt a tous,

je ne m'y connais pas du tout en c++ et je dois ecrire un programme qui
qui change les lettres majuscules en minuscules...Comment le faire?



http://c.developpez.com/faq/cpp/?page=strings#STRINGS_tolower

google est ton ami ;-)

Cela dit ça ressemble à un exercice de cours, alors si tu dois le faire
sans <string> et <algorithm>, avec un tableau de char pour ta chaine, il
faut que tu parcoures ta chaine et que tu regarde si chaque caractère
est entre 'a' et 'z' et que le cas échéant tu lui ajoute ('A'-'a'). Mais
ce n'est pas du C++ ;-)

Bon courage,

--
Vincent Jacques

"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème."
Devise Shadok

Avatar
Fabien LE LEZ
On Tue, 15 Nov 2005 21:31:00 +0100, Ghislain Tchoudjeu Ngaha
:

je ne m'y connais pas du tout en c++ et je dois ecrire un programme qui
qui change les lettres majuscules en minuscules...


Après quelques années de lecture assidue de fr.comp.lang.c++, je ne
suis pas sûr que je saurais faire ça proprement.
Je sais à peine le faire dans les cas particuliers que je rencontre.

Comment le faire?


Changer de langage. Le C++, s'il est largement plus pratique que le C,
est tout de même loin d'être le langage le plus agréable pour gérer
les chaînes, surtout quand on ne le maîtrise pas.
PHP, par exemple, est un petit peu plus décent dans ce domaine.

Avatar
Vincent Jacques
On Tue, 15 Nov 2005 21:31:00 +0100, Ghislain Tchoudjeu Ngaha
:


je ne m'y connais pas du tout en c++ et je dois ecrire un programme qui
qui change les lettres majuscules en minuscules...



Après quelques années de lecture assidue de fr.comp.lang.c++, je ne
suis pas sûr que je saurais faire ça proprement.


Aïe... La FAQ de developpez.com
(http://c.developpez.com/faq/cpp/?page=strings#STRINGS_tolower)
m'aurait-elle menti ?

Sans provocation, je suis curieux et aime le "propre",
--
Vincent Jacques

"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème."
Devise Shadok


Avatar
Fabien LE LEZ
On Tue, 15 Nov 2005 22:31:09 +0100, Vincent Jacques
:

Aïe... La FAQ de developpez.com
(http://c.developpez.com/faq/cpp/?page=strings#STRINGS_tolower)
m'aurait-elle menti ?


S'il s'agit de transformer en minuscules des lettres non accentuées,
ça doit pouvoir se faire sans trop de problèmes.

Maintenant, si tu as le caractère char(192) à convertir, comment
fais-tu ?

Avatar
kanze
Vincent Jacques wrote:

je ne m'y connais pas du tout en c++ et je dois ecrire un
programme qui qui change les lettres majuscules en
minuscules...Comment le faire?


http://c.developpez.com/faq/cpp/?page=strings#STRINGS_tolower


Comme ils disent, le code-là ne se compile pas avec tous les
compilateurs. Ce qu'il ne dit pas, c'est que quand il compile,
il a un comportement indéfini lors de l'exécution.

C'est le genre de solution qu'on propose quand on ne connaît pas
le C++. La solution avec transform serait quelque chose du
genre :

typedef std::ctype< char >
Cvt ;
std::transform(
source.begin(), source.end(),
std::back_inserter( dest ),
std::bind1st(
std::mem_fun(
static_cast< char (Cvt::*)( char ) const >(
&Cvt::tolower ) ),
&std::use_facet< Cvt >( std::locale() ) ) ) ;

Sans oublier d'initialiser le locale global avant. Et sans
oublier d'inclure <algorithm>, <functional>, <iterator>, <local>
et les include pour les collections utilisées. (Si tu oublies un
include, ça peut bien marcher avec un compilateur, mais pas avec
un autre.)

google est ton ami ;-)


Plus ou moins. Il faut quand même savoir juger la fiabilité des
informations qu'on trouve. En fait, il y a beaucoup plus de
désinformation que d'information sur la toile.

Cela dit ça ressemble à un exercice de cours, alors si tu dois
le faire sans <string> et <algorithm>, avec un tableau de char
pour ta chaine, il faut que tu parcoures ta chaine et que tu
regarde si chaque caractère est entre 'a' et 'z' et que le cas
échéant tu lui ajoute ('A'-'a'). Mais ce n'est pas du C++ ;-)


Bof. La plus simple, si on connaît l'encodage en jeu, et qu'on
se limite l'anglais (et encore), c'est de faire un simple
tableau de transcodage. Si on veut faire proprement, en
revanche, il faut bien définir exactement ce qu'on entend par «
changer les majuscules en minuscules ». Par exemple, donnée la
chaîne, "M. DUPONT M'AMENE A LA FETE D'ETE", je m'attendrais à
"M. Dupont m'amène à la fête d'été". Ce qui serait un sacré
devoir, si c'en est un. Que faire, par exemple, de "LES INTERNES
DE L'HOPITAL PSYCHIATRIQUE" ? Parle-t-on des internes ou des
internés ?

Évidemment, dans un français soigné, on mettrait les accents sur
les majuscules, ce qui simplifierait le problème énormement.
Mais un programme robuste ne peut pas y compter, et dans
d'autres langues, tel l'allemand, ça ne suffira pas. En général,
il n'y a pas de bijection entre les majuscules et les
minuscules, ce qui fait que quand on a tout en majuscules ou
tout en minuscules, il y a une perte d'information qu'on ne peut
combler qu'avec grande difficulté.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
Fabien LE LEZ wrote:
On Tue, 15 Nov 2005 22:31:09 +0100, Vincent Jacques
:

Aïe... La FAQ de developpez.com
(http://c.developpez.com/faq/cpp/?page=strings#STRINGS_tolower)
m'aurait-elle menti ?


S'il s'agit de transformer en minuscules des lettres non
accentuées, ça doit pouvoir se faire sans trop de problèmes.


Comme c'est écrit sur le site, le code ne se compile pas avec
tous les compilateurs. Ce qu'il n'ont pas écrit, c'est que quand
il se compile, il a un comportement indéfini. Ce n'est pas du
C++ légal.

Maintenant, si tu as le caractère char(192) à convertir,
comment fais-tu ?


En général, il faut partir du principe que tu peux trouver
n'importe quoi dans un fichier d'entrée. On peut, à la rigueur,
dire qu'on ne traduit pas les caractères accentués, parce qu'ils
ne sont pas présents dans l'encodage qu'on utilise (encore que
je trouve cette attitude inacceptable en Europe), mais il ne
faut pas tomber dans le comportement indéfini simplement parce
que les données en entrée ne sont pas ce auxquelles on s'attend.

Pour une définition un peu simplistes de « convertir majuscules
en minuscules », la norme prévoit pas moins de quatres
« fonctions » :

int std::tolower( int ) ;
template< typename CharT > CharT
std::tolower( Char, std::locale const& ) ;
template< typename CharT > CharT
std::ctype< CharT >::tolower( CharT ) const ;
template< typename CharT > CharT const*
std::ctype< CharT >::tolower( CharT*, CharT* ) const ;

Les deux premières sont des fonctions libres, les deux dernières
des fonctions membres de std::ctype. Quand on veut en utiliser
l'adresse d'une des deux premières, il faut que le contexte
permette au compilateur de résoudre le surcharge ; ce n'est
jamais le cas quand l'adresse sert de paramètre à une fonction
templatée, et que le paramètre doit servir dans la deduction du
type :le type de la fonction généré dépend du type du
paramètre, et le type du paramètre dépend du type de la
fonction ; alors, comment est-ce que le compilateur peut faire ?

Ensuite, il faut noter que la seule fonction dans la liste qui
n'est pas en fait un template, c'est la première, et la première
prend et rend int, et non char. Pire, c'est qu'il n'a un
comportement défini que si l'int vaut EOF ou qu'il est dans
l'intervale 0...UCHAR_MAX. C-à-d que si char tout court est
signé (le cas le plus fréquent), tu ne peux pas lui passer un
char sans avoir un comportement indéfini (ou s'être assuré avant
que le char en fait n'est pas négatif). C'est la seule fonction
qu'on avait en C (et en C++ pré-norme), et c'était systèmatique
de convertir le char en unsigned char avant de l'appeler, c-à-d :

*p = tolower( (unsigned char)( *p ) ) ;

C'est aussi la seule fonction dans la liste qui peut s'appeler
avec un seul paramètre ; je suppose que c'est la fonction voulue
dans le code sur le site cité. (D'après le commentaire, faux,
que <string> inclut <cctype>. Qui, d'ailleurs, ne doit pas
déclarer tolower, mais seulement std::tolower. Mais je ne
connais pas de compilateur qui est conforme sur ce point.)
Seulement, std::transform va bien appeler cette fonction avec un
char comme paramètre, ce qui est un comportement indéfini. Pour
utiliser cette fonction, il faut faire :

#include <ctype.h>

struct ToLower
{
char operator()( char ch ) const
{
return tolower( static_cast< unsigned char >( ch ) ) ;
}
} ;

// ...
std::transform( ..., ToLower() ) ;

Pendant longtemps, j'aurais dit que c'est la seule solution
portable, mais depuis peu, les compilateurs commencent à
supporter toute la puissance des templates, et aussi parfois
même <locale>. Du coup, on pourrait bien considérer
l'utilisation des trois autres fonctions. Qui ont les
caractèristiques tous les trois d'être des templates, et donc de
fonctionner correctement avec char, sans cast, et aussi d'avoir
besoin d'un objet du locale -- soit std::locale même, soit
std::ctype<CharT>. Si les locales dont tu as besoin fonctionnent
avec les compilateurs dont tu te sers, donc, on pourrait écrire
quelque chose comme :

typedef std::ctype< char >
Cvt ;
std::transform(
source.begin(), source.end(),
std::back_inserter( dest ),
std::bind1st(
std::mem_fun(
static_cast< char (Cvt::*)( char ) const >(
&Cvt::tolower ) ),
&std::use_facet< Cvt >( std::locale() ) ) ) ;

Ça compile et ça marche bien en locale "C" avec g++ 3.4.3, par
exemple. Au moins sous Solaris, en revanche, g++ ne supporte pas
trop les autres locales, ou au moins le locale dont je me sers
d'habitude. (Je crois que le supporte pour les locales est mieux
sous Linux.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Fabien LE LEZ
On 16 Nov 2005 01:02:15 -0800, "kanze" :

Par exemple, donnée la
chaîne, "M. DUPONT M'AMENE A LA FETE D'ETE", je m'attendrais à
"M. Dupont m'amène à la fête d'été".


Houlà !
D'une part, ça ne répond pas à la question, puisqu'il reste des
majuscules.
D'autre part, tu fais de la correction orthographique : le mot "FETE"
est incorrect ; le mot "FÊTE" (ou "fête") l'est.
Ben oui, les accents sont obligatoires en français, même sur les
majuscules.

Enfin bon, si on sait qu'on travaille sur du texte en français (sans
fautes d'orthographe), la conversion n'est pas trop difficile.

Mais quid de l'allemand ? Si j'ai bien compris, le "ß" se transforme
en "SS" en majuscules. Mais est-ce qu'un "SS" se transforme
systématiquement en "ß" ?

Avatar
Fabien LE LEZ
On 16 Nov 2005 01:46:10 -0800, "kanze" :

Maintenant, si tu as le caractère char(192) à convertir,
comment fais-tu ?


(Je crois que le supporte pour les locales est mieux
sous Linux.)


J'ai cru comprendre que sous Windows, Microsoft aurait tendance à
abandonner totalement les char, et d'utiliser Unicode à la place.
Ce qui, je crois, évite le problème que je citais ci-dessus.


Avatar
Falk Tannhäuser
Fabien LE LEZ wrote:
Mais quid de l'allemand ? Si j'ai bien compris, le "ß" se transforme
en "SS" en majuscules. Mais est-ce qu'un "SS" se transforme
systématiquement en "ß" ?


Malheureusement non, et même en cherchant dans un dictionnaire on
ne pourra pas toujours le décider - pour exemple, il y a "Maße"
(pluriel de "Maß") et "Masse".

Falk

Avatar
Vincent Jacques
Vincent Jacques wrote:



je ne m'y connais pas du tout en c++ et je dois ecrire un
programme qui qui change les lettres majuscules en
minuscules...Comment le faire?




http://c.developpez.com/faq/cpp/?page=strings#STRINGS_tolower


C'est le genre de solution qu'on propose quand on ne connaît pas
le C++.


Ah. Bon, que moi je ne connaisse pas le C++ n'est pas bien grave, mais
que developpez.com ne le connaisse pas, c'est plus embetant... Merci
pour vos éclairages, à vous et à LE LEZ.

--
Vincent Jacques

"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème."
Devise Shadok



1 2 3 4 5