Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème avec rename

    20 juillet 2006 à 21:28:28

    Salut,
    J'ai fait un code pour renomer plein d'image en même temps avec un programe, mais j'ai une petite erreur de compilation, voici mon code :
    #include <stdlib.h>
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
    long i = 00427;
    long num1 = 100;
    long num2 = 1575;

     

    while (num2 != 1702)
    {
        i++;
        num2++;

        rename("/home/luc/Photo/2006/00renomer/%ld_%ld.JPG", "/home/luc/Photo/2006/00renomer/%ld.JPG", num1, num2, i);
    }
    }


    Il y a une erreur a la logne 17 sur le rename("/hom...
    voici l'erreur :
    /home/luc/C/renomerphoto.c:17: erreur: too many arguments to function ‘rename’

    Amicalement
    LuC
    • Partager sur Facebook
    • Partager sur Twitter
      20 juillet 2006 à 21:31:28

      rename ne fonctionne par comme printf, elle n'a que deux arguments.
      • Partager sur Facebook
      • Partager sur Twitter
        20 juillet 2006 à 21:31:54

        Tu passes trop de variable a rename, il ne gere pas le texte formate.

        Tu dois copier l'image a renomer dans un premier tableau de char puis le nouveau nom dans un autre tableau de char et passer les deux tableaux en argument a rename
        • Partager sur Facebook
        • Partager sur Twitter
          20 juillet 2006 à 21:36:17

          o_O je n'ai pas trop compris là...
          • Partager sur Facebook
          • Partager sur Twitter
            20 juillet 2006 à 21:41:09


            rename("/home/luc/Photo/2006/00renomer/%ld_%ld.JPG", "/home/luc/Photo/2006/00renomer/%ld.JPG", num1, num2, i);


            Comme il a ete dit, rename ne fonctionne pas comme printf, il ne prend pas en charge le texte formate.

            rename prend uniquement deux parametres:
            - le nom du fichier a renommer
            - le nouveau nom a donner

            là tu lui transmets des variables en plus ce qui est en desaccord avec le prototype c'est pourquoi le compilateur te dis qu'il y a trop d'arguments

            tu peux te debrouiller avec deux tableau de char et sprintf (va voir le chapitre sur les chaines de caractere en cas)
            • Partager sur Facebook
            • Partager sur Twitter
              20 juillet 2006 à 21:51:55

              en faite ce que je doit faite c'est mettre juste un %ld au lieu de /home/luc/Photo/2006/00renomer/%ld_%ld.JPG et avant le rename je fabrique ma phrase comme je veut ?
              • Partager sur Facebook
              • Partager sur Twitter
                20 juillet 2006 à 21:55:37

                tu peux fabriquer ta chaine avec sprintf.
                ex:
                sprintf(chaine_final, "coucou %d", i);
                • Partager sur Facebook
                • Partager sur Twitter
                  21 juillet 2006 à 1:53:55

                  Citation : richidi

                  tu peux fabriquer ta chaine avec sprintf.
                  ex:
                  sprintf(chaine_final, "coucou %d", i);



                  Le stdlib.h ne sert a rien dans ce programme.
                  Bien que sizeof(int) == sizeof(long) sur de nombreuses architectures, je préfère utiliser int dans ce cas.
                  Pourquoi n'utilises tu pas num1 en dur? il n'est jamais modifié!

                  Avec snprintf plutôt, afin d'éviter des risques de segfaults, écrasement de données... par exemple:


                  #include <stdio.h>

                  int
                  main(int argc, char *argv[]) {
                      int i, num2;
                      char buf1[512], buf2[512];

                      for (i = 427, num2 = 1575; num2 <= 1702; i++, num2++) {
                          snprintf(buf1, sizeof(buf1), "/home/luc/Photo/2006/00renomer/100_%d.JPG",
                              num2);
                          snprintf(buf2, sizeof(buf2), "/home/luc/Photo/2006/00renomer/%d.JPG",
                              i);
                          rename(buf1, buf2);
                      }

                      return 0;
                  }
                  • Partager sur Facebook
                  • Partager sur Twitter
                    21 juillet 2006 à 2:43:44

                    c'est vrai quand precisant la taille de ton buff tu ne segfault pas. Mais si tu alloues correctement une variable il n'ya pas de probleme.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 juillet 2006 à 7:45:47

                      Citation : richidi

                      c'est vrai quand precisant la taille de ton buff tu ne segfault pas. Mais si tu alloues correctement une variable il n'ya pas de probleme.



                      Comment tu peux connaitre a l'avance la taille exacte de "%d %s" ? pour allouer pile poil a a l'avance ?

                      Tu prévois de la place mais tu es obligé de snprintf, car la taille tu l'as connait pas, on ne sprintf que dans des cas précis, c'est à dire jamais pour les débuts la.

                      Même snprintf il a déjà un comportement aléatoire (au niveau du size_t pour le null terminated string) alors sprintf n'en parlons pas.

                      snprintf apres un malloc (donc lorsque tu alloues dynamiquement plutôt qu'en dur dans le programme):
                      char *tada;
                      tada = malloc(sizeof(char)*53);
                      snprintf(tada, 52, "...", ...);

                      sans snprintf tu peux toujours avec un pagefault ou un écrasement.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        21 juillet 2006 à 10:14:39

                        c'est vraiment cool, sauf qu'il reste un petit problème vraiment très légé :D .
                        En faite il faut que le nom du fichier a la fin sois comme ca : 00427.JPG et avec cette manière sur certaine image ca devient 001926.JPG , il y a donc un 0 en trop au début. J'ai essayer de mettre :
                        for (i = 00428, num2 = 1575; num2 <= 3073; i++, num2++) avec les 0 a i mais ca plante a la compilation, donc pour le moment le seul moyen c'est de les mettre a 00%d.JPG mais ca repose le problème du debut o_O
                        • Partager sur Facebook
                        • Partager sur Twitter
                          21 juillet 2006 à 10:20:52

                          Citation : Luc

                          c'est vraiment cool, sauf qu'il reste un petit problème vraiment très légé :D .
                          En faite il faut que le nom du fichier a la fin sois comme ca : 00427.JPG et avec cette manière sur certaine image ca devient 001926.JPG , il y a donc un 0 en trop au début. J'ai essayer de mettre :
                          for (i = 00428, num2 = 1575; num2 <= 3073; i++, num2++) avec les 0 a i mais ca plante a la compilation, donc pour le moment le seul moyen c'est de les mettre a 00%d.JPG mais ca repose le problème du debut o_O


                          "%0nd"
                          n est la largeur du champ voulu

                          "%03d", 2 -> 002
                          "%03d", 12 -> 012

                          OK ? C'est écrit dans ton livre de C ou dans n'importe quelle référence comme http://man.developpez.com/...
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Music only !
                            21 juillet 2006 à 10:26:50

                            okai j'ai compris le principe, mais j'y met où :honte: ?

                            EDIT : en faite j'ai compris merci :D

                            EDITbis : Merci c'est vraiment éxélent comme programme, en plus ca va vachement beaucoup me servire, merci encore :D
                            • Partager sur Facebook
                            • Partager sur Twitter
                              21 juillet 2006 à 10:32:43

                              Je te relance la question....
                              Tu determines bien une taille fixe.
                              Je vais te dire pourquoi on peut passer une taille en parametre, c'est pour pouvoir copier nimporte quel caractere, car le sprintf parse la variable jusqu'a trouver un \0. et snprintf jusqu'a t_size.

                              Donc c'est pas avec snprintf ou sprintf que t'aura pile poil le minou la taille de la chaine.

                              Citation : undefined



                              #include <stdio.h>

                              int
                              main(int argc, char *argv[]) {
                                  int i, num2;
                                  char buf1[512], buf2[512]; // taille 512
                              .
                              .
                              .
                              .

                               snprintf(buf1, sizeof(buf1)-1, "/home/luc/Photo/2006/00renomer/100_%d.JPG",
                              //sizeof(buf1)-1 = 512 vu qu'on commence a partir de zero
                              snprintf(buf2, sizeof(buf2)-1, "/home/luc/Photo/2006/00renomer/%d.JPG",
                              ...
                                  }

                                  return 0;



                              Par contre la ou tu as raison c'est le debordement, ou sprintf n'est pas proteger.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                21 juillet 2006 à 11:12:04

                                Citation : richidi

                                Je te relance la question....
                                Tu determines bien une taille fixe.
                                Je vais te dire pourquoi on peut passer une taille en parametre, c'est pour pouvoir copier nimporte quel caractere, car le sprintf parse la variable jusqu'a trouver un \0. et snprintf jusqu'a t_size.
                                Par contre la ou tu as raison c'est le debordement, ou sprintf n'est pas proteger.



                                car le sprintf parse la variable jusqu'a trouver un \0. --> Tu as des \0 pour un %d ? un %p ?
                                Et le \0 pour une %s qui te dit qu'il est pas apres 150 carracteres et pas 50 ?
                                Et un %d (int) ca peut autant prendre 1 carractère que 10 (2**31) pour x86 32bits, puis ca change encore en fonction de l'architecture...

                                Y a que peu de cas ou on connait de facon SUR a l'avance la taille d'une chaine lors d'un sprintf...

                                Et snprintf il fait comme sprintf, sauf qu'il arrête la chaine à size_t (+1 avec le \0) SI jamais elle dépasse ca... Donc tu perds rien, tu protèges seulement! Et ca coute rien même si tu es sur pour le sprintf.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  21 juillet 2006 à 15:47:19

                                  quand tu sauras vraiment de quoi tu parles tu reviendras me voir hein ;)

                                  Citation : Pas de titre


                                  Et un %d (int) ca peut autant prendre 1 carractère que 10 (2**31) pour x86 32bits, puis ca change
                                  encore en fonction de l'architecture...



                                  Et alors t'es pas un boulet tu sais jusqu'a quelle valeur s'arrete ta variable d'incrementation.
                                  donc tu peux connaitre le nombre de char que va prendre la valeur.

                                  On se contrefiche des %d %g ... tout ce que tu voudras !!! car sprintf si tu le savais pas, se sert des varags pour associe par exemple ton %d au nombre en parametre.
                                  Et pour l'histoire du \0, sprintf ajoute un \0 a la fin, juste pour le fun ? nan pour marquer la fin de la chaine finale !!!

                                  cordialement
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    21 juillet 2006 à 15:52:58

                                    Citation : richidi

                                    quand tu sauras vraiment de quoi tu parles tu reviendras me voir hein ;)



                                    Tu insinues quoi ? Dit moi ou j'ai tord :-)

                                    Et toi tu me diras ou tu vois des \0 dans snprintf :-)

                                    Ceci a une importance lors qu'un strcpy, ou quand on passe un %s a sprintf.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      21 juillet 2006 à 16:07:25

                                      je sais pas si t'a deja coder des systemes de transferts par reseaux, tu envoies generalement des fichiers binaires. :lol: Wow, ces memes fichiers comportent des caracteres inimaginables !!! meme des \0 qui se trouvent pour la plupart du temps dans les headers des binaires.
                                      Toi a la reception, tu dois les stocker par les methodes que tu veux. Prenons deux fonctions de copy :
                                      - strncpy (ou le t_size marque son importance)
                                      - snprintf (idem)
                                      car ces fonctions ne se servent pas du \0 comme fin mais du nom t_size a parcourir.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        21 juillet 2006 à 16:27:33

                                        Je pense surtout que tu dis des choses érronées là. (pour pas dire fausses). Et j'ai pas aimé ce que tu as insinué en plus.

                                        Quand moi je parlais de \0 c'était pour:
                                        snprintf(bidule, taille, "%s", tada)
                                        Celui en fin de chaine dans "tada"

                                        Bref, pour détruire ce que tu viens de dire à propos du fait que snprintf et strncpy n'utilisent pas le \0:

                                        Citation


                                        Toi a la reception, tu dois les stocker par les methodes que tu veux. Prenons deux fonctions de copy :
                                        - strncpy (ou le t_size marque son importance)
                                        - snprintf (idem)
                                        car ces fonctions ne se servent pas du \0 comme fin mais du nom t_size a parcourir.


                                        (puis c'est pas t_size, c'est size_t déjà).

                                        Bidule contiendra, après l'appel du snprintf plus haut, *tada à *(tada+i) tel que ( *(tada+i) == '\0' ou i = taille )
                                        le \0 de tada est donc prit en compte.
                                        (Ce serait illogique qu'il le prenne pas en compte, je te le prouve:
                                        souvent on fait
                                        snprintf(bidule, 68, "%d %s\n", 10, tada);
                                        pour obtenir "10 suivit de tada et de \n et \0"... Tu es d'accord que le size_t on le prévoit souvent plus élevé ? Et pourtant après le \0 de tada il s'arrête... Il cherche pas a remplir bidule jusque 68 octets. C'est l'utilisation courante. Tu peux essayer.)

                                        strncpy fait attention au \0 aussi: il s'arrête de copier après \0 (contrairement à ce que tu as dit)...

                                        C'est la définition d'une chaine de caractère de finir par \0 et ca sert de règle pour toutes les fonctions dans string.h...

                                        strncpy(dst,src,5)
                                        src contient seulement "ab\0"
                                        dst contiendra "ab\0\0\0" après appel de la fonction (et pas "ab\0XY" ou XY est ce qui suit src en mémoire comme TU le dis)
                                        La règle c'est de s'arreter au \0 (ou a la taille) et de rajouter des \0 jusque fin a part s'il a été arrêté par la taille.
                                        Tu peux essayer :-).

                                        Les size_t ne font pas office de règle, seulement de sécurité.

                                        Pour les données réseaux on n'utilise pas de chaines compatibles avec les fonctions de string.h... Car on suit pas un protocole qui fait terminer par \0 obligatoirement et qui a une suite de carractères "cohérentes" (on peut retrouver un octet null(\0) n'importe ou et cie) :-)...
                                        Faut être insensé pour gérer des données a contenu aléatoire mais de tailles fixe avec les fonctions string.h...

                                        Il faut utiliser memcpy pour ignorer les \0 et gérer à l'aide de la taille.

                                        pour ce que j'ai dit sur les \0 cf --> man strncpy.

                                        Donc merci de pas embrouiller tout le monde et de provoquer des gens en disant qu'ils ne savent pas coder quand c'est toi qui est en tort...

                                        J'attend ta réponse avec impatience.
                                        Cordialement,

                                        -----------------------

                                        Vu que tu réponds pas j'ai pris le temps de te faire ca:

                                        /*Désolé pour le style gore, je suis pressé*/

                                        int
                                        main (int argc, char *argv[]) {
                                                char bidule[512];
                                                char tagada[] = "pouet\0et re pouet"; /*un \0 est ajouté apres le dernier pouet*/
                                                int i = 110;

                                                snprintf(bidule, 512, "%d \"%s\" après tagada y a pas de suite!!\n", i, tagada);

                                                printf("%s",bidule);

                                                /*on met a 0 bidule*/
                                                memset(bidule, 0, 512);

                                                strncpy(bidule, tagada, 511);

                                                printf("%s-%d-%d-%d-%d\n",bidule,bidule[5],bidule[6],bidule[7],bidule[8]);

                                                /*on met a 1 bidule*/
                                                memset(bidule, 1, 512);

                                                strncpy(bidule, tagada, 511);

                                                printf("%s-%d-%d-%d-%d\n",bidule,bidule[5],bidule[6],bidule[7],bidule[8]);

                                                return 0;
                                        }

                                        qui retourne:
                                        $ ./a.out
                                        110 "pouet" après tagada y a pas de suite!!
                                        pouet-0-0-0-0
                                        pouet-0-0-0-0

                                        Miracle :) il a pas copié l'apres \0 de tagada dans bidule comme tu disais... Il a pas ignoré le \0. Par contre il a ajouté \0 pendant size_t pour strncpy comme j'ai dit plus haut...
                                        Tu as du perdre des données quand tu faisais du réseau après les octets nuls! Ou tu as eu de la chance et tu n'en as pas eu! Ou tu confonds et tu as pas utilisé strncpy!

                                        -----------
                                        Et pour ton edit que je viens de voir:

                                        Citation

                                        Et pour l'histoire du \0, sprintf ajoute un \0 a la fin, juste pour le fun ? nan pour marquer la fin de la chaine finale !!!


                                        snprintf aussi rajoute un \0 final, la preuve j'ai pu printf.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          21 juillet 2006 à 19:38:49

                                          Citation : richidi

                                          Prenons deux fonctions de copy :
                                          - strncpy (ou le t_size marque son importance)
                                          - snprintf (idem)
                                          car ces fonctions ne se servent pas du \0 comme fin mais du nom t_size a parcourir.


                                          Faux. Elle se servent des 2. L'arrêt se fait dès qu'on a recontré un des deux critères. Par contre strncpy() ne met pas de 0 final à la déstination en cas de saturation.

                                          Tu confonds avec fwrite() / fread() (send() / receive()) qui sont effectivement indiqués pour transférer des données 'transparentes' selon le principe bien connu 'adresse, longueur' qui est plus universel que les chaines C.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Music only !
                                            21 juillet 2006 à 19:46:22

                                            Tu confonds strncpy() avec memcpy() non ? Va réviser, les fonctions de manipulation de chaine s'arrête au caractère \0, puisque la lib C utilise des chaines null-terminated.

                                            Citation : richidi

                                            quand tu sauras vraiment de quoi tu parles tu reviendras me voir hein


                                            La prochaine fois, surtout si c'est pour dire des énormités pareil, merci d'employer un autre ton...
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              21 juillet 2006 à 22:05:42

                                              Citation : remram44

                                              Tu confonds strncpy() avec memcpy() non ? Va réviser, les fonctions de manipulation de chaine s'arrête au caractère \0, puisque la lib C utilise des chaines null-terminated.

                                              Citation : richidi

                                              quand tu sauras vraiment de quoi tu parles tu reviendras me voir hein


                                              La prochaine fois, surtout si c'est pour dire des énormités pareil, merci d'employer un autre ton...



                                              Oui j'ai parlé de memcpy dans mon post :-)
                                              Puis faire le malin car monsieur a fait du réseau a coup de strncpy et que donc blabla... Tu t'es trompé de personne et je me demande toujours comment tu as fait :-P.
                                              Et j'attend des excuses de monsieur richidi :-)
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                21 juillet 2006 à 22:17:22

                                                c'est vrai que j'ai dit de la mer***.
                                                Je m'excuse ;) par contre pour les echanges de fichiers j'avais mis en place un accuse de reception (checksum)
                                                edit : j'ai utilise strncpy et le checksum me sert a renvoyer un msg SUCCESS/FAILED au serveur pour retenter l'envoi ou non du meme paquet
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  21 juillet 2006 à 22:53:48

                                                  Citation : richidi

                                                  c'est vrai que j'ai dit de la mer***.
                                                  Je m'excuse ;) par contre pour les echanges de fichiers j'avais mis en place un accuse de reception (checksum



                                                  Change pas que si tu utilisais strcpy ou sprintf (malheur), tu as du perdre des données après les octets nuls s'il y en avait.
                                                  Le checksum n'y peut rien!
                                                  Au nouvel envoie, au moment d'un octet nul, tu auras encore un checksum faux. Puis imagine le checksum contient un octet nul :p.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  problème avec rename

                                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                  • Editeur
                                                  • Markdown