IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Printf ne fonctionne plus


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Malikemal
    Invité(e)
    Par défaut Printf ne fonctionne plus
    Bonjour à tous,

    Je suis en train d'écrire une fonction de chiffrement en césar, et j'ai un problème ... La fonction marche sans problème, mais quand je fais appelle à la dite fonction, dans le main, et que je veux afficher le résultat avec un printf, celui-ci ne fonctionne pas. Après plusieurs tests, j'ai vu que ça fonctionnait à chaque fois sauf quandje voulais afficher la chaine de caractère qui venait de la fonction cesar ... Pour récupérer le texte au clavier, j'utilise une fonction de mon cru qui renvoie un tableau qui a exactement la taille voulue ! Je met le fichier source en PJ si vous voulez.. Voici donc le CS de la fonction de saisie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    char *saisie(void)
    {
        char *tab = NULL;
     
        tab = malloc(1000 * sizeof(char));
     
        if(tab)
        {
     
            fgets(tab, 999, stdin); /* Pour pourvoir placer le '\0' */
     
            if((strchr(tab, '\n')) == NULL) /* Si le texte est trop grand pour le tableau */
            {        
                tab = utilBuffer(tab);
     
                if(tab == NULL)
                    return NULL;
            }
     
            else if    (strlen(tab) != 999) /* Si le tableau est trop grand pour le texte */
            {
                tab = realloc(tab, strlen(tab) * sizeof(char));
            }
     
            return tab;
        }
     
        else
            return NULL;
    }
     
    char *utilBuffer(char *tab)
    {    
        char *temp = malloc(500 * sizeof(char));
     
        if(temp == NULL)    
            return NULL;
     
        size_t size;
        fgets(temp, 499, stdin);
     
        if((strchr(temp, '\n')) == NULL)
        {    
            temp = utilBuffer(temp);
        }
        size = (strlen(tab) + strlen(temp)) * sizeof(char);
        tab = realloc(tab, size); /* On réajuste le tableau */
        strcat(tab, temp); /* On rajoute */
        return tab;
    }
    Celui de la fonction qui convertit les valeurs en nombres ASCII :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int conversionAscii(char lettre)
    {
        int nombre = -1; /* Contiendra la valeur ASCII */
        nombre = (int) lettre; /* On cast lettre pour qu'il nous donne la valeur ASCII de sa lettre*/
     
    /* On vérifie si 'nombre' est bien un code de la table ASCII*/
        if(!isascii(nombre))  
            return -1;
        else
            return nombre;
    }
    La fonction de cryptage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    char* cesar(void)
    {
        int i = 0;
        char *texte = malloc(100); /* Texte à crypter ou décrypter */
        char *result = NULL; /* Texte crypter ou décrypter */
        int *valeurAscii = NULL; /* Tableau contenant les valeurs Ascii des lettres de 'texte' */
        long decalage = 3; /* Décalage à opérer */        
     
        texte = saisie();
        result = malloc(sizeof(*texte)); 
        valeurAscii = malloc(strlen(texte) * sizeof (int));
     
        for(i = 0; texte[i]; i++)
        {
            valeurAscii[i] = conversionAscii(texte[i]);
     
                if(valeurAscii[i] + decalage > 255) /* Si jamais la valeur ASCII est trop grande */
                    valeurAscii[i] = (valeurAscii[i] + decalage) - 255;
     
                else
                    valeurAscii[i] = valeurAscii[i] + decalage;
     
            result[i] = toascii(valeurAscii[i]);
        }
     
        return result;
     
     
    }
    et voila la fonction principale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main()
    {
    printf("%s", cesar());
    return 0;
    }
    Je suis sur que la fonction marche car j'ai fait un fprintf dans un fichier texte, et ça ma donné le bon crypt. Si vous voulez plus de précisions je suis à votre service !

    Merci,
    Fichiers attachés Fichiers attachés
    Dernière modification par Malikemal ; 05/06/2011 à 15h18.

  2. #2
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Dans la fonction cesar

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = malloc(sizeof(*texte));
    l'espace alloué pour result fait la taille d'un char, ce n'est pas suffisant pour ce que tu veux faire.

  3. #3
    Malikemal
    Invité(e)
    Par défaut
    Je vais corriger ça, mais à supposer que ce soit ce qui cause le problème ça m'aurait mis "Segmentation Fault" non ?

  4. #4
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Je vais corriger ça, mais à supposer que ce soit ce qui cause le problème ça m'aurait mis "Segmentation Fault" non ?
    Pas forcement.

    Il n'y a pas que cela :
    tu fait des malloc un peu partout et jamais de free,

    fonction cesar :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char *texte = malloc(100); // char *texte = malloc(100*sizeof(char)); 
     
    //....
     
    texte = saisie();
    ton espace alloué est perdu a jamais

  5. #5
    Malikemal
    Invité(e)
    Par défaut
    Ooooups ! Je vais de suite corriger ça et je reposte en EDIT, le fichier corrigé .... J'en profite pour voir si ça remarche !

    EDIT : Ca ne marche toujours pas ....
    Fichiers attachés Fichiers attachés

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Il y a plein de fuites de mémoire potentielles dans ton code. De plus, ta fonction de saisie est plutôt bancale, elle manque de logique. Si la chaine dépasse, elle appelle une autre fonction pour concaténer (et une fois maximum). Cela fait un peu "usine à gaz" manquant de cohérence.

    Je te propose une solution un peu plus clean :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #define TAILLE_MAX_SAISIE 10 /* valeur arbitraire, à modifier si besoin */
     
    char * saisie(void)
    {
    	char tab[TAILLE_MAX_SAISIE];
    	char * chaine = NULL;
    	size_t taille_totale = 1; /* la chaine contient au moins '\0' */
    	int fin_boucle = 0;
     
    	do
    	{
    		size_t taille_saisie;
     
    		fgets(tab , TAILLE_MAX_SAISIE , stdin);
    		{
    			char * supp_lf;
    			supp_lf = strchr(tab , '\n'); /* on vire le '\n' s'il est présent */
    			if (supp_lf != NULL)
    			{
    				*supp_lf = '\0';
    				fin_boucle = 1;
    			}
    		}
    		taille_saisie = strlen(tab);
    		taille_totale += taille_saisie;
    		if (taille_totale == 1 /* on cree une chaine vide meme si on n'a rien saisi pour éviter un crash */ || taille_saisie != 0)
    		{
    			char * tmp_realloc;
    			tmp_realloc = realloc(chaine , taille_totale);
    			if (tmp_realloc != NULL)
    			{
    				if (chaine == NULL)
    					*tmp_realloc = '\0'; /* lors de la 1ere alloc, on met '\0' comme 1er caractère (à cause du strcat plus bas) */
    				chaine = tmp_realloc;
    			}
    			else
    			{
    				free(chaine);
    				chaine = NULL;
    				break;
    			}
    			strcat(chaine , tab);
    		}
    	} while (fin_boucle == 0);
     
    	return chaine;
    }
    Quelques remarques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = malloc(sizeof(*texte));
    ouch ! Tu confonds apparemment sizeof et strlen. En tout cas, le résultat de sizeof ici est... 1 !
    De plus, n'oublie pas le '\0' final de ta chaine, il doit être compté.

    Ton tableau valeurAscii ne sert à rien du tout. Tu peux mettre le résultat de ton calcul directement dans ta chaine.

    Il n'y a de free nulle part !

  7. #7
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 57
    Par défaut
    Bonjour,

    Je viens de survoler le sujet et il me semble que ca n'a pas ete dit, meme si je ne pense pas que ca resolve le probleme mais voila:
    Citation Envoyé par Malikemal Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main()
    {
    printf("%s", cesar());
    return 0;
    }
    Il manque un '\n' a ton printf avant le dernier ".

    Bonne journee!

  8. #8
    Modérateur
    Avatar de Overcrash
    Homme Profil pro
    Architecte Logiciel et responsable CRM (Salesforce)
    Inscrit en
    Mai 2008
    Messages
    1 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Architecte Logiciel et responsable CRM (Salesforce)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 254
    Par défaut
    Citation Envoyé par ailonn Voir le message
    Bonjour,

    Je viens de survoler le sujet et il me semble que ca n'a pas ete dit, meme si je ne pense pas que ca resolve le probleme mais voila:


    Il manque un '\n' a ton printf avant le dernier ".

    Bonne journee!
    Il est pas obligatoire ?
    En tout cas il n'afflue en rien le fonctionnement du printf.
    ---
    Overcrash

    Je ne lis pas les codes qui ne sont pas indentés.
    Merci de les messages utiles en cliquant en bas à droite du message

    Bloqué par le firewall pour accéder au chat ? Essayez avec l'adresse en direct : http://87.98.168.209/

  9. #9
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 57
    Par défaut
    A ma connaissance printf bufferise et le '\n' est la pour lui dire fin de buffurisation.
    Dans le cas present je ne suis pas sur que ca derange mais dans d'autre cas ou les printf sont dans differentes fonctions, ou simplement plusieurs d'affiler, ca peut donner des effets assez interessants du genre oublier les '\n' sur tout les printf et avoir une longue tres longue chaine de caractere qui va s'afficher au return du main.
    Pour tester:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     #include <stdio.h>
     #include <stdlib.h>
     
     int main()
     {
       printf("Salut");
       printf(" comment");
       printf(" vas");
       printf(" tu?");
       sleep(5);
       printf("\n");
       return (0);
    }

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 26
    Par défaut
    Citation Envoyé par ailonn Voir le message
    A ma connaissance printf bufferise et le '\n' est la pour lui dire fin de buffurisation.
    Dans le cas present je ne suis pas sur que ca derange mais dans d'autre cas ou les printf sont dans differentes fonctions, ou simplement plusieurs d'affiler, ca peut donner des effets assez interessants du genre oublier les '\n' sur tout les printf et avoir une longue tres longue chaine de caractere qui va s'afficher au return du main.
    Pour tester:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     #include <stdio.h>
     #include <stdlib.h>
     
     int main()
     {
       printf("Salut");
       printf(" comment");
       printf(" vas");
       printf(" tu?");
       sleep(5);
       printf("\n");
       return (0);
    }
    Bonjour. printf est en effet une fonction temporisé, mais « \n » n'est pas là pour vider le tampon mais pour indiquer new line. Ici le message est affiché lors du printf("\n"); simplement parce que le programme se termine et que le tampon est alors vidé ; un exemple pour vous en convaincre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     #include <stdio.h>
     #include <stdlib.h>
     
     int main()
     {
       printf("Salut");
       printf(" comment");
       printf(" vas");
       printf(" tu?");
       printf("\n");
       sleep(5);
       return (0);
    }
    aura le même comportement que le code que vous avez donné.

    Pour vider le tampon et provoquer l'affichage du texte, il faut utiliser fflush sur le flux de sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     #include <stdio.h>
     #include <stdlib.h>
     
     int main()
     {
       printf("Salut");
       printf(" comment");
       printf(" vas");
       printf(" tu?");
       fflush( stdout );
       sleep(5);
       return (0);
    }

  11. #11
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 57
    Par défaut
    Ton premier exemple n'est pas concluant. Si j'ai bien compris l'affichage ne devrais se faire qu'apres 5 secondes alors qu'il est directe et on attend 5 seconde avant la fin de l'execution.
    Il se peut que la demande de nouvelle ligne declenche le vidage du tampon.

    Mais je reconnais que vider le tampon est aussi efficace pour declencher l'affichage.
    Merci je ne le savais pas et

  12. #12
    Modérateur
    Avatar de Overcrash
    Homme Profil pro
    Architecte Logiciel et responsable CRM (Salesforce)
    Inscrit en
    Mai 2008
    Messages
    1 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Architecte Logiciel et responsable CRM (Salesforce)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 254
    Par défaut
    Citation Envoyé par ailonn Voir le message
    A ma connaissance printf bufferise et le '\n' est la pour lui dire fin de buffurisation.
    Dans le cas present je ne suis pas sur que ca derange mais dans d'autre cas ou les printf sont dans differentes fonctions, ou simplement plusieurs d'affiler, ca peut donner des effets assez interessants du genre oublier les '\n' sur tout les printf et avoir une longue tres longue chaine de caractere qui va s'afficher au return du main.
    Pour tester:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     #include <stdio.h>
     #include <stdlib.h>
     
     int main()
     {
       printf("Salut");
       printf(" comment");
       printf(" vas");
       printf(" tu?");
       sleep(5);
       printf("\n");
       return (0);
    }
    A ta connaissance ?

    le "\n" est en aucun cas la fin de bufferisation ou encore le vidage de la mémoire tampon ... Pour vider la mémoire tampon je connais fflush.
    Le "\n" est uniquement un saut de ligne.

    Faut pas non plus dire n'importe quoi ...
    Je sais pas ou tu as vu ça mais j'aimerais bien avoir la source.

    Pour infos :

    \n
    passe à la ligne
    \r
    renvoie le curseur en début de ligne
    \t
    tabulation
    \v
    tabulation verticale
    \b
    retour en arrière
    \a
    « alerte » (sonore ou visuelle)
    Et encore si tu as des doutes : http://compute.cnr.berkeley.edu/cgi-...n-cgi?printf+1

    ce qui revient au man printf
    ---
    Overcrash

    Je ne lis pas les codes qui ne sont pas indentés.
    Merci de les messages utiles en cliquant en bas à droite du message

    Bloqué par le firewall pour accéder au chat ? Essayez avec l'adresse en direct : http://87.98.168.209/

  13. #13
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    En fait, il y a trois modes de fonctionnement pour les flux d'E/S :
    1- non tamponnées : la transmission se fait aussi tôt que possible
    2- totalement tamponnées : la transmission est faite lorsque le tampon est plein
    3- tamponnées par ligne : la transmission est faite lorsque le tampon est plein ou lorsqu'un '\n' est trouvé dans le flux

    Les flux stdout et stdin, par défaut, ne sont totalement tamponnés que dans le cas où ils correspondent à un dispositif non interactif. Dans le cas de la console, cela laisse à l'implémentation les choix 1 et 3. Et si la console est tamponnée il ne reste que le choix 3 : la transmission se fera bien sur un '\n'

Discussions similaires

  1. CSS ne fonctionne plus depuis le passage au XHTML
    Par Cr@zyDeep dans le forum Mise en page CSS
    Réponses: 6
    Dernier message: 27/09/2005, 14h42
  2. recordcount ne fonctionne plus
    Par Oluha dans le forum ASP
    Réponses: 1
    Dernier message: 26/09/2005, 14h24
  3. Réponses: 2
    Dernier message: 22/06/2005, 13h07
  4. mes requetes sous access ne fonctionnent plus
    Par trialrofr dans le forum ASP
    Réponses: 12
    Dernier message: 04/12/2004, 21h52
  5. [JSP][Tomcat]Changement de context -> JSP fonctionne plus
    Par mathieu dans le forum Servlets/JSP
    Réponses: 7
    Dernier message: 01/03/2004, 08h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo