Votre question

[Resolu][C++]Recup donnée dans chaine de caractere

Tags :
  • Programmation
Dernière réponse : dans Programmation
23 Avril 2006 14:45:24

Salut,

[Edit 26/04/06 : Veuillez lire la fin du topic (car le pb est pseudo résolu pour ce qui est du sujet actuel, mais le pb porte tjrs sur les données dans une chaine de caractère]

[... Ancien poste delete/edit]

Merci d'avance ;) 

Autres pages sur : resolu recup donnee chaine caractere

a b L Programmation
23 Avril 2006 15:55:48

Un truc de ce genre:
  1. char * pseudo;
  2. unsigned int longueurPseudo = strlen(buffer) - 40; // 40 caractère en dehors du pseudo si j'ai bien compté
  3.  
  4. pseudo = new char [longueurPseudo + 1];
  5. strncpy(pseudo, buffer + 21, longueurPseudo); // 21 caractères avant le buffer si j'ai bien compté
  6. buffer[longueurPseudo] = '\0';


ps: j'ai pas testé alors je ne sais pas que ça marche. :-D
23 Avril 2006 16:06:14

Ah, excuse, je me suis tromper dans l'ennoncer car je ne pensait pas que ça allait avoir de l'importance...

Le nom de caractère avant et après son vraiment aléatoire :
bla bla bla (x nombre de caractère)
Le pseudo est : PSEUDO
L'autre truc est :
bla bla bla avec x nombre de caractère.

Voilà, et j'dois récuperer le PSEUDO qui est compris entre "Le pseudo est :" et "L'autre truc est :"
Contenus similaires
a b L Programmation
23 Avril 2006 16:11:20

Ok, alors utilise la fonction strstr() pour trouver une chaine de caractère dans une autre.
23 Avril 2006 16:52:18

Bah, ma première méthode était celle ci :

  1. char *tmp1= "Le pseudo : ";
  2. char *tmp2= "L'autre machine : ";
  3.  
  4. char *buff=buffer;
  5. char *i;
  6. int j=0;
  7.  
  8. char* adresse_debut= strstr(buff, tmp1);
  9. char* adresse_fin= strstr(buff, tmp2);
  10.  
  11. char pseudo[100];
  12. for (char*y= adresse_debut+11; y!= adresse_fin ; y= y+sizeof(char), j++)
  13. {
  14. pseudo[j]= *y;
  15. }
  16. cout << "Pseudo : " << pseudo << endl;


ça fonctionne à peu pres... :-/
J'aurai préféré une méthode sans doute plus courte et efficace
a b L Programmation
23 Avril 2006 18:46:27

Au lieu de copier caractère par caractère, tu peux faire un strncpy() en indiquant le nombre de caractères (même si ça fait la même chose que toi, tu es sûr que ça marche bien).
Par contre dans les 2 cas pense à mettre le caractère 0 de fin de chaine en mettant à la fin de ta boucle
  1. pseudo[j] = '\0';

car je suppose que lorsque tu affiches ça ça met des caractères bizarres à la fin du pseudo.

  1. char *tmp1= "Le pseudo : ";
  2. char *tmp2= "L'autre machine : ";
  3.  
  4. char *buff=buffer;
  5. char *i;
  6. int j=0;
  7.  
  8. char* adresse_debut= strstr(buff, tmp1);
  9. char* adresse_fin= strstr(buff, tmp2);
  10.  
  11. char pseudo[100];
  12. int taille = adresse_fin - adresse_debut - 11;
  13. strncpy(pseudo, adresse_debut+11, taille);
  14. pseudo[taille] = '\0';
  15. cout << "Pseudo : " << pseudo << endl;

après je me suis peut-être trompé dans la taile à + ou - 1, je n'ai pas testé.
24 Avril 2006 12:58:34

Il y a un pb avec ton strncpy;

La compilation fonctionne, mais c'est à peu prêt le même pb que j'ai rencontrait en manipulant les strstr : erreur violation machin truc...

A mon avis, ça doit être du à qqchose pointé ou une valeur retourné qu'il faut bien manipuler... :-/
a b L Programmation
24 Avril 2006 13:17:28

ton buffer est terminé par un caratère de fin de chaine '\0' au moins ?
parce que si non, s'il ne trouve pas la chaîne, il va continuer sr toute la mémoire, jusqu'à tomber sur une mémoire qui ne lui est pas réservé => l'OS te traite :-D
24 Avril 2006 13:19:18

Oui, oui, j'ai mi avec le '\0'
mais l'erreur se trouve au niveau de strncpy quand je teste (avant qu'on lui indique le '\0')
a b L Programmation
24 Avril 2006 19:27:47

ah oui, j'ai oublié: s'il ne trouve pas, ça retourne un pointeur NULL s'il ne trouve pas. Du coup, les calculs ne seraient pas bon.
donc ajoute des tests, et regarde si "taille" a justement la bonne taille.
25 Avril 2006 00:42:51

J'pense avoir résolu le pb ^^

Et comme par hasard, quand on résous qqchose .. ya autre chose qui arrive :

J'ai créé un buffer qui récupère les données du net.
Le buffer ne récupère que le début... j'me suis alors demandait pourquoi, et il s'avère qu'en réseau, il y a cette règle du MTU (Maximum Transfert unit) l'unité maximum de transfert qui limite de 500 à 1500 (un peu moins de 1500 dans mon cas).

Du coup, au lieu que mon buffer de récup directement les données... j'ai pensait à récup les données dans un ptit buffer et de le réassembler dans un plus gros buffer (nommé result);
Mais coté algorithmi, j'ai tenter de faire qqchose, mais ça me pond qu'il y une violation dans la zone mémoire ... bref -_-' le code me semblait bon, mais ya qqchose qui n'allais pas...
Je voulais savoir si vous avez une idées de comment faire. ;) 
a b L Programmation
25 Avril 2006 13:00:48

Le mieux est effectivement de gérer ça en petits paquets réseaux.
26 Avril 2006 04:07:50

Bon, apparement, je n'ai pas encore trouver la solution pour le MTU... mais j'ai trouver le moyen de le contourner temporairement (enfin, jusqu'ici, mon proxy marche enfin ! pas tout, mais bon...)

mais j'ai encore quelque truc qui merde bcp..

oui, oui, tout n'est pas parfait;
Bon, je vais donnée un exemple concret :
Voici 3 exemples de requêtes HTTP sur le site de google effectuer par 3 navigateurs différent :

Sea monkeys : (le mozilla poursuivi)
GET http://www.google.fr/ HTTP/1.1
Host: www.google.fr
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR; rv:1.8.0.2) Gecko/20060404 SeaMonkey/1.0.1
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr,en-us;q=0.7,en;q=0.3
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive

IE : (sans commentaire... Crosoft l'a créé)
GET http://www.google.fr/ HTTP/1.0
Accept: */*
Accept-Language: fr
Cookie: PREF=ID=blablabla
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host: www.google.fr
Proxy-Connection: Keep-Alive

Firefox : (le ptit renard adoré de mozilla)
GET http://www.google.fr/ HTTP/1.1
Host: www.google.fr
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: PREF=ID=blablabla
Cache-Control: max-age=0

Quelque info :
buffer -> chaine de caractère contenant la requête HTTP

  1. char *tmp1= "Host: ";
  2. char *tmp2= "Proxy-Connection: ";
  3. char *buff=buffer;
  4. char *i;
  5. int j=0;
  6. char* adresse_debut= strstr(buff, tmp1);
  7. if(adresse_debut==NULL)...;//penser a faire qqchose...
  8. char* adresse_fin= strstr(buff, tmp2);
  9. int taille = adresse_fin - adresse_debut-7;
  10. char result[100];
  11. for (i= adresse_debut+6; i!= adresse_fin ; i= i+sizeof(char), j++)
  12. {
  13. result[j]= *i;
  14. }
  15. result[taille] = '\0';
  16. cout << "Le nom d'hote reçu est : \n" << result << endl;


Et voici l'erreur que j'ai :
Violation d'accès lors de la lecture

bon, comme on peut le remarquer... ce que j'ai fait dans mon code ne s'applique que pour IE...
Or, je voudrai que ça s'applique pour les 3 navigateurs. c'est à dire, trouver un strstr qui va de "Host :" à saut de ligne après Host...

PS : Merci d'avance à Criky qui est casiment le seul qui répond à mes posts ^^
PS 2 : Ce n'est pas interdit au autre de poster des réponses ;) 
26 Avril 2006 09:28:03

Citation :

char result[100];
...
result[j]= *i;


Il faut être sûr que ce que tu lis fait moins de 100 caractères (et je ne compte pas la 0 normalement en fin de chaine). Ton code fonctionne très bien chez moi si on prend l'entete de IE, par contre plante avec l'entete de Firefox.

Pour que ton code soit valable quelque soit le navigateur, il vaut mieux parser ta chaîne de caractères pour en obtenir tout les paramètres distincts. Ceci te permet de ne pas prendre en compte l'ordre dans lequel ils sont envoyer par le navigateur.

Remarque que si le caractère de saut de ligne est envoyé par le navigateur ('\n'), alors tu peux le remplacer dans
Citation :

char *tmp2= "\n";

et
Citation :

result[taille+1] = '\0';
26 Avril 2006 10:55:44

bonjour, jeen sais aps si g bien compris ton prob mais....
pour cela, il faut enregistrer les caractére du pseudo un par un, et pour cela il faut savaoi de quel numéro de case tu commance et a quel num tu t'arrete

(1)"Je répond au post de " il ya 21 caractéres c ça!
" sur le forum d'IDN" il ya 19 caracéters
(2)"RepliCarter sur le forum d'IDN" 30 - 19, donc ton pseudo a 11 caractére, ça veux dire:
tu met une boucle pour i := numdépar à num arrivé,
le début c 21, et larriveé c 21 + 11
for i := 21 to 32, et tu enregistre caractére par caractére, c simple!, le prob c de calculer la longueure du pseudo, donc tu calcule la longueur de la chaien a commencer du pseudo, et tu diminu le nombre de caractére en allant de al fin vers l'avant. enfin ça parrait compliquer, mais sur place c un jeux d'enfant.
26 Avril 2006 17:21:37

Citation :

ataofeal a écrit :
Citation :

char *tmp2= "\n";

et
Citation :

result[taille+1] = '\0';


en mettant "\n", il me semble qu'étant donnée qu'il y a plusieurs retour chariot... strstr pour \n sera mal localiser

(Sinon, mon code fonctionne bien avec IE mais seulement dans une seul condition), or, il génère bcp d'erreur dans plusieurs autre cas de figure.. -_-"
26 Avril 2006 17:46:04

Citation :
en mettant "\n", il me semble qu'étant donnée qu'il y a plusieurs retour chariot... strstr pour \n sera mal localiser

oui, mais c'était seulement un bout de la solution.

pour que le "\n" soit bien localisé, il suffit dans le deuxième strstr de passer adresse_debut comme premier paramètre au lieu de la chaîne initiale.

  1. char *tmp1= "Host: ";
  2. char *tmp2= "\n";
  3. char* adresse_debut= strstr(buff, tmp1);
  4. char* adresse_fin= strstr(adresse_debut, tmp2);
  5. int taille = adresse_fin - adresse_debut-6;


En rajoutant bien sûr les contrôles adéquates sur les longueurs de chaînes que tu manipules.
27 Avril 2006 04:03:20

merci, j'ai pu résoudre le pb en utilisant ta méthode ainsi que strtok combiné à strstr :) 
27 Avril 2006 16:52:33

Bon, je vais revenir sur un autre pb que j'ai encore du mal à résoudre concernant le MTU :

char Donnes="01234567890123456789abcdefghijklmnopqrstuvwxyz</endofbuffer>";
//Je vous présente ci dessus mes jolies donnes contenant les informations que je souhaite stoqué dans buffer2.
char buffer2[1024];

Maintenant, j'ai une fonction AFF qui permet de récupéré les données.
AFF segmente les données en paquet de 1024 caractère.

Lorsque je fais appel à ma fonction AFF j'ai ces parametres :
AFF (donnes, buffer2, taille des donnes);
Le 1er paramètre représente les données.
Le 2eme, c'est le buffer et le 3eme, c'est la taille des données.

Lorsque je fais appel à AFF une fois, il prend que le début des données, lorsque je fais appel à AFF une second fois, j'ai une autre partie des données etc...

Je souhaite stocké l'intégralité des données "Donnes" dans un 3emes buffer. (ou dans le 2nd buffer si c'est possible mais d'apres ce que j'ai tenter deja de faire... le mieu serai un 3eme buffer).

(sans ligne de code)
-----

boucle tant qu'on ne rencontre pas le caractere de fin "</endofbuffer>" faire
{
la fonction AFF copie les premiers 1024 caracteres de données dans buffer 2
buffer2 stock les données dans buffer3 les uns à la suite des données
}

----
Bon, deja, quand j'essaie de faire ça, je n'arrive pas à specifier la taille etc... quelqu'un pourrai t-il m'aider et me fournir un debut de code que je pourrai tenter ?

PS : Si celà vous semble absurde de faire ceci, ce n'est pas exactement ça que je dois faire mais je devrai adapter ça à mon programme.

Info : (ceci n'est pas le cas concret mais bon, le cas concret serai bcp bcp plus long à expliquer prennant en compte plein d'autre parametre) mais les réponses apporter m'aideront à l'adapter à mon cas
28 Avril 2006 13:30:20

Petit up ^^
(tjrs bloquer à ce niveau là)
28 Avril 2006 14:08:47

désolé mais je ne comprends pas trop ce que tu veux faire ...

Si je comprends :
Tu as des données dans un buffer du type :
char Donnes="01234567890123456789abcdefghijklmnopqrstuvwxyz</endofbuffer>";

Tu as une fonction AFF qui te permet de découper ce buffer en paquet de 1024 caractères.

Par la suite je ne comprends pas l'interet du buffer3 qui semble être au final ton buffer "Donnes" ...

Ne pourrait tu pas donner un exemple concret ou un peu mieux expliquer ce que tu souhaites faire?
28 Avril 2006 23:38:22

Salut, merci de répondre au post :) 

Il semblerai que j'ai réussi cette apres midi, de résoudre le ptit soucis concernant cette chaine de caractère...

Maintenant, je suis confronté à un autre soucis :

J'utilise la fonction recv (qui permet de recevoir des données)

Elle retourne soit la valeur -1 en cas d'erreur, soit la valeur du nombre de caractere qu'elle a

J'ai donc utiliser une boucle while mais le soucis est que tel que je met les conditions... la boucle ne se termine jamais.... -_-

C'est à dire :

int

while (nombredebyte!=0)
{
nombredebyte= recv(...);
if (nombredebyte==-1) cout << "erreur" << endl;
else if (nombredebyte==0) break;
[mon ptit programme]
[...]
}
cout << "ce qui va apres la boucle" << endl;

Et apparement... ça ne sert jamais de la boucle... :-!

Question : Ai-je mi qqchose dans la boucle que je ne devait pas mettre ?

Edit :
Définition de retour de la fonction recv :
Ces fonctions renvoient le nombre d'octets reçus si elles réussissent, ou -1 si elles échouent, auquel cas errno contient le code d'erreur.
Pour ma boucle, j'ai tenté :
while (nombredebyte>0)
if (nombredebyte<0)
else if (nombredebyte==0)

mais il semblerai qu'il ne soit jamais égal à 0... (chose que je pensait s'il ne reçoit rien... )
29 Avril 2006 01:43:50

Bon, apparement, j'ai pseudo-résolu le probleme... (avec des termes additionnel fesant fermer la boucle)

Outch outch ! ...

J'ai de ces problemes pour maitriser les chaines de caractères... :-/
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS