alf a écrit 255 commentaires

  • # Wikibooks != wikipen

    Posté par  . En réponse au journal wiki : créer un livre de fiction. Évalué à 2.

    La discussion de ce qui a sa place sur Wikibooks a eu lieu de nombreuses fois. Même si certains contours ne sont pas très bien définis ou sont encore mouvants, en ce qui concerne les oeuvres de fiction, la réponse a depuis le début été : PAS SUR WIKIBOOKS. Les personnes qui posent la question sur le Bistro sont (poliment) redirigées vers d'autres sites, le plus souvent vers Wikipen ( http://fr.wikipen.org/wiki/Accueil ). Ce site ne fait certes pas partie des projets Wikimédia, mais est animé par de nombreux contributeurs des projets wikimédia (wp et wb principalement, évidemment, mais pas seulement)...

    Les critères d'admissibilité (pour Wikibooks fr, tout du moins) sont encore à l'état de brouillon ( http://fr.wikibooks.org/wiki/Wikilivres:Crit%C3%A8res_d%27ad(...) ), mais la règle est claire :
    Wikilivres accueille des ressources pédagogiques. Sont donc exclus les contenus suivants :

    1. Les textes originaux de fiction ou littéraires. Notez que ce genre de contenu est le bienvenu sur des sites comme Wikipen.
    2. Les textes de recherche. Wikilivres n'est pas un site où publier les résultats de recherches, des idées, des théories, etc.
    3. Les textes d'opinion. Les textes se doivent d'être neutres, aucun texte partial n'est accepté.
  • [^] # Re: On m'aurait mentit ?

    Posté par  . En réponse au journal la vaccination GPL vs la liberté total BSD : le cas du drivers atheros. Évalué à 7.

    En droit d'auteur, c'est le contraire ! L'auteur dispose de tous les droits sur son oeuvre et est seul capable de décider ce que peut en faire autrui. Donc, si l'auteur ne précise pas explicitement que tu as le droit de redistribuer son oeuvre / code source sous une autre licence que celle qu'il a choisi, tu ne peux pas le faire.

    La BSD n'autorisant pas explicitement de redistribuer sous une autre licence un code initialement distribué sous licence BSD , la question est réglée.
  • [^] # Re: C'est pour quoi faire, au fait, les machines à voter ?

    Posté par  . En réponse au journal Machines à voter : le test. Évalué à 1.

    Le seul argument en faveur de ces machines est l'absence de volontaires dans certaines communes, ce qui obligerait parfois les maires à payer des employés municipaux pour faire le travail.

    D'après une doc du Forum des Droits sur Internet, sur une élection présidentielle, les frais liés à la tenue des bureaux de vote ne couvrent que 8% du coût global de l'élection, loin derrière les 35% liés aux envois des programmes par courrier postal... L'argument du coût n'est donc pas le bon.
  • [^] # Re: C'est pour quoi faire, au fait, les machines à voter ?

    Posté par  . En réponse au journal Machines à voter : le test. Évalué à 1.

    Les gains du vote électronique pourraient être dans le vote à distance...

    ... sauf que ledit vote par correspondance a été aboli par l'assemblée nationale à l'unanimité en 1975 à cause des fraudes (mais redu possible depuis pour les Français à l'étranger).
  • [^] # Re: au hasard ...

    Posté par  . En réponse au message deux char pour faire un short. Évalué à 1.

    Ensuite, tu peux également utiliser une tableau "unsigned char tableau [2];" et déposer tes valeurs directement dedans avec tableau[0] et et tableau[1]. Au moins tu es sûr que tes valeurs sont concaténées en mémoire, et dans le bon ordre. Sachant cela, tu n'as plus qu'à les lire comme s'il s'agissait d'un short, en utilisant un transtypage (cast) :

    short result = *(short *)tableau;

    Arg !
    J'avais pas fait gaffe à première lecture, mais quand même...
    short result = 0;
    unsigned char *p = (unsigned char*) &result;
    p[0] = 0xaa;
    p[1] = 0xaa;

    Ce code n'a aucun problème d'alignement (ce qui est correctement aligné pour un truc quelconque qui n'est pas un champ de bits sera toujours correctement aligné pour un unsigned char). Par contre, la valeur de result reste dépendante de CHAR_BITS.

    (il y a plantage éventuel suivant sizeof(short) qui peut être égal à 1, mais un if ou une bête boucle peut suffire à gérer correctement tous les cas)
  • [^] # Re: Ahem...

    Posté par  . En réponse au journal Machines à voter : le test. Évalué à 2.

    Et si la batterie interne foire, prece que la machine a vécu 10 ans en n'étant utilisée que 2 à 10 jours par an, les votes ne sont pas perdus, j'espère ?

    Mis à part la boulette où il fallait lire "parce que" en lieu de cette erreur malencontreuse, je précise ceci: j'ai dit "10 ans" parce qu'il faudra bien ça pour amortir les coûts de la machine vu le peu de jours de vote par an (ou même de consultations locales) où elle serait utilisée. Mais c'est une estimation à la louche, à préciser...
  • # Ahem...

    Posté par  . En réponse au journal Machines à voter : le test. Évalué à 4.

    Bien que totalement non-spécialiste en matière de sécurité, j'ai un peu lu Bruce Schneier, et retenu quelques principes. Certes, je sais qu'il vaut mieux pas de sécurité du tout plutôt qu'une illusion de sécurité donnée par un système plein de failles.
    [...]
    Je ne sais pas ce que de vrais spécialistes de la sécurité penseront de ma petite inspection, et de ce que j'ai éventuellement pu oublier. En tous cas, j'ai eu l'impression que la sécurité des machines était plutôt bien conçue.

    Ok, la boiboîte est fermée à clé. A part ça ?

    Quand on touche l'écran un peu n'importe comment, un seul vote au maximum s'enregistre, et en tous cas rien ne plante.

    C'est bien le moins qu'on puisse attendre d'un machin pareil...

    Si on débranche l'alimentation, la machine ne reboote pas, car une batterie interne prend le relais.
    Et si la batterie interne foire, prece que la machine a vécu 10 ans en n'étant utilisée que 2 à 10 jours par an, les votes ne sont pas perdus, j'espère ?
    Et (tiens, je ne me souviens pas avoir déjà vu cette objection quelque part, à creuser...) si ça flanche en plein milieu de l'enregistrement d'un vote, comment on sait s'il a bien été enregistré, et si on doit ou non demander à l'électeur de recommencer ?

    la préfecture prend les choses en main et procède, soit à un contrôle approfondi, soit à un nouveau vote

    Et le "contrôle approfondi", c'est quoi ? Regarder les logs et demander à chaque votant si le nom de candidat/liste qui a été enregristré était bien celui pour lequel il a voté ?

    Il pourrait, à mon avis, y avoir une manière de frauder qui consisterait à fabriquer une clé électronique. En effet, si le lecteur de clé se situe sur le bureau du président, la machine possède également un port clé.
    Tiens... Le port qu'ils utilisent, c'est un truc propriétaire ou non ?
    Ca me fait penser à un article de MISC parlant d'une possibilité de faire un dump de la mémoire d'un PC en branchant dessus un périphérique Firewire "maison" (ou USB, mais je crois bien que c'est Firewire). Leur machin est protégé contre ça ?

    Et un Tempest, c'est prévu pour ?
  • [^] # Re: Comportement non défini en C

    Posté par  . En réponse au message deux char pour faire un short. Évalué à 1.

    L'opération "a << b" est indéfini en C si b est plus grand que le nombre de bits de a.

    Plus grand ou égal. D'où un problème (en C du moins).

    Mais il y a autre chose. Si le type char est signé (en C, c'est possible, et même courant. En C++, à voir, mais je suppose que c'est pareil.), et si CHAR_BIT vaut 8 (ce qui est garanti par POSIX, si je ne m'abuse), alors la valeur maximale pour un char est 127.

    Or 0xaa == 170.

    D'où débordement, sur un type signé, et donc comportement indéfini (en C toujours).
    En utilisant unsigned char à la place, il n'y a plus débordement à ce niveau, et a vaut bien 170.

    Ensuite, j'ai un doute et la flemme de resortir la norme, mais il me semble que les opérandes de << subissent la promotion entière. Donc la valeur de a est convertie en int avant qu'on calcule le a << 8. Pasunsigned int.

    Et 170 << 8, hors débordement, ça fait 170 * 2^8 = 43520 (et donc 43690 avec le + b). Si ton int est sur plus de 16 bits, ça passe. Puis tu stockes le tout dans un short. Si short fait aussi plus de 16 bits, ça passe.

    Si short et/ou int est signé et fait 16 bits, alors je rappelle que la valeur max d'un type signé sur 16 bits est 32767... i.e. il y aura débordement (et donc comportement indéfini pour ceux qui suivent).

    D'où, sauf erreur de ma part, une solution :
    unsigned char a = 0xaa;
    unsigned char b = 0xaa;
    unsigned short s1 = a << 8 + b;
    /* si jamais je me suis trompé sur la promotion entière */
    unsigned short s2 = (((unsigned int) a) << 8) + b;


    Vu tous les comportements indéfinis rencontrés en chemin, je ne prends pas la peine de chercher pourquoi tu as 0xa9aa plutôt que -1, 42 ou SIGSEV...
  • [^] # Re: Traduction n'est pas forcément trahison, mais des fois...

    Posté par  . En réponse à la dépêche Montrez-nous le code !. Évalué à 3.

    Merci bien de m'avoir corrigé.
  • [^] # Re: Traduction n'est pas forcément trahison, mais des fois...

    Posté par  . En réponse à la dépêche Montrez-nous le code !. Évalué à 1.

    Quand on prétend, on dit clairement, sans ambiguïté et avec la volonté de se faire parfaitement comprendre. Quand on insinue, on parle a mots couverts, pour qu'un message soit compris par certains, généralement ciblés, mais par forcément par tous. Insinuer est en général lié a un contexte qui lève l'ambiguïté du message pour ceux ayant les informations nécessaires pour le comprendre.
    Merci de la précision. C'est bien ce que je pensais, mais sans dictionnaire, ma certitude n'était pas totale.

    D'ailleurs "request" se traduit sans aucun doute par "demande". C'est pas du SQL ici.
    Pour le "request", j'y avais pensé, puis je me suis dit qu'en terme juridique ça pourrait peut-être passer. Et pas de dictionnaire sous la main, tout ça.

    Au passage, je garde le lien, ça m'a l'air intéressant :)
  • [^] # Re: Traduction n'est pas forcément trahison, mais des fois...

    Posté par  . En réponse à la dépêche Montrez-nous le code !. Évalué à 5.

    Prétendre et insinuer, n'est-ce point à peu près la même chose ?
    Pour "insinuer", ok, j'admettais que ça passait dans ce contexte, et que je n'avais pas de dico sous la main pour vérifier.

    Let's make this crystal clear peut se traduire littéralement par "Clarifiez nous le cristal".
    Moui. Si tu considères "this" comme COD et "crystal clear" comme attribut du COD, effectivement, et à l'erreur de conjugaison près, ça serait ça. Mais "crystal clear" est une expression tellement commune, et le reste du texte ne parlant pas de cristal, on peut difficilement faire autrement que comprendre que c'est "this" le COD et "crystal clear" l'attribut du COD. Donc, quitte à être littéral : "Rendons ceci clair comme le cristal".

    Eclaircissez nous le mystère n'est pas si mauvais que cela vu qu'il y a un mystère autour des insinuations de Steve Ballmer ! En montrant le code, il n'y aura plus de mystère.
    Certes, je suis bien d'accord qu'on peut dire que MS fait un mystère autour des brevets posant problème, mais le texte original ne le dit pas. D'où ma remarque.

    Pour ce qui est de faire avancer le débat, je ne l'ai pas prétendu, je voulais juste réagir sur des erreurs de traduction, tout comme d'autres postent des commentaires pour corriger des fautes de grammaire/frappe/orthographe. Il ne faut pas s'énerver non plus pour si peu... (et puis, j'aime bien "pinailler" pour des traductions, ça change un peu des fautes de frappe)
  • # Traduction n'est pas forcément trahison, mais des fois...

    Posté par  . En réponse à la dépêche Montrez-nous le code !. Évalué à 6.

    The request is simple, since you, Microsoft, claim to be so sure of yourself: Show Us the Code. Show us the Code and Show Us the Patents. Lets make this crystal clear.
    La requête est simple, puisque vous, Microsoft, insinuer être sûr de vous : montrez-nous le code, et les brevets en question. Éclaircissez le mystère.

    Je n'ai pas mon Harrap's sous la main, mais il me semble que "to claim" se traduit par "prétendre" et non "insinuer" (bien que, dans le contexte, ça puisse passer, j'ai comme un gros doute).

    Et pour ce qui est de "Let[']s make this crystal clear", il y a deux choses :
    - traduire un "nous" par un "vous" est un peu fumeux ("let's" étant la contraction de "let us"). Le texte de départ est suffisamment "impératif" pour ne pas en rajouter.
    - "mystère" ? Ca sort d'où ? Qui parle de mystère ?
    "Mettons les choses au clair une fois pour toutes" ou "Clarifions les choses pour de bon" me semblerait plus proche du texte original. On garde la première personne du pluriel, la notion de "clarifier", ainsi que l'insistance du "crystal clear". Ce n'est pas génial non plus, mais c'est plus proche.
  • [^] # Re: Taille de pile

    Posté par  . En réponse au message comportement 'aléatoire'. Évalué à 1.

    Je ne vois pas en quoi le fait que la mémoire d'un objet static ne soit pas désallouée est un problème. C'est la définition même de static qui veut ça !

    Une variable locale statique peut être utile. Mais il faut savoir quand l'utiliser et quand ne pas l'utiliser...

    Si tu veux un problème lié aux variables statiques, il y en a un autre, plus grave : pas de pas de réentrance. I.e. pas de récursivité possible (tout du moins de manière "classique"), marche pas avec le multi-thread...
  • [^] # Re: un petit endien .. nagawika ...

    Posté par  . En réponse au message Lecture de fichier binaire. Évalué à 1.

    Je ne sais plus comment il joue avec le bit de poids fort lorsqu'il passe d'un signé à un non-signé plus long,

    En C, les conversions se font toujours en essayant de préserver la valeur. Si la valeur de départ "tient" dans le type d'arrivée, alors elle est conservée telle quelle. Sinon, ça dépend... Dans le cas d'une conversion vers un type non signé, la conversion se fait modulo (le nombre maximal représentable par ce type) + 1 (i.e. UINT_MAX +1 dans le cas d'unsigned int).

    Donc, si la valeur de v est négative, la conversion en unsigned int se fera avec un changement de valeur modulo UINT_MAX +1. Sinon, comme on a par ailleurs SHORT_MAX <= INT_MAX <= UINT_MAX, la valeur après conversion sera identique. Pas besoin de jouer avec les opérateurs binaires...

    En passant, il sert à quoi ton assert ?
  • # Commentaires

    Posté par  . En réponse au message Lecture de fichier binaire. Évalué à 1.

    size=2;
    ptr=(short int *)malloc(size);
    • Le cast de la valeur de retour de *alloc est inutile et peut même cacher l'oubli d'inclusion de stdlib.h. A éviter.
    • Tu n'as pas vérifié que ptr n'est pas nul...
    fread(ptr,(size_t)size,1,data_file);
    • Le cast en size_t est inutile, la conversion se faisant implicitement lors de l'appel de fread.
    • Tu as oublié de vérifier la valeur de retour de fread, donc tu ne sais pas si tu as effectivement lu ce que tu voulais, ou non. Il a pu y avoir une erreur d'I/O...
    • L'utilisation d'une valeur "size" est douteuse si ton code ne fait que ça... Evite, car ça risque d'être source de bugs (pas portable, valeur modifée en cours de programme...).
    printf("%02X ",*((short int *)ptr));
    Comme dit par ailleurs, c'est horrible.
  • [^] # Re: Je ne pense pas que ce soit l'erreur...

    Posté par  . En réponse au message cc, as et ld. Évalué à 1.

    Certes, mais note aussi la présence du point-virgule dans le code posté, qui elle est une erreur de syntaxe.
  • # Débordement

    Posté par  . En réponse au message cc, as et ld. Évalué à 1.

    long int factorielle(int n)
    {
        if (n<2)
            return 1;
        else
            return n*factorielle(n-1);
    }
    Le typage est risqué... Pour les grandes valeurs de n, ton programme n'est plus portable. Explications :
    • n est de type int, factorielle(n - 1) est de type long, donc le produit sera de type long (conversions arithmétiques usuelles, 3.6.1.8 du n1124).
    • Lorsque n est grand, au point que factorielle(n - 1) est supérieur à LONG_MAX / n, le produit est donc supérieur à LONg_MAX et déborde donc le domaine de valeurs de long.
    • Le type long est signé, le débordement cause donc un comportement défini par l'implémentation (6.3.1.3 du n1124).
    En langage C, un "comportement défini par l'implémentation" doit être documenté par ton implémentation (compilateur et/ou libc), mais peut être différent d'une implémentation à l'autre (une autre version du même compilateur étant une autre implémentation, comme le même compilateur avec des options différentes).
      En utilisant un autre type (comme unsigned long, voire long long ou stdint.h si tu l'as sous la main), tu augmentes le domaine où ta fonction est utile, mais la gestion d'erreur doit être implémentée, quel que soit le type.
        Proposition (non testée) :
        #include <limits.h>
        
        /*
         * Retourne la factorielle de n.
         * Si la valeur de n! depasse LONG_MAX, la fonction renvoie -1.
         */ 
        long int factorielle(int n)
        {
            long res = 1;
            if (n >= 2)
            {
                res = factorielle(n - 1);
                if (LONG_MAX / n < res || res == -1)
                {
                    /* debordement */
                    res = -1;
                }
                else
                {
                    res *= n;
                }
            }
            return res;
        }
        J'ai juste fait la correction de l'implémentation, mais l'algorithme de calcul présenté ici (application naïve de l'algorithme par récursion non terminale) est largement sous-optimal. Je suppose que le côté algorithmique sera étudié séparément...
      • [^] # Re: Porpagation facilité de la culture

        Posté par  . En réponse au journal Modèle économique et justification de l'art libre ?. Évalué à 3.

        Les avantages ils sont surtout pour les consomateurs de culture, car cela permet de diffuser, à l'aide de l'internet, à un très grand nombre. C'est mieux pas parceque cela permet d'avoir accès à de la culture à moindre frais, mais parceque cela permet d'avoir accès à une quantité plus importante de contenus plus diversifiés.

        Bel exemple de pollution de l'esprit par l'"industrie de la culture" (beurk, je n'aime pas cette expression), même parmi ceux qui y sont opposés...

        Merci de parler de spectateurs et d'oeuvres. On aura beau dire, j'ai du mal à me faire à l'idée que "Candide" (parmi tant d'autres) n'est qu'un "contenu" à "consommer", et non une oeuvre à lire, à apprécier, critiquer, qui fait réfléchir et permet de regarder le monde d'un oeil nouveau.

        Ca peut avoir l'air simpliste, mais les glissements de vocabulaire de ce genre sont en soit une défaite de la Culture (oui, j'ose la majuscule, diantre !).
      • [^] # Re: Pas beaucoup plus simple...

        Posté par  . En réponse au message saisie de chaine et correction d'erreur autonome. Évalué à 2.

        isdigit(-250) : La réponse est positive.

        Dixit 7.4p1 :
        The header <ctype.h> declares several functions useful for classifying and mapping characters.168) In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

        Donc:
        - Si EOF ne vaut pas -250 sur ton implémentation, alors tu viens de tester un comportement indéfini.
        - Si EOF vaut -250, alors ton implémentation est buggée.

        Je plaide pour la première possibilité (J'ai du mal à croire que la libc d'OpenBSD puisse être aussi buggée pour renvoyer vrai pour EOF) (et j'ai aussi du mal à croire qu'EOF puisse valoir -250, c'est plus probablement -1).
      • [^] # Re: Type struct != type pointeur

        Posté par  . En réponse au message problème de struct et d'alignement. Évalué à 3.

        tes deux malloc utilisent donc le sizeof de ces pointeurs (soit 4 octets sur une machine 32 bits)
        La taille d'un pointeur n'est pas forcément 4 octets, même si c'est usuel sur les architectures 32 bits (au regard de la norme C, ça peut être 1, 2, 8, 15...).
        Tu pourrais corriger rapidement avec "malloc(sizeof(&Doc))" pour avoir la taille réellement nécessaire; mais je trouve que ça fait beaucoup de circonvolutions et que ça embrouille le cerveau.
        Petite erreur: "*doc". "&Doc" ne compilera pas (on ne peut prendre l'adresse d'un type).
        Définis plutot tes types de structure en tant que structure ("typedef struct {...} Doc" au lieu de "*Doc") et déclare des variables explicitement pointeurs
        (Doc *doc, Pos *cur;), ce sera plus clair.
        C'est une question de style (voir mon autre post plus bas)...
      • # Erreur de typage et malloc

        Posté par  . En réponse au message problème de struct et d'alignement. Évalué à 3.

        #include <stdio.h>;
        Le point-virgule est en trop.
        typedef struct {
            int row;
            int col;
        } *Pos;
        Tu définis le type Pos comme pointeur sur une structure anonyme (on va dire "aPos").
        typedef struct {
            /*...*/
        } *Doc;
        Idem pour Doc.
        int main(int argc, char *argv[])
        {
            Doc doc = malloc(sizeof(Doc));
            Pos cur = malloc(sizeof(Pos));
        
        Deux erreurs :
        1. Il faut vérifier le retour de *alloc ;
        2. sizeof(Doc) retourne la taille du type Doc, i.e. pointeur sur la structure anonyme "aDoc". Or, ce que tu veux, c'est allouer un espace mémoire suffisant pour une structure "aDoc".
        Il fallait donc faire soit (code non testé) :
        typedef struct {
            int row;
            int col;
        } aPos;
        
        typedef aPos *Pos;
        
        /*...*/
            Pos cur = malloc(sizeof(aPos));
        Mais cette solution demande de redéfinir tes structures de données, donc c'est assez intrusif (peut-être avais-tu une bonne raison pour laisser le type structure anonyme). Il y a donc une autre solution, qui es tà la fois plus simple et plus maintenable :
            Pos cur = malloc(sizeof *cur)
        Avec cette dernière, sizeof *cur détermine la taille correcte, quel que soit le type de cur, ou la manière dont il a été défini (*).
            cur->;row = 1;
        Erreur de syntaxe, ton programme ne devrait même pas compiler (ou alors le point-virgule est arrivé là durant le copié-collé ?).
          (*)Bon, à l'exception d'un type incomplet où la définition de la structure ne serait pas visible.
        1. [^] # Re: Pas beaucoup plus simple...

          Posté par  . En réponse au message saisie de chaine et correction d'erreur autonome. Évalué à 2.

          moi perso, j'aime pas ecrire '\0', j'utilise NULL, ou carrement 0, mais ca c'est une question de gout je pense.
          Pour '\0' et 0, c'est en effet histoire de goût. Pour NULL, c'est une erreur, car c'est une constante de type pointeur.

          La macro NULL peut en effet être définie par 0, auquel cas tu n'as pas de problème, mais aussi par (void *) 0, auquel cas tu fais alors une conversion d'une valeur de type pointeur en un type entier, ce qui est implementation-defined. Peu dangereux en pratique, mais autant utiliser les bons types dès le début.
        2. # Pas beaucoup plus simple...

          Posté par  . En réponse au message saisie de chaine et correction d'erreur autonome. Évalué à 5.

          Si j'ai bien compris, tu veux tolérer la présence de caractères non numériques dans la chaîne, en les effaçant avant de passe à strtoul. Ok, pourquoi pas. Comme tu veux traiter un nombre entier positif ou nul, c'est assez simple (pour les flottants, je te dis pas ;) ).
            Premier truc, pour ta boucle de copie, la norme C garantit que '1' == '0' + 1, '2' == '0' + 2... (cf. 5.2.1p3 du n1124 :
            In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
            ). Donc tu n'as pas besoin de switch, un if (c >= '0' && c <= '9') est suffisant. Et, encore mieux, isdigit fourni par l'en-tête ctype.h.
              Deuxième truc : for(i=0;i<strlen(buffer);i++) Il y a de fortes chances que strlen soit appelée à chaque itération, à moins que le compilo arrive à se prouver que tu ne modifies pas le contenu de buffer à l'intérieur de ta boucle (ce qui n'est pas gagné). Il est mieux de faire :
              size_t  len = strlen(buffer);
              for (int i = 0; i < len; i++)
              {
                      /* ... */
              }
              Enfin, pour strtoul, j'ai un doute en voyant tes bouts de code. Le premier paramètre est une chaînes de caractères, donc un char*. Si buffer2 est de ce type, ou un tableau défini par quelque chose comme char buffer2[N], alors le & est une erreur :
              #include <stdlib.h>
              char tab[50] = "a";
              unsigned long i = strtoul(tab, NULL, 10);   /* pas de '&' */ 
            1. [^] # Re: base de la programmation

              Posté par  . En réponse au message Question pour C gourou !. Évalué à 2.

              Dans mes fichiers, les données sont toujours exactement les memes. Donc pour fgets ca ne doit pas poser de problemes pratiques normalement, idem pour sscanf (ceci dit merci d'avoir soulevé le probleme potentiel).
              Ca ne pose pas de problèmes, jusqu'à ce que ça en pose... Loi de Murhpy, tu connais ?
              fct(&x[100000]) est effectivement faux, mais si je fais fct(x), j'envoie une copie de la structure et non un pointeur non ?
              Avec :
              #define N 1000
              struct T {
                  int n;
              }
              
              void struct g(struct T *p) { /* .... */ }
              
              void f(void)
              {
                  struct T mavar[N];
                  g(mavar); /* correct */
                  g(&mavar[0]); /* correct, équivalent à la première ligne */
                  g(&mavar[N/2]): /* correct aussi */
              }
              mavar est un tableau de N structures. En C, lorsqu'on passe un tableau en paramètre à une fonction, il est automatiquement converti en un pointeur sur le type de base du tableau, pointant sur le premier élément. Donc, dans le premier appel à g, mavar est converti en struct T*, de valeur &mavar[0]. Les deux premiers appels à g sont donc équivalents. Le troisième est là pour te montrer que tu peux passer un pointeur vers n'importe quel élément du tableau (il faut juste faire attention à bien rester entre les bornes 0 -> N-1). Dans cet exemple, p sera un pointeur vers le 501e élément de mavar.
                Note que, dans g, tu peux toujours utiliser la notation tableau sur le pointeur p, pour accéder à d'autres éléments :
                #include <stdlib.h>
                void struct g(struct T *p) 
                {
                    if (p != NULL)
                    {
                        /* les trois lignes suivantes sont équivalentes */
                        printf("a: %d\n", (*p).n);
                        printf("b: %d\n", p->n);
                        printf("c: %d\n", p[0].n);
                
                        /* la suite suivante ne peut marcher que 
                         * si p pointe dans un tableau, et 
                         * sur autre chose que le dernier élément 
                         */
                        printf("d: %d\n", p[1].n);
                    }
                }
                Comme on ne peut passer vraiment un tableau en paramètre à une fonction (à cause de la conversion implicite en pointeur), il faut passer à la fonction g la taille du tableau, i.e. le nombre d'éléments accessibles à partir de *p.
                void struct g(struct T *p, size_t s) 
                {
                    if (p != NULL && s > 0)
                    {
                        for (int i = 0; i < s; i++)
                        {
                            printf("p[%u].n = %u\n", i, p[i].n);
                        }
                    }
                }
                Ainsi g sait jusqu'où elle peut aller (dans mon exemple, le test "s > 0" est inutile, vue la construction de la boucle, mais dans le cas général il est bon de faire le test).
                  Pour ton problème, si tu veux avoir un seul tableau pour toutes les données de tous les fichiers, je pense que tu peux faire quelque chose comme ça :
                  1. tu créés ton tableau à N éléments par malloc ;
                  2. tu passes à ta fonction un pointeur vers le premier élément, la taille N, et le nom du fichier (que tu détermines comme tu veux) ;
                  3. la fonction lit ce qui se trouve dans le fichier, à hauteur de N lignes, et les place dans le tableau ;
                  4. la fonction renvoie le nombre de lignes lues (avec peut-être un code d'erreur négatif pour indiquer si elle s'est arrêtée à N, et qu'il y a peut-être d'autres lignes encore dans le fichier) ;
                  5. la fonction principale reçoit ce nombre de lignes (disons n), puis rappelle la fonction de lecture sur le n+1è élément du tableau, en lui passant N-n comme limite (les erreurs "à un près" sont classiques dans ce genre de travail sur les tableaux, vérifie mes calculs sur le papier avant de coder (et puis c'est toujours un bon exercice)).
                  Les étapes 2 à 5 sont à faire en boucle, jusqu'à ce que tu ais lu tous tes fichiers.
                    Je te passe les contrôles d'erreur habituels, c'est juste une idée d'algo que tu peux utiliser, à ajuster en fonction de tes besoins.
                  1. [^] # Re: base de la programmation

                    Posté par  . En réponse au message Question pour C gourou !. Évalué à 2.

                    - Je passe sous visual C++ et là ca compile, mais ca plante lorsque le tableau dépasse 10000 lignes... j'augmentes logiquement le nombre de lignes 30000 et ca plante sans raison valable.

                    Comme je l'ai dit plus bas, la raison valable est que 30000 lignes, ça fait environ 1,5 Mo (en supposant une cinquantaine d'octets par structure), et que tu alloues tes scructures sur la pile. Une implémentation est libre de refuser un tel code (de tête, la limite minimale imposée par la norme doit être autour de 65 Ko, à moins que je mélange avec autre chose). Passe par malloc quand tu as besoin d'autant de mémoire.