découpage d'un char (C++)

découpage d'un char (C++) - C++ - Programmation

Marsh Posté le 12-05-2016 à 23:11:30    

bonjour,  
j'ai commencer depuis peu le C++ et je me suis lancer sur un petit projet, mais je suis aussi (et surtout ) tomber sur un "bloquage" qui est pourtant tout con ^^
il s'agit de découper une variable CHAR
en gros voila la portion de codes utile pour se cas :  

Code :
  1. char chars[]={'GT','CSS','etc', ..... ,'voila','fin'}; // en vrais on s'en fou du contenu ...
  2. cout << "Nombre de tread: " << endl;
  3. cin >> tread;
  4. int decoupage;
  5. decoupage = 59/tread;


 
en gros, selon le nombre de "tread" utiliser (il s'agit de calcule en parallèle ^^ ) je voudrais découper la chaine de 59 valeurs (char) en part (presque) égale, et faire un truc du genre :
5 tread, donc 59/5=11.8, sa met 12 morceau dans le 1er, 12 pour le 2eme etc.. et le dernier se prend le reste  
 
voila, je vous remercie d'avance,  
cordialement Thomas

Reply

Marsh Posté le 12-05-2016 à 23:11:30   

Reply

Marsh Posté le 13-05-2016 à 00:15:25    

Tu devrais activer les warnings de ton compilateur... :o
C'est quoi déjà un char? Un seul caractère...

 

Si tu veux découper une chaîne de caractères (soit char chaine[]="abc"; ) c'est juste une histoire de boucle et de memcpy avec les bons offsets+longeurs. Simule le avec papier+crayon, c'est simple.


Message édité par rat de combat le 13-05-2016 à 00:19:49
Reply

Marsh Posté le 13-05-2016 à 08:29:56    

Bonjour,
Déjà merci de ton intérêt pour mon cas,
En réalité il n'y a bien que 1charecter dans le char (ce que j'ai écrit n'était qu'un exemple mal formuler je m'excuse)
 
Mon problème est qu'une partie de mon programme doit utiliser qu'une partie de cette chaîne. Un peut comme le explode de PHP mais celon un certain nombre de caractères (par groupe de 10 en gros )
 
Je connais assez peu le c++ , je suit quelques cours sur le web en même temps mais je travaille surtout avec du PHP, et la transition est assez brutale pour moi :/
 
Je vous remercie d'avance
Cordialement Thomas

Reply

Marsh Posté le 13-05-2016 à 15:25:11    

Commencer le C++ en s'attaquant à du threading, ca va piquer, oui  [:petrus75]  
 
Pars plutôt de là, pour ton problème

Code :
  1. std::vector<std::string> mesChaines { "GT", "CSS", "etc", "voila", "fin" };


 
Assure-toi que ton compilateur est bien compatible avec C++11 ou plus récent.


---------------
last.fm
Reply

Marsh Posté le 13-05-2016 à 19:32:38    

theshockwave a écrit :

Commencer le C++ en s'attaquant à du threading, ca va piquer, oui  [:petrus75]


Effectivement...  
 
J'avais pas vu qu'il est question de C++, du coup je me tais... Dans ce language il y a certainement quelque chose de mieux adapté et de plus élégant mais je ne connais pas.

Reply

Marsh Posté le 14-05-2016 à 01:37:50    

Non mais déjà la première ligne est probablement fausse:
char chars[]={'GT','CSS','etc', ..... ,'voila','fin'}; // en vrais on s'en fou du contenu ...  
en C++, 'GT' est de type char mais sa valeur est implementation defined et probablement pas ce que tu attends.
 
char chars[]={'G', T','C', 'S', 'S'};  
ça aurait bien plus de sens ici par exemple.
 
A+,


Message édité par gilou le 14-05-2016 à 01:51:36

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-05-2016 à 10:14:27    

Bonjour,
Deja merci de vos réponses,
Effectivement je commence en ayant les yeux plus gros que le ventre ^^
Pour ce qui est du char je suis d'accord qu'il y a une erreur (j'avez réécrit les lignes à  voler)  
Cette ligne ressemble plus à  
char chars[]={'G', T','C', 'S', 'S'};  
Comme le dit gilou,
Mon compilateur est effectivement régler sur "GNU g++11" , et changer avec ou sans GNU ne m'a rien changer ^^
 
Et pour ce qui est de mon problème je vais reformuler ^^
 
J'ai un  
char chars[]={'G', T','C', 'S', 'S'};  
Et je voudrai le découper en plusieurs partie,
Par exemple en 2 me donnerai
char chars1[]={'G', T'};  
char chars2[]={'C', 'S', 'S'};  
 
Voilà,  
Cordialement Thomas

Reply

Marsh Posté le 14-05-2016 à 12:47:47    

Bon, puisque tu insistes sur tes chars...

 
Citation :

Et je voudrai le découper en plusieurs partie,
Par exemple en 2 me donnerai
char chars1[]={'G', T'};  
char chars2[]={'C', 'S', 'S'};  


Sous cette forme là ce n'est pas possible car il faut connaître le nombre de variables à l'avance. Par contre avec du malloc()...

 

Si j'ai bien compris tu cherches un truc genre

Code :
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cmath>
  5.  
  6. using namespace std;
  7.  
  8. int main ()
  9. {
  10.    char chars[59]={'S','F','J','B','V','K','E','S','H','L','R','V','Z','B','H','H', \
  11.    'H','F','P','P','A','T','F','F','E','B','I','G','Z','Y','V','U','E','B','R''H', \
  12.    'Q','A','Z','F','Y','C','C','I','U','Y','V','L','H','K','K','B','G','H','P','I','H','A','T'};
  13.    int nb;
  14.    int lg_morceaux;
  15.    int cpt;
  16.    int i;
  17.    
  18.    cout<<"nb de morceaux?";
  19.    cin>>nb;
  20.    
  21.    if(nb<2 || nb>25) //25 pris au pif...
  22.    {
  23.        cout<<"error";
  24.        return 0;
  25.    }
  26.    
  27.    lg_morceaux=ceil(59.0/nb);
  28.    cout<<"lg_morceaux: "<<lg_morceaux<<endl;
  29.    
  30.    for(cpt=0; cpt<=59; cpt+=lg_morceaux)
  31.    {
  32.        int lg=cpt+lg_morceaux>59?(59-cpt):(lg_morceaux);
  33.        
  34.        cout<<"segment start: "<<cpt<<" long: "<<lg;
  35.        
  36.        //memory-leak, faudra évidemment garder un pointeur sur chaque ensemble de chars, c'est juste pour la démo de l'algo
  37.        //(pas envie d'écrire trop...)
  38.        char *ptr=(char*)malloc(lg*sizeof(char));
  39.        if(ptr==NULL)
  40.        {
  41.            cout<<"error";
  42.            return 0;
  43.        }
  44.        
  45.        memcpy(ptr, chars+cpt, lg);
  46.        
  47.        cout<<" contenu: ";
  48.        for(i=0; i<lg; i++)
  49.        {
  50.            cout<<ptr[i]<<" ";
  51.        }
  52.        cout<<endl;
  53.        
  54.    }
  55.    
  56.    return 0;
  57. }


Je ne parle pas C++ mais le truc compile et tourne sans warnings avec -Wall, donc ça doit être bon... Par contre faudra remplacer le 59 par une constante (c'est plus propre) et revoir la gestion d'erreurs bien sûr.

 
Citation :

Mon compilateur est effectivement régler sur "GNU g++11" , et changer avec ou sans GNU ne m'a rien changer ^^


Le C++11 c'est pour le vector-bidule dont parlait theshockwave, pas pour les char[], ça c'est du classique...


Message édité par rat de combat le 14-05-2016 à 12:58:57
Reply

Marsh Posté le 14-05-2016 à 17:18:07    

Merci de cette réponse ,
Je teste ce soir et je vous tien au courant ^^

Reply

Marsh Posté le 14-05-2016 à 20:11:46    

Citation :

J'ai un  
char chars[]={'G', T','C', 'S', 'S'};  
Et je voudrai le découper en plusieurs partie,
Par exemple en 2 me donnerai
char chars1[]={'G', T'};  
char chars2[]={'C', 'S', 'S'};  


Sauf que ça, c'est pas du C++ mais du C
En C++, tu vas travailler avec une string.

Code :
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. std::vector<std::string> split(const std::string &str, int parts) {
  5.   std::vector<std::string> svec;
  6.   svec.reserve(parts);
  7.   int partsize = str.length()/((str.length()%parts)?(parts - 1):parts);
  8.   std::size_t pos = 0;
  9.   while (parts--) {
  10.       svec.push_back(str.substr(pos, partsize));
  11.       pos += partsize;    
  12.   }
  13.   return svec;
  14. }
  15. int main(int argc, char **argv) {
  16.     const std::string sample =
  17.         "Lorem ipsum dolor sit amet, "
  18.         "consectetur adipiscing elit, "
  19.         "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
  20.         "Ut enim ad minim veniam, "
  21.         "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
  22.         "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
  23.         "Excepteur sint occaecat cupidatat non proident, "
  24.         "sunt in culpa qui officia deserunt mollit anim id est laborum.";
  25.     int chunknums = 14;
  26.     std::vector<std::string> chunks = split(sample, chunknums);
  27.     for (int i = 0; i < chunknums; ++i)
  28.         std::cout << chunks[i] << std::endl;
  29.     return 0;
  30. }


(Noter que ça marchera pas bien sur si la chaîne est plus petite que le nombre de morceaux qu'on veut la découper, mais j'allais pas filer un truc a 100% finalisé... :D)
 
Note: si j'avais un prototype
std::vector<std::string> split(std::string str, int parts);
plutôt qu'un avec un passage de paramètre par référence,
std::vector<std::string> split(const std::string &str, int parts);
ça doublerait le temps d’exécution (sur ma machine en tout cas)
Par contre le compilo semble suffisamment intelligent (g++) pour optimiser le push_back d'un objet temporaire (svec.push_back(str.substr(pos, partsize)); ) sans que j'aie besoin de faire un move pour qu'il ne fasse pas de copie (svec.push_back(std::move(str.substr(pos, partsize))); )
 
Tandis que si tu veux utiliser des char[] (comme tu en connais pas la taille au départ, ca sera des char * en fait), c'est du C et pas du C++.

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. char **split(char *str, int parts) {
  5.     char **buffers = NULL;
  6.     int len = strlen(str);
  7.     int partsize = len/((len%parts)?(parts - 1):parts);
  8.     int lastsize = len - (partsize * (parts - 1));
  9.     char **b, *p;
  10.     int size;
  11.     b = buffers = malloc(parts * sizeof(char*));
  12.     while (parts--) {
  13.         size = parts?partsize:lastsize;
  14.         p = *b = malloc(size + 1);
  15.         while (size--) {
  16.             *p++ = *str++;
  17.         }
  18.         *p = 0;
  19.         b++;
  20.     }
  21.     return buffers;
  22. }
  23. int main(int argc, char **argv) {
  24.     int i;
  25.     char sample[] =
  26.         "Lorem ipsum dolor sit amet, "
  27.         "consectetur adipiscing elit, "
  28.         "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
  29.         "Ut enim ad minim veniam, "
  30.         "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
  31.         "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
  32.         "Excepteur sint occaecat cupidatat non proident, "
  33.         "sunt in culpa qui officia deserunt mollit anim id est laborum.";
  34.     int chunknums = 14;
  35.     char **chunks = split(sample, chunknums);
  36.     for (i = 0; i < chunknums; ++i) {
  37.         printf("%s\n", chunks[i]);
  38.     }
  39.     for (i = 0; i < chunknums; ++i) {
  40.         free(chunks[i]);
  41.     }
  42.     free(chunks);
  43.     return 0;
  44. }


(la pareil, c'est pas blindé, on teste pas la valeur de retour des mallocs... mais je vais pas tout paufiner)
 
A+,


Message édité par gilou le 15-05-2016 à 16:47:11

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 14-05-2016 à 20:11:46   

Reply

Marsh Posté le 16-05-2016 à 15:06:26    

ok ok ...
 
j'avoue ne pas avoir tout compris, mais le gros est rentrer,
je croit effectivement que je vais retourner a mes petit cours pour mieu comprendre, ce cera mieu que de patauger comme je le fait ^^
 
en tout cas je te remercie gilou de m'avoir ainsi éclairé, et aussi rat de combat qui m'a donner un morceau de code qui fait EXACTEMENT ce que je cherchait ^^ ainsi qu'aux autres ;)
 
en tout cas problème régler, j'ai enfin pue avancer ^^ et même faire tourner mon morceau de programme avec du theading grâce a vous ^^,
je vous remercie encore et vous souhaite une bonne journée.
Cordialement Thomas

Reply

Marsh Posté le 16-05-2016 à 19:02:37    

Tiens, une version optimisée (memcpy), en C99:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. /* découpe la chaine str en parts morceaux, les parts-1 premières étant de taille égale maximale
  5. * et renvoie un pointeur sur les morceaux */
  6. char **split(char *str, int parts) {
  7.     int len = strlen(str);
  8.     int partsize = len/((len%parts)?(parts - 1):parts);
  9.     int lastsize = len - (partsize * (parts - 1));
  10.     char **buffers = malloc(parts * sizeof(char*));
  11.     for (int i = 0; i < parts; ++i) {
  12.         int size = (parts - i - 1)?partsize:lastsize;
  13.         buffers[i] = malloc(size + 1);
  14.         memcpy(buffers[i], str, size);
  15.         buffers[i][size] = 0;
  16.         str += size;
  17.     }
  18.     return buffers;
  19. }
  20. int main(int argc, char **argv) {
  21.     char sample[] =
  22.         "Lorem ipsum dolor sit amet, "
  23.         "consectetur adipiscing elit, "
  24.         "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
  25.         "Ut enim ad minim veniam, "
  26.         "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
  27.         "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
  28.         "Excepteur sint occaecat cupidatat non proident, "
  29.         "sunt in culpa qui officia deserunt mollit anim id est laborum.";
  30.     int chunknums = 14;
  31.     char **chunks = split(sample, chunknums);
  32.     for (int i = 0; i < chunknums; ++i) {
  33.         puts(chunks[i]);
  34.     }
  35.     for (int i = 0; i < chunknums; ++i) {
  36.         free(chunks[i]);
  37.     }
  38.     free(chunks);
  39.     return 0;
  40. }


C'est une version qui suppose que tes chaines sont des chaînes C, terminées par un 0.
 
Si tu travailles vraiment avec des buffers de caractères et non des chaînes C, c'est juste une variation sur ce thème:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. /* découpe la chaine str en parts morceaux, les parts-1 premières étant de taille égale maximale
  5. * et renvoie un pointeur sur les morceaux */
  6. char **split(char *str, int parts) {
  7.     int len = strlen(str);
  8.     int partsize = len/((len%parts)?(parts - 1):parts);
  9.     int lastsize = len - (partsize * (parts - 1));
  10.     char **buffers = malloc(parts * sizeof(char*));
  11.     for (int i = 0; i < parts; ++i) {
  12.         int size = (parts - i - 1)?partsize:lastsize;
  13.         buffers[i] = malloc(size);
  14.         memcpy(buffers[i], str, size);
  15.         str += size;
  16.     }
  17.     return buffers;
  18. }
  19. int main(int argc, char **argv) {
  20.     char sample[] =
  21.         "Lorem ipsum dolor sit amet, "
  22.         "consectetur adipiscing elit, "
  23.         "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
  24.         "Ut enim ad minim veniam, "
  25.         "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. "
  26.         "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
  27.         "Excepteur sint occaecat cupidatat non proident, "
  28.         "sunt in culpa qui officia deserunt mollit anim id est laborum.";
  29.     int chunknums = 14;
  30.     char **chunks = split(sample, chunknums);
  31.     int len = strlen(sample);
  32.     int partsize = len/((len%chunknums)?(chunknums - 1):chunknums);
  33.     int lastsize = len - (partsize * (chunknums - 1));
  34.     for (int i = 0; i < chunknums; ++i) {
  35.         int size = (chunknums - i - 1)?partsize:lastsize;
  36.         fwrite(chunks[i], size, 1, stdout);
  37.         fwrite("\n", 1, 1, stdout);
  38.     }
  39.     for (int i = 0; i < chunknums; ++i) {
  40.         free(chunks[i]);
  41.     }
  42.     free(chunks);
  43.     return 0;
  44. }


 
A+,


Message édité par gilou le 16-05-2016 à 19:17:04

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed