[langage c] question (en cours)
-
- Elfe
- Messages : 623
- Inscription : dim. 27 avr. 2014, 09:32
[langage c] question (en cours)
Bonjour,
On peut poser des questions sur un programme écrit en C sur ce forum ?
On peut poser des questions sur un programme écrit en C sur ce forum ?
- FoolEcho
- Maître du Kyudo
- Messages : 10707
- Inscription : dim. 15 août 2010, 11:48
- Localisation : Basse-Normandie
Re: [langage c] question (en cours)
Tu peux toujours... après, ce n'est pas la vocation de ce forum, forcément.
«The following statement is not true. The previous statement is true.»
Re: [langage c] question (en cours)
Moi je dis qu'il ne peut pas
-
- Elfe
- Messages : 623
- Inscription : dim. 27 avr. 2014, 09:32
Re: [langage c] question (en cours)
J'ai un programme qui se connecte via la protocole imap sur mon serveur mail.
J'ai une boucle infini (Tant que l'utilisateur ne veut pas quitter en tapant LOGOUT), qui permet d'envoyer des requêtes au serveur mail puis de recevoir les réponses :
Et voici la fonction add :
Les données sont reçu du serveur par bloc de 1024 octets. Ma variable data a donc une taille de 1025 pour accueil le '\0' de fin de chaine.
Lors de la première requête effectué sur le serveur, tout ce passe bien (je reçois bien les données).
Lors de la deuxième requête, je reçois que la moitié des données, et il y a des caractères qui se sont transformé en caractère bizarre. Pourtant les deux requêtes sont identiques.
Je ne vois pas pourquoi ? Voyez vous une erreur dans mon code ?
NB : Je tient à signaler que si je ne regroupe pas toutes les données reçu dans la variable data avant de les afficher, mais que je les affiche par bloc de 1024 octets (décommenter les deux lignes avec le else, et commenter la ligne du printf("%s", data) et data = add() ), tout marche très bien.
Mais ce que je veux c'est toutes mes données d'une requête dans une seule variable.
J'espère avoir été clair.
J'ai une boucle infini (Tant que l'utilisateur ne veut pas quitter en tapant LOGOUT), qui permet d'envoyer des requêtes au serveur mail puis de recevoir les réponses :
Code : Tout sélectionner
/* On boucle tant que l'utilisateur ne veut pas quitter */
while((strstr(msg, "LOGOUT\r\n")) == NULL)
{
char *data = ""; /* Chaine contenant la réponses du serveur */
i++;
/* Saisie de l'utilisateur */
printf("\n> ");
input(tmp, 1024); /* Voire la fonction input comme la fonction scanf, mais en plus évolué */
sprintf(msg, "%d %s\r\n", i, tmp); /* On construit le message à envoyer au serveur mail */
/* Envoie de la saisie au serveur */
if(send(sock, msg, strlen(msg), 0) < 0)
{
perror("send()");
exit(errno);
}
/* Récupération des données */
do {
/* On recoit les données par bloc de 1024 octets */
if((n = recv(sock, buffer, sizeof buffer, 0)) < 0)
{
perror("recv()");reqûete
exit(errno);
}
/* On termine la chaine de caractère par le '\0' de fin de chaine */
if(n < 1024)
buffer[n] = '\0';
/* VERSION 1 : COMMENTER CETTE LIGNE */
data = add(data, buffer); /* Reconstruction de la chaine */
/* On ferme le serveur à la demande de l'utilisateur */
if((strstr(msg, "LOGOUT\r\n")) != NULL)
{
printf("Serveur fermé !\n\n");
break;
}
/* VERSION 1 : DECOMMENTER CES DEUX LIGNES */
//else
// printf("%s", buffer);
} while(strstr(buffer, "completed.\r\n") == NULL);
/* VERSION 1 : COMMENTER CETTE LIGNE */
printf("%s", data);
free(data);
}
Code : Tout sélectionner
char *add(char *ch1, char *ch2)
{
char *data = "";
int i, j, n = strlen(ch1), m = strlen(ch2);
data = (char*) malloc(n * sizeof(char) + m * sizeof(char));
//strcat(data, ch1);
//strcat(data, ch2);
for(i = 0 ; i < n ; i++)
data[i] = ch1[i];
for(j = i ; j < m+n ; j++)
data[j] = ch2[j-i];
return data;
}
Lors de la première requête effectué sur le serveur, tout ce passe bien (je reçois bien les données).
Lors de la deuxième requête, je reçois que la moitié des données, et il y a des caractères qui se sont transformé en caractère bizarre. Pourtant les deux requêtes sont identiques.
Je ne vois pas pourquoi ? Voyez vous une erreur dans mon code ?
NB : Je tient à signaler que si je ne regroupe pas toutes les données reçu dans la variable data avant de les afficher, mais que je les affiche par bloc de 1024 octets (décommenter les deux lignes avec le else, et commenter la ligne du printf("%s", data) et data = add() ), tout marche très bien.
Mais ce que je veux c'est toutes mes données d'une requête dans une seule variable.
J'espère avoir été clair.
-
- Maître du Kyudo
- Messages : 1855
- Inscription : mer. 06 janv. 2010, 13:51
- Localisation : Ried - Alsace - France
Re: [langage c] question (en cours)
J'imagine que buffer est déclaré comme ça :
Premier souci : si tu reçois précisément 1024 caractères, tu n'auras pas de '\0' de fin de chaîne à la fin de buffer. Donc ta fonction add ne va pas trop bien marcher.
Ensuite tu as des fuites mémoire, quand tu fais :
data pointe sur une zone mémoire. A la sortie de la fonction add, data pointe sur une autre zone mémoire (celle allouée dans add). Mais l'ancienne zone mémoire n'est pas libérée.
PS : Je ne me souvenais plus que le C pouvait être aussi bas niveau et moche à lire
Code : Tout sélectionner
char buffer[1024];
Ensuite tu as des fuites mémoire, quand tu fais :
Code : Tout sélectionner
data = add(data, buffer)
PS : Je ne me souvenais plus que le C pouvait être aussi bas niveau et moche à lire
La majorité des bugs se situe entre la chaise et le clavier...
Arrêtez de vous prendre la tête avec les partitions... passez au LVM
Arrêtez de vous prendre la tête avec les partitions... passez au LVM
- benjarobin
- Maître du Kyudo
- Messages : 17288
- Inscription : sam. 30 mai 2009, 15:48
- Localisation : Lyon
Re: [langage c] question (en cours)
Ta fonction add ne réserve pas via le malloc le \0 de fin.
Sinon pourquoi ne pas utiliser strcpy et strcat ? Voir encore plus simple de remplacer toute cette fonction (ok c'est un peu moins rapide mais vraiment tu n'est pas à quelques us prêt) par
Sinon pourquoi ne pas utiliser strcpy et strcat ? Voir encore plus simple de remplacer toute cette fonction (ok c'est un peu moins rapide mais vraiment tu n'est pas à quelques us prêt) par
Code : Tout sélectionner
asprintf(&data, "%s%s", ch1, ch2)
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
-
- Elfe
- Messages : 623
- Inscription : dim. 27 avr. 2014, 09:32
Re: [langage c] question (en cours)
Non, justement buffer est déclaré comme ceci :oktoberfest a écrit :J'imagine que buffer est déclaré comme ça :Premier souci : si tu reçois précisément 1024 caractères, tu n'auras pas de '\0' de fin de chaîne à la fin de buffer. Donc ta fonction add ne va pas trop bien marcher.Code : Tout sélectionner
char buffer[1024];
Code : Tout sélectionner
char buffer[1025];
Je ne connaissais pas asprintf() . Mais lorsque je marque :benjarobin a écrit :Ta fonction add ne réserve pas via le malloc le \0 de fin.
Sinon pourquoi ne pas utiliser strcpy et strcat ? Voir encore plus simple de remplacer toute cette fonction (ok c'est un peu moins rapide mais vraiment tu n'est pas à quelques us prêt) parCode : Tout sélectionner
asprintf(&data, "%s%s", ch1, ch2)
Code : Tout sélectionner
asprintf(&data, "%s%s", data, buffer)
Deplus, si je garde mon code précédent et que j’enlève tout simplement free(data), ca marche.
-
- archer de cavalerie
- Messages : 187
- Inscription : lun. 10 août 2015, 13:50
- Localisation : France
Re: [langage c] question (en cours)
Salut,
asprintf(3) - Linux man page
*flies away*
AchilleFraisse a écrit : il me dit implicit declaration of function asprintf.
Code : Tout sélectionner
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
[...]
*flies away*
Arch Linux x86_64 UEFI
7,3 Gio RAM
Intel® Core™ i5-4200U CPU @ 1.60GHz × 4
Intel® Haswell Mobile + NVIDIA GeForce 840M 2 Gio vRAM
KDE Plasma + SDDM
7,3 Gio RAM
Intel® Core™ i5-4200U CPU @ 1.60GHz × 4
Intel® Haswell Mobile + NVIDIA GeForce 840M 2 Gio vRAM
KDE Plasma + SDDM
-
- Elfe
- Messages : 623
- Inscription : dim. 27 avr. 2014, 09:32
Re: [langage c] question (en cours)
Il me renvoie encore le même warning
- benjarobin
- Maître du Kyudo
- Messages : 17288
- Inscription : sam. 30 mai 2009, 15:48
- Localisation : Lyon
Re: [langage c] question (en cours)
Pourtant ceci compile (et fonctionne) sans warning
Compilé avec
Code : Tout sélectionner
#define _GNU_SOURCE 1
#include <stdio.h>
int main(void)
{
char *data = NULL;
const char *ch1 = "hello";
const char *ch2 = " world";
asprintf(&data, "%s%s", ch1, ch2);
puts(data);
return 0;
}
Code : Tout sélectionner
gcc -std=c99 -O2 -Wall -Wextra t.c -o t
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
-
- archer de cavalerie
- Messages : 187
- Inscription : lun. 10 août 2015, 13:50
- Localisation : France
Re: [langage c] question (en cours)
Je confirme, même sans spécifier la version. Donnes-nous la commande que tu utilise pour compiler.
Arch Linux x86_64 UEFI
7,3 Gio RAM
Intel® Core™ i5-4200U CPU @ 1.60GHz × 4
Intel® Haswell Mobile + NVIDIA GeForce 840M 2 Gio vRAM
KDE Plasma + SDDM
7,3 Gio RAM
Intel® Core™ i5-4200U CPU @ 1.60GHz × 4
Intel® Haswell Mobile + NVIDIA GeForce 840M 2 Gio vRAM
KDE Plasma + SDDM