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

strcmp

5 réponses
Avatar
heron
Bonjour,

Pourquoi le code ci-dessous ne fonctionne pas comme il devrait? Nombre
invalide devra=EEt s'afficher si '.' est entr=E9?

D'ailleurs si buffer est un tableau de caract=E8re, strcmp compare
chaque caract=E8re avec '.'. La fonction strcmp devrait =EAtre ...
if( strcmp('.', buffer) =3D=3D 0 ) ... car il s(agit d'un caract=E8re seul
qui entre en comparaison?

Merci de m'=E9clairer.

do
{
ok =3D 1 ;

printf("\n%d. Nombre (fin par \"q\") : ", n+1 ) ;
fgets(buffer, 81, stdin) ;

if ( strcmp(".", buffer) =3D=3D 0 )
{
printf("\nNbr invalide.\n") ;
ok =3D 0 ;
}

} while ( !ok ) ;

5 réponses

Avatar
Samuel DEVULDER
heron a écrit :
Bonjour,

Pourquoi le code ci-dessous ne fonctionne pas comme il devrait? Nombre
invalide devraît s'afficher si '.' est entré?



Ben non. En fait ce sujet a déjà été abordé sur le ng.

Le soucis (outre l'absence de vérif sur la valeur de retour de fgets()
mais qui n'est pas essentiel pour ton problème actuel), c'est quand tu
entres '.' au clavier, le buffer contient en *réalité* '.' suivi de 'n'
et enfin suivi de '', donc tu cherches à comparer "." et ".n", ce qui
explique le phénomène ce que tu observes.

==> man fgets (la partie interressante est dans les >> ... << vers la
fin de la citation)

FGETS(3) NEWLIB

NAME
4.12 'fgets'--get character string from a file or stream

SYNOPSIS
#include <stdio.h>
char *fgets(char *BUF, int N, FILE *FP);


DESCRIPTION
Reads at most N-1 characters from FP until a newline is
found. The characters >>including to the newline<< are stored in
BUF. The buffer is terminated with a 0.

D'ailleurs si buffer est un tableau de caractère, strcmp compare
chaque caractère avec '.'. La fonction strcmp devrait être ...
if( strcmp('.', buffer) == 0 ) ... car il s(agit d'un caractère seul
qui entre en comparaison?




non, fais un "man strcmp":
STRCMP(3) NEWLIB

NAME
--character string compare

SYNOPSIS
#include <string.h>
int strcmp(const char *A, const char *B);


Strcmp() veut deux adresses de chars (qui sont des tableaux dont le
dernier élément doit être un '' pour que ça marche toujours). Quand tu
passes "." tu passes fort justement l'adresse d'un tel tableau qui est
construit pour toi par le compilo quelque part en mémoire. Quand tu
utilises '.' tu passes uniquement le code ASCII du caractère. Ca n'a
rien à voir.

Si tu cherches à savoir si le 1er caractère de buffer est un '.', il te
suffit de faire:

if(buffer[0] == '.')

Si enfin tu veux savoir si buffer contient un caractère '.' quelque
part, il te faut utiliser strchr():

==> man strchr

STRCHR(3) NEWLIB

NAME
--search for character in string

SYNOPSIS
#include <string.h>
char * strchr(const char *STRING, int C);

DESCRIPTION
This function finds the first occurence of C (converted to a
char) in the string pointed to by STRING (including the
terminating null character).

RETURNS
Returns a pointer to the located character, or a null pointer
if C does not occur in STRING.


sam.
Avatar
heron
On 8 mai, 19:02, Samuel DEVULDER
wrote:
heron a écrit :

> Bonjour,

> Pourquoi le code ci-dessous ne fonctionne pas comme il devrait? Nombre
> invalide devraît s'afficher si '.' est entré?

Ben non. En fait ce sujet a déjà été abordé sur le ng.

Le soucis (outre l'absence de vérif sur la valeur de retour de fgets()
mais qui n'est pas essentiel pour ton problème actuel), c'est quand tu
entres '.' au clavier, le buffer contient en *réalité* '.' suivi de ' n'
et enfin suivi de '', donc tu cherches à comparer "." et ".n", ce qu i
explique le phénomène ce que tu observes.

==> man fgets (la partie interressante est dans les >> ... << vers la
fin de la citation)

FGETS(3)                            NEWLIB

NAME
        4.12 'fgets'--get character string from a file or stream

SYNOPSIS
             #include <stdio.h>
             char *fgets(char *BUF, int N, FILE *FP);

DESCRIPTION
        Reads  at  most  N-1  characters  from FP until a newline is
        found. The characters >>including to the newline<< are st ored in
        BUF. The  buffer  is terminated with a 0.

> D'ailleurs si buffer est un tableau de caractère, strcmp compare
> chaque caractère avec '.'. La fonction strcmp devrait être ...
> if( strcmp('.', buffer) == 0 ) ... car il s(agit d'un caractère s eul
> qui entre en comparaison?

non, fais un "man strcmp":
STRCMP(3)                           NEWLIB

NAME
--character string compare

SYNOPSIS
             #include <string.h>
             int strcmp(const char *A, const char *B);

Strcmp() veut deux adresses de chars (qui sont des tableaux dont le
dernier élément doit être un '' pour que ça marche toujours). Q uand tu
passes "." tu passes fort justement l'adresse d'un tel tableau qui est
construit pour toi par le compilo quelque part en mémoire. Quand tu
utilises '.' tu passes uniquement le code ASCII du caractère. Ca n'a
rien à voir.

Si tu cherches à savoir si le 1er caractère de buffer est un '.', il te
suffit de faire:

        if(buffer[0] == '.')

Si enfin tu veux savoir si buffer contient un caractère '.' quelque
part, il te faut utiliser strchr():

==> man strchr

STRCHR(3)                           NEWLIB

NAME
--search for character in string

SYNOPSIS
             #include <string.h>
             char * strchr(const char *STRING, int C);

DESCRIPTION
        This  function  finds the first occurence of C (conve rted to a
        char) in the string pointed to by STRING (including the
        terminating null character).

RETURNS
        Returns a pointer to the located character, or a null poi nter
        if C does not occur in STRING.

sam.



parfait,
merci
Avatar
heron
En fait :

Qu'est-ce qui empeche le code ci-dessous de prendre en compte les
décimales?

#include <stdio.h>
#include <ctype.h> /*isdigit */
#include <stdlib.h> /* atof */
#include <string.h>

#define YES 'o'

int main(void)
{
char buffer[81] ;
double num[50] ;
char rep1, rep2 ;
int i, n, ok ;
int dpoint, start, end ;
double *s, *e, sum ;
int c ;
char *ptr_end ;

n = 0 ;

do /* DO 1 */
{
do /* DO 2 */
{
ok = 1 ;
printf("n%d. Nbr (fin par "q") : ", n+1 ) ;
fgets(buffer, 81, stdin) ;

if ( strchr(buffer, '.') != 0 ) /* If no valid conversion could
be performed then an zero value is returned. */
{
printf("nNbr invalide!n") ;
ok = 0 ;
}
else
{
i = 0 ;
dpoint = 0 ;
while ( buffer[i] != '' && ok )
{
if ( buffer[i] == '.' && dpoint == 0 )
dpoint = 1 ;
else if ( !isdigit(buffer[i]) && !(strcmp("q", buffer) ) )
{
printf("nNbr invalide : n") ;
ok = 0 ;
}
i++ ;
}
} /* fin else */
} while ( !ok ) ; /* DO 2 */

if ( buffer[0] != 'q' )
{
num[n++] = strtod(buffer, &ptr_end) ;
}

} while ( buffer[0] != 'q' && n < 50 ) ; /* DO 1 */

if ( n > 0 )
{
if ( n > 49 )
printf("nCapacite epuise.n") ;
printf("n%d nombre ont ete saisis.n", n) ;
printf("nAfficher le tableau ? (o/n)") ;
if ( rep1 = (getchar() == YES) )
{
printf("n") ;
for ( i = 0 ; i < n ; i++ )
printf("nValeur no %d : t%fn", i+1, num[i]) ;
printf("nn") ;

while ( c = getchar() != 'n' )
;
}
}

printf("nTotaliser le tableau ? (o/n)") ;

if ( rep2 = ( getchar() == YES ) )
{
printf("nDu nombre no : ") ;
scanf("%d", &start) ;

while ( start < 0 || start > n )
{
printf("nDebut de zone invalide!n") ;
printf("nDu nombre no : ") ;
scanf("%d", &start) ;
}

printf("nAu nombre no : ") ;
scanf("%d", &end) ;

while ( end < 0 || end > n )
{
printf("nFin de zone invalide!n") ;
printf("nDu nombre no : ") ;
scanf("%d", &end) ;
}

s = &num[start-1] ;
e = &num[end-1] ;
sum = 0.0 ;

while ( s <= e )
sum += *s++ ;

printf("nLa somme des valeurs %d a %d est de : %fn", start, end,
sum) ;
}

printf("nn") ;
return 0 ;
}
Avatar
Antoine Leca
heron écrivit :
if ( strchr(buffer, '.') != 0 )



S'il y a un '.' quelque part dans la chaîne BUFFER....

printf("nNbr invalide!n") ;



... dire que « c'est invalide »

ok = 0 ;


<...>
while ( buffer[i] != '' && ok )



... et ne pas traiter BUFFER.


Antoine
Avatar
Benoit Izac
Bonjour,

le 10/05/2010 à 16:31, heron a écrit dans le message
:

#include <stdio.h>
#include <ctype.h> /*isdigit */
#include <stdlib.h> /* atof */
#include <string.h>

#define YES 'o'

int main(void)
{
char buffer[81];
double num[50];
char rep1, rep2;
int i, n, ok;
int dpoint, start, end;
double *s, *e, sum;
int c;
char *ptr_end;

n = 0;

do { /* DO 1 */
do { /* DO 2 */
ok = 1;
printf("n%d. Nbr (fin par "q") : ", n + 1);



fflush(stdout); /* pour être sûr que ta ligne s'affiche */

fgets(buffer, 81, stdin);
if (strchr(buffer, '.') != 0) { /* If no valid
* conversion could be
* performed then an
* zero value is
* returned. */



strchr retourne un char* ; on écrit plutôt
if (strchr(buffer, '.') != NULL) {
ou
if (strchr(buffer, '.')) {

ensuite ici tu dis : si buffer contient un « . »,

printf("nNbr invalide!n");
ok = 0;
} else {
i = 0;
dpoint = 0;
while (buffer[i] != '' && ok) {
if (buffer[i] == '.' && dpoint == 0)



ça n'a pas de sens puisque juste avant tu as vérifié qu'il n'y avait pas
de « . ».

dpoint = 1;
else if (!isdigit(buffer[i])
&& !(strcmp("q", buffer))) {



pas besoin des parenthèses : && !strcmp("q", buffer)) {

printf("nNbr invalide : n");
ok = 0;
}
i++;
}
} /* fin else */
} while (!ok); /* DO 2 */

if (buffer[0] != 'q') {
num[n++] = strtod(buffer, &ptr_end);
}

} while (buffer[0] != 'q' && n < 50); /* DO 1 */

if (n > 0) {
if (n > 49)
printf("nCapacite epuise.n");
printf("n%d nombre ont ete saisis.n", n);
printf("nAfficher le tableau ? (o/n)");



fflush(stdout);

if (rep1 = (getchar() == YES)) {



if ((rep1 = getchar()) == YES) {

printf("n");
for (i = 0; i < n; i++)
printf("nValeur no %d : t%fn", i + 1, num[i]);
printf("nn");

while (c = getchar() != 'n');



while ((c = getchar()) != 'n';

}
}

printf("nTotaliser le tableau ? (o/n)");



fflush(stdout);

if (rep2 = (getchar() == YES)) {



if ((rep2 = getchar()) == YES) {

printf("nDu nombre no : ");



fflush(stdout);

scanf("%d", &start);



Il faut vraiment tester le retour de scanf pour savoir si il a
fonctionné car sinon start peut contenir n'importe quoi.

while (start < 0 || start > n) {
printf("nDebut de zone invalide!n");
printf("nDu nombre no : ");



fflush(stdout);

scanf("%d", &start);



même remarque que précédemment

}

printf("nAu nombre no : ");
scanf("%d", &end);



même remarques que précédemment

while (end < 0 || end > n) {
printf("nFin de zone invalide!n");
printf("nDu nombre no : ");
scanf("%d", &end);



même remarques que précédemment

}

s = &num[start - 1];
e = &num[end - 1];
sum = 0.0;

while (s <= e)
sum += *s++;

printf("nLa somme des valeurs %d a %d est de : %fn", start,
end, sum);
}

printf("nn");
return 0;
}



--
Benoit Izac