Langage C

Discutez d'informatique ici !
Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 20 Sep 2013, 12:56

fatal_error a écrit:Simplifier les choses ne veut pas dire débiter des boulettes.

et pendant que j'y suis, non, ca dépend du système de fichier. ntfs windows, ext4 linux (par exemple), ya ptet intérêt à avoir des drivers de temps en temps...
Donc il faut quand même y aller molo sur les affirmations.

Rien de tel qu'un exemple pour infirmer ou vérifier cela.



Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 20 Sep 2013, 19:54

ben sachant que sous linux t'es généralement en ext*, je vois pas comment sous windows tu vas arriver à lire le secteur alors que windows gere pas lext de base :)

le contenu d'un fichier est normalement indépendant de la plateforme, mais la façon dont on accède au fichier diffère selon le système de fichiers.

je viens de te décrire un exemple que tu peux vérifier toi même.
la vie est une fête :)

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 20 Sep 2013, 20:12

Manifestement, on ne parle pas de même chose.
Je parle de fichier, tels que ceux que l'on transmet sur et par un support physique, ou par internet, et non pas de la façon dont il est stocké sur le disque géré par le système, suivant l'OS utilisé.
En tout cas, une chose certaine, les fichiers texte tels que les mails sont créés sous Unix, et pas de souci pour les lire.
La seule différence est le caractère de fin de ligne.
Quant aux fichiers de données en binaire, il n'y a aucune différence. Par contre, les fichiers qui sont des exécutables sont dépendant de l'OS.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 11:06

Peut être pourrez vous me dire ce quine va pas dans la logique de ce code.

(il compile mais ne réalise pas ce que je voudrais qu'il fasse)

Code: Tout sélectionner
char carac;
    int nbMot=0;
    int fin=0;
    int tailleMot=0;
    int mot3c=0;
    printf("Entrez une phrase terminée par un $\n");
    while (fin=0)
    {
        carac=getchar();

        if (carac=' ')
        {
            nbMot=nbMot+1;
            tailleMot=0;
        }
        if (carac!=' ')
        {
            tailleMot=tailleMot+1;
            if (tailleMot>=3)
            {
                mot3c=mot3c+1;
            }
        }
        if (carac='$')
        {
            fin=1;
        }
    }
    printf("La phrase contient %d mots dont %d mots de plus de 3 caractères",nbMot,mot3c);


J'ai cru comprendre que la fonction getchar (et/ou) getche lisait et gardait en mémoire un caractère.

Je fais donc des test sur ce caractère.

Hors si je fais tourner tel quel; le programme me renvois directement les valeurs de nbMot et mot3c égaux à 0 sans rien me laisser taper.

Est ce parce que j'ai une mauvaise utilisation de cette fonction ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 22 Sep 2013, 12:11

Rockleader a écrit:Peut être pourrez vous me dire ce quine va pas dans la logique de ce code.

(il compile mais ne réalise pas ce que je voudrais qu'il fasse)

Code: Tout sélectionner
char carac;
    int nbMot=0;
    int fin=0;
    int tailleMot=0;
    int mot3c=0;
    printf("Entrez une phrase terminée par un $\n");
    while (fin=0)  // Tu positionnes fin = 0 donc la condition "(fin=0)" est toujours vraie
    {
        carac=getchar();

        if (carac=' ')  // un test c'est "==" ou "!=" ou '>'. Le caractère '=' est un caractère d'affectation.
        {
            nbMot=nbMot+1;
            tailleMot=0;
        }
        if (carac!=' ')  soit carac == ' ', soit in ne l'est pas, donc, il faut faire "else"
        {
            tailleMot=tailleMot+1;
            if (tailleMot>=3)
            {
                mot3c=mot3c+1;
            }
        }
        if (carac='$')
        {
            fin=1;
        }
    }
    printf("La phrase contient %d mots dont %d mots de plus de 3 caractères",nbMot,mot3c);


J'ai cru comprendre que la fonction getchar (et/ou) getche lisait et gardait en mémoire un caractère.

Je fais donc des test sur ce caractère.

Hors si je fais tourner tel quel; le programme me renvois directement les valeurs de nbMot et mot3c égaux à 0 sans rien me laisser taper.

Est ce parce que j'ai une mauvaise utilisation de cette fonction ?

Bonjour,
Je te déconseille vivement de travailler à partir de stdin, donc d'utiliser getchar et à fortiori getche.
Lis une chaine avec fgets(Buffer, taille,stdin); puis tu la décode.
J'ai indiqué des fautes dans ton code.
Mais il y a une énorme faute de logique :
Il faut
tester un caractère
s'il est ' ' alors ...
sinon
si c'est un '$' alors ...
si c'est une minuscule ...
etc.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 12:36

Je n'ai pas encore vu la syntaxe exacte du if else voir elsif; c’est pour ça que j'ai aligné deux if..mais oui je suis d'accord avec toi.

Le '=' au lieu de '==' :mur: où avais je la tête...ce sont mes habitudes de ada avec := et = ça...


Lorsque tu me dit que fin est toujours égal à 0 je suis pas d'accord, vu qu'en fin de boucle je peux lui donner la valeur 1. Je suis d'accord que cela pourrait surement s'écrire mieux mais je ne vois pas en quoi ça bloque de ce coté là.

Cela dit tu as raisons, car en changeant et en faisant une condition de la forme !=1 ça passe. Mais je ne comprends pas pourquoi.


Mon programme tourne comme il faut maintenant.


Pour aller plus loin, j'essaierais surement pour moi la méthode que tu m'indique.


Une question tout de même: comment détecte t'on une majuscule ou minuscule en C.

Je suppose qu'il faut passer par la table ascii; mais quelle fonction permettra cela ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 22 Sep 2013, 13:20

Bon, je doute que ton prof soir choque que tu utilise des choses de base pas encore vu en cours. les 'if', 'else' sont des choses de bases supposées connues quand on écrit la première ligne en C
Pour détecter une majuscule, j'ai ouvert mon bouquin et j'ai vu qu'il existait une fonction islower et une fonction isupper de la bibliothèque ctype (donc #include ) qui doit faire cela très bien.
Mais je suppose que si l'exercice porte sur cela, il vaut mieux la réécrire. D'ailleurs dans ctype, ce n'est pas une fonction, mais une macro, alors ...

Concernant la dernière question : si c est un char, alors on peut écrire
if (c > 96 && c < 123)
{
printf(" le caractère %c est minuscule et son code ASCII est %d\n",c,c);
}

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 13:39

Tu dis que c est un caractère mais tu le compares avec un nombre, il n'y a pas une contradiction là ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 22 Sep 2013, 13:57

Si je déclare un caractère
char car;
car est un octet qui peut valoir de -128 à 127.
unsigned char ucar;
ucar est un octet valoir de 0 à 255.
C'est strictement la même chose (en C) de comparer car à 'a' ou à 97.
Rassure toi, je ne connais pas la table ASCII par coeur, Mais il y a de nombreuses années, je l'ai imprimée en grand, affichée en face de moi, je peux donc la lire sans me lever.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 14:03

Donc, si je comprend bien, en C, le compilateur traduit automatiquement une lettre en ascii.

Si j'écrivais une condition du genre

tant que (a != b)

Ce qui se passerait dans le compilateur ce serait tant que (97 != 98); il n'y a donc pas à utiliser de fonction particulière pour passer de l'ascii à son caractère équivalent et inversement.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 22 Sep 2013, 14:20

Oui, exactement, sauf que faudrait écrire
while (x != 'a')
x étant la variable type char, unsigned char, int ou unsigned int, et 'a' entre quotes.
(je suis pas sûr de l'orthographe de 'quote')

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 14:45

Oui ok, bon bah j'ai compris un truc intéressant je crois là merci ! :we:


Petite question, quel sera la différence entre un char par exemple et un unsigned char etc etc
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 22 Sep 2013, 14:58

Un char est sur 8 bits, comme un unsigned char.
Si un char vaut 127 et que j'ajoute 1, le résultat sera -128.
Si je fais la même chose avec un unsigned char cad 127 + 1, j'aurai 128.
Mais avec ce même unsigned char, si feis 255 + 1 j'obtiendrai 0.
C'est la même chose avec les int, sauf que c'est sur 32 bits.

Quand on travaille avec des chaines de caractères, il vaut mieux les déclarer en unsigned char. Même si les caractères numériques, ponctuation, spécieux (<=32) sont inférieurs à 128, il arrive que le caractère de fin de fichier est 255, c'est à dire -1 pour char signé (cf l'article de Wiki) Donc c'est une habitude à prendre.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 15:26

D'accord, mai concrètement les deux marcheront de la même manière ?

Que je fasse unsigned char x ou bien char x le code de mon x sera bien le même ?

Car certains n'ont tout de même pas les mêmes valeurs, je veux bien que des choses du genre l'alphabet ou des nombres soit comprises dans l'intervalle commun [0-127] donc; mais pour les extrêmité uniques de ces intervalles il doit s'agir de caractères spéciaux ?


EDIT: je pense faire un bon investissement en imprimant la table ascii sur une feuille de papier :ptdr:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 22 Sep 2013, 16:07

Oui, mais il ne faut pas tout mélanger.
D'abord, on peut trouver des choses du style
int x=100;
char c=(char)x;
Cela peut se justifier pour certaines raisons.
Il y a aussi des notions de transtypage (qu'on appelle cast).
Ce n'est pas "parce que c'est la même choses" que les écritures sont interchangeables.
Oui, les 128 premiers caractères de la table ASCII sont normalisés (0-127) mais les autres existent aussi. Ce sont effectivement des caractères graphiques qui diffèrent selon les tables, mais ce ne sont pas des caractères dits spéciaux.
La zone des caractères spéciaux est (0-32), c'est la même pour tout le monde.
Avec un langage aussi évolué (et non "de haut niveau") que le C, il faut éviter de dire trop vite "c'est pareil, donc je peux m'en tenir à une seule méthode".

En C, on peut obtenir le même résultat de plusieurs manière, à part les mauvaises, il n'y a pas de méthodes moins bonnes, ni meilleures que d'autres. Par contre, il faut toujours pouvoir dire pourquoi on utilise telle méthode plutôt que telle autre.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Sep 2013, 18:34

Ok et bien merci pour tout ces conseils !
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 23 Sep 2013, 18:17

Nouvelle question :zen:

Je ne comprends pas ce qui se passe dans ce genre d’exécution.


(oui je pourrais directement utiliser une variable de type boolean, mais j'ai pas trouvé le type dans mes cours...mais c’est pas le problème).

Je fais quelques chose dans ce style là, pour demander à l'utilisateur s'il voudra relancer le programme.


Code: Tout sélectionner
char rep='o'
while (rep == 'o')
Bloc d'instruction
Voulez vous continuer (o/n)
scanf("%c",&rep);



Hors lorsque je fais cela, le programme se termine sans même me laisser le temps d'entrer une valeur pour rep. ET j'avoue que je comprends pas pourquoi; on entre bien dans la boucle avec la valeur o.
Vu que le programme se termine, la valeur de rep change, mais comment cela est il possible vu que l'on ne me laisse pas l’opportunité de taper la dite valeur.
J'irai même plus loin, dans la mesure où il y est quelque chose qui se passe au niveau machine qui me change la valeur de rep pendant le bloc d'instruction; pourquoi ne puis je pas tout de même faire mon scanf de rep à la fin de la boucle ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 23 Sep 2013, 19:03

Bonjour,
D'abord, le type booléen n'existe pas en C.
Cependant, on l'utilise beaucoup, anomalie ? : non.
En C, 0 et FALSE, c'est pareil. Donc n'importe quoi non nul, c'est vrai.
C'est pour ça que dans l'instruction
while (ret = 0) // j'ai pas fait de faute
J'avais dit, dans un message précédent, que la condition était toujours vraie (ret = 0) est une affectation, donc c'est vrai.

Concernant le "voulez-vous continuer", quand j'étais sous unix, j'ai eu de gros soucis avec ça, et en fait j'ai fini par renoncer.
Le problème, est qu'une valeur n'est prise en compte que s'il y a return, ce qui impose de frapper 2 caractères.
Sous Windows et à fortiori sous DOS, il n'y a pas de difficulté, c'est quelque-chose du genre
while (!getche()) ou while (!kbhit())
qui n'existe pas sous unix ou linux.
Mais il y a peut-être soit une fonction qui remplace cela, soit une astuce que je ne connais pas.
Comme je n'ai plus de linux sous la main, je ne peut rien tester.
Si il y a une solution, Ampholyte la connait surement.
Sinon, il faut accepter de taper 2 touches.
Là, je donne ma langue au chat. :cry:

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 23 Sep 2013, 19:17

Si je tapais le même code sur mon windows il fonctionnerait donc ?

Et ok pour les booléens, j'aurais pensé qu'ils existaient quand même, mais bon on s'en passe ça reste du bon sens.


Pour l'histoire de taper deux touches, je devrais plutôt déclarer une chaîne de caractère et évaluer avec quelque chose comme oui/non plutôt que o/n si j'ai bien compris ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Dlzlogic
Membre Transcendant
Messages: 5273
Enregistré le: 14 Avr 2009, 13:39

par Dlzlogic » 23 Sep 2013, 19:35

Non, la difficulté est
1- de faire attendre la machine (facile)
2- se contenter d'un seul caractère comme intervention de l'utilisateur.
Il faudrait que tu montres ton code. Windows reconnait kbhit(), tu devrais aussi attendre que Ampholyte dise ce qu'il en pense.

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 7 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite