Commentaire sur un code en C

Fermé
jeff - 10 nov. 2005 à 23:35
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 - 11 nov. 2005 à 11:40
Bonsoir à tous , je vous présente un programme qui est une version réduite à l'essentiel du programme UNIX wc ( word count ) . Ce programme compte les lignes , les caractères , les mots en définissant un mot approximativement comme toute séquence de caractères qui ne contient ni espace , ni tabulation , ni fin de ligne :

Je vais commenter ce code jusqu'à ce que je sache le faire , à la fin j'arrive pas à le commenter , j'ai besoin de votre aide svp
#include <stdio.h>

#define DEDANS 1 /*à l'intérieur d'un mot*/
#define DEHORS 0 /*à l'extérieur d'un mot*/

int main()

{

int c, nl, nm, nc, etat; /* déclaration des variables à utiliser dans le programme */

etat = DEHORS;
nl = nm = nc = 0;

/*affectation des valeurs aux variables*/

while ( (c = getchar() ) != EOF) / tant que la variable c prendre un caratère en entrée différent de EOF )
{
++nc; /* on compte le nombre de caractères */
if ( c == '\n' ) 
++nl;

/* si ce caractère est une fin de ligne , on compte les lignes , enfin on les incrémente */
if ( c == ' ' || c == 'n\' || c == '\t' ) /* si le caractère pris en entrée est une fin de ligne , une tabulation ou un espace */ et ensuite je n'arrive plus à comprendre la logique du programme , l'état est DEHORS ok ? MAIS 0 PARTIR DU ELSE IF... çà donne : si l'état est dehors alors l'état = dedans? çà va pas...
etat = DEHORS;
else if ( etat == DEHORS )
{
etat = DEADANS;
++nm;
}
}
printf("%d %d %d\n", nl, nm, nc);
}




A voir également:

5 réponses

teebo Messages postés 33491 Date d'inscription jeudi 14 octobre 2004 Statut Modérateur Dernière intervention 24 février 2011 1 793
11 nov. 2005 à 10:07
Salut

En fait mettons que tu ais:

Ceci est mon texte.


Quand tu arrives au premier espace, tu remarques que tu es dehors (sous entendu, d'un mot), tu reboucles, et si tu as un caractère normal (pas espace, ni tab, ni retour charriot, autrement dit une lettre ou un chiffre (manque d'ailleurs les ponctuations, passons)) et que tu étais "dehors" alors tu comptes un mot de plus et tu remets ton compteur à dedans...

J'éspère avoir éclairé, sinon hésite pas à redemander, j'ai bien compris le truc mais mon explication me semble pas tiptop...
0
ton explication n'est pas si mal , mais là où il faudrait m'éclairer alors c'est sur ton "reboucle" :

elfe if ( etat == DEHORS ) /* donc si l'état de la variable est DEHORS , autrement dit qu'on sort d'un mot */

etat = DEDANS; /* etat devient DEDANS , çà va pas j'ai du mal là , c'est surement le rebouclage que tu as voulu m'expliquer mais j'ai pas bien saisi la structure de ce doee alorrs */


mais on est d'accord que la variable etat est simplement là pour compter les mots , pas les lignes ni les caractères...
0
teebo Messages postés 33491 Date d'inscription jeudi 14 octobre 2004 Statut Modérateur Dernière intervention 24 février 2011 1 793
11 nov. 2005 à 10:29
Bon, je te réécris le programme en pseudo code vite fait avec juste la partie intéressante...

while (not EOF)
    if (char actuel est une fin de mot)
        etat=dehors
    else if (etat=dehors)
        nm++;
        etat=dedans;


Donc en fait tu arrives à la fin d'un mot (à un caractère qui est "dehors" du mot), tu dis que tu es dehors, et tu boucle (ton while), si le caractère suivant est une lettre, tu passes dans le else, tu remarques que avant tu étais dehors, alors tu précises que tu rentre "dedans" un mot, et tu augmentes ton compteur.

Tu pourrais te passer éventuellement de ça en faisant

while (not EOF)
    if (char actuel est une fin de mot)
         nm++;


Mais tu courerais le risque d'avoir deux espaces et donc de compter

je[ ][ ]teste
Comme 3 mots(les [] sont là que pour la compréhensions de mes deux espaces...)

C'est mieux?

0
oui c'est plus clair merci beaucoup
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
11 nov. 2005 à 11:40
Salut,

Une version reduite en Perl.
J'ai le même résultat que wc
[lamitest@localhost bin]$ cat suppr_espace_dans_fichier.pl | wc -l
8
[lamitest@localhost bin]$ cat suppr_espace_dans_fichier.pl | wc -w
16
[lamitest@localhost bin]$ cat suppr_espace_dans_fichier.pl | wc -c
130
[lamitest@localhost bin]$

Script perl
#! /usr/bin/perl -w

use strict;
$"="\n"; # separateur de liste pour affichage
my @nb_mots;
my @nb_caracteres;
while(<>){
        push @nb_mots,$_=~/\w[^\W]+/g;# mot=tout caractère mot sauf les caractères spéciaux
        push @nb_caracteres,$_=~/./gsm; # n'importe quel caractère
}
print "Nombre lignes : $.\n";
print "Nombre mots : ",scalar @nb_mots,"\nNombre caractères : ",scalar @nb_caracteres,"\n";
######## le calcul s'arrête ici #########
# affiche mots et caractères comptés - pour voir à l'écran - pas obligatoire dans le code
print "-" x 5,"Les mots qui sont comptés","-" x 5,"\n@nb_mots\n";
print "-" x 5,"Les caractères qui sont comptés","-" x 5,"\n";

# affichage des caractères et leur code Ascii

foreach (@nb_caracteres){
print $_," - ",ord $_,"\n";
}


Mais c'est délicat. Comment tu veux qu'on considère :
chomp(my ?
Comme 2 mots : chomp et my
ou comme un seul puisuqu'il n'y a pas d'espace.
/\w[^\W]/ dans ce cas j'ai chomp et my donc 2 mots
/[^\t\n\s]/ dans ce cas j'ai chomp(my comme un seul mot

1. Le fichier que j'ai utilisé comme exemple (un autre script).
#! /usr/bin/perl -w

use strict;

print "Entrez une phrase : ";
chomp(my $chaine=<STDIN>);
$chaine=~s/\s+/x/g;
print "$chaine\n";

2. Le résultat
[lamitest@localhost bin]$ perl wc_en_perl_v_reduite.pl suppr_espace_dans_fichier.pl 
Nombre lignes : 8
Nombre mots : 16
Nombre caractères : 130
-----Les mots qui sont comptés-----
usr
bin
perl
use
strict
print
Entrez
une
phrase
chomp
my
chaine
STDIN
chaine
print
chaine
-----Les caractères qui sont comptés-----
# - 35
! - 33
  - 32
/ - 47
u - 117
s - 115
r - 114
/ - 47
b - 98
i - 105
n - 110
/ - 47
p - 112
e - 101
r - 114
l - 108
  - 32
- - 45
w - 119
u - 117
s - 115
e - 101
  - 32
s - 115
t - 116
r - 114
i - 105
c - 99
t - 116
; - 59
p - 112
r - 114
i - 105
n - 110
t - 116
  - 32
" - 34
E - 69
n - 110
t - 116
r - 114
e - 101
z - 122
  - 32
u - 117
n - 110
e - 101
  - 32
p - 112
h - 104
r - 114
a - 97
s - 115
e - 101
  - 32
: - 58
  - 32
" - 34
; - 59
c - 99
h - 104
o - 111
m - 109
p - 112
( - 40
m - 109
y - 121
  - 32
$ - 36
c - 99
h - 104
a - 97
i - 105
n - 110
e - 101
= - 61
< - 60
S - 83
T - 84
D - 68
I - 73
N - 78
> - 62
) - 41
; - 59
$ - 36
c - 99
h - 104
a - 97
i - 105
n - 110
e - 101
= - 61
~ - 126
s - 115
/ - 47
\ - 92
s - 115
+ - 43
/ - 47
x - 120
/ - 47
g - 103
; - 59
p - 112
r - 114
i - 105
n - 110
t - 116
  - 32
" - 34
$ - 36
c - 99
h - 104
a - 97
i - 105
n - 110
e - 101
\ - 92
n - 110
" - 34
; - 59
0