Newsgroup: it.comp.lang.c
Titolo: [HELP] funzione non funziona...

Salve,
Non riesco a capire cosa non va in questa funzione.
Praticamente dato come buffer un header, si posiziona alla fine della
stringa "Date: " (fin qui funziona) e poi dovrebbe restituire un puntatore
a una stringa contenente la data fino al carattere 10 o 13 o "-" o "+".
Il problema è che la funzione restituisce solo i primi 6 o 7 caratteri
della data.
Questo è il codice:
char* getDataPost(char* buffer) {
  const char* TOFIND = "Date: ";
  char* res=strstr(buffer, TOFIND);
  char* data = (char*) malloc(50);
  int i = 0;
  if (res != NULL) {
     res += 5;
     do {
         res++;
         data[i] = (char)(*res);
         i++;
     } while (data[i] != 10 && data[i] != 13 && data[i] != '-' 
          && data[i] != '+');
  } else 
    return NULL;
  data[i-1] = '\0';
  return data;
}
Secondo voi cosa c'è che non va?

 Secondo voi cosa c'è che non va?
fai anche attenzione che se in input ti viene dato
Date: +
il tuo codice non farà quello che ti aspetti perché il primo carattere 
(il + in questo caso) non viene controllato nel do ... while. Io userei 
un semplice while.
E.

Il Wed, 12 Dec 2007 18:17:14 +0100, Yello '73 ha scritto:
risolto da solo grazie comunque :)

   .....
io la farei +/- cosi':
======
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BF_GETDATAPOST_SZ  50
char *getDataPost(char *pBuffer)
{
	int i = 0;
	char *p, *pBfRet;
	char sToFind[] = "Date: ";
	if(!pBuffer || !*pBuffer)
		return NULL;
	if(!(p = strstr(pBuffer, sToFind)))
		return NULL;
 
	/* "Date :" deve trovarsi ad inizio linea */
	if(p > pBuffer && *(p-1) != '\n')
		return NULL;
	if(!(pBfRet = malloc(BF_GETDATAPOST_SZ)))
		return NULL;
	p += strlen(sToFind);
	/* salta eventuali spazi all'inizio */
	while(*p && isspace(*p))
		p++;
	for(i = 0; i < (BF_GETDATAPOST_SZ-1) && *p && !strchr("-+\r\n", *p); 
i++, p++)
		pBfRet[i] = *p;
	/* toglie eventuali spazi alla fine */
	for(--i; i >= 0 && isspace(pBfRet[i]); i--)
		;
	++i;
	pBfRet[i] = '\0';
	return pBfRet;
}
/* test */
int main(void)
{	
	/* la stringa nel buffer e' tipo questa sotto? ho indovinato? */
	char *pTest = "Content-type: text/html\r\nDate: Tue, 11 Dec 2007 
12:18:43 +0100\r\n";
	char *p = getDataPost(pTest);
	if(p)
	{	printf("Risultato: <%s>\n", p);
		free(p);
	}
	return 0;
}
====
magari, pero', provala bene...
che mi sono divertito a scriverla mentre aspettavo che si cuocesse la 
minestra (e ora mi si sta raffreddando) :-)
ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

ciao
Effettivamente la tua versione è più robusta e pulita.
Userò questa :)
Grazie infinite.
G.

Yello '73 ha scritto:

vabbe', allora te ne posto un'altra che dovrebbe essere un po' meno 
/approssimativa/ della versione precedente. Pero' analizzala e provala bene 
prima di metterla a lavoro.
Ciao
======
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *getDataPost(char *pBuffer)
{
	size_t	u = 0;
	char 	*p, *pBfRet;
	char	sToFind[] = "Date: ";
 
	if(!pBuffer || !*pBuffer)
		return NULL;
	/* cerchiamo la 1^ occorrenza di sToFind, ma */
	/* solo se e' all'inizio di una linea di testo */
	for(p = pBuffer; (p = strstr(p, sToFind)); p++)
		if(p == pBuffer || *(p-1) == '\n')
			break;
	if(!p)
		return NULL; /* non trovata */
	p += strlen(sToFind);
	/* salta eventuali spazi o tab all'inizio */
	while(*p && (*p == ' ' || *p == '\t'))
		p++;
	/* calcola lungh. segmento iniziale (o fino a '\0') */
	u = strcspn(p, "-+\r\n");
	/* toglie dal calcolo eventuali spazi o tab alla fine */
	for(; u > 0U && (p[u-1U] == ' ' || p[u-1U] == '\t'); u--)
		;
	/* alloca la memoria richiesta */
	if(!(pBfRet = malloc(u+1U)))
		return NULL;
	/* ci copia il segmento di stringa e lo termina */
	strncpy(pBfRet, p, u);
	pBfRet[u] = '\0';
	return pBfRet;
}
/* test */
int main(void)
{
	char *pTest = "Content-type: text/html\r\nDate: Tue, 11 Dec 2007 12:18:43 
-0100\r\n";
	char *p = getDataPost(pTest);
	if(p)
	{	printf("Risultato: <%s>\n", p);
		free(p);
	}
	return 0;
}


 Ciao
[snip]
Ottima interpretazione, anche in standard ANSI C!
Partendo dalla tua ne ho fatta una versione generica (visto che siamo
pignoli mi sono permesso di modificare anche la riga dell'allocazione):
/* pBuffer : header
   sToFind : pattern da ricercare (es. "Date: ")
   sDelim  : delimitatore (es. "\r\n+-") */
char *getField(char *pBuffer, const char* sToFind, const char* sDelim)
{
	size_t	u = 0;
	char 	*p, *pBfRet;
 
	if(!pBuffer || !*pBuffer)
		return NULL;
	/* cerca la 1^ occorrenza di sToFind, ma       */
	/* solo se e' all'inizio di una linea di testo */
	for(p = pBuffer; (p = strstr(p, sToFind)); p++)
		if(p == pBuffer || *(p-1) == '\n')
			break;
	if(!p)
		return NULL; /* non trovata */
 
	p += strlen(sToFind);
	/* salta eventuali spazi o tab all'inizio */
	while(*p && (*p == ' ' || *p == '\t'))
		p++;
	/* calcola lungh. segmento iniziale (o fino a '\0') */
	u = strcspn(p, sDelim);
	/* toglie dal calcolo eventuali spazi o tab alla fine */
	for(; u > 0U && (p[u-1U] == ' ' || p[u-1U] == '\t'); u--)
		;
	/* alloca la memoria richiesta */
	if(!(pBfRet = (char*)malloc(u+1U) * sizeof(char)))
		return NULL;
	/* ci copia il segmento di stringa e lo termina */
	strncpy(pBfRet, p, u);
	pBfRet[u] = '\0';
	return pBfRet;
}
Che poi richiamo da questa, specifica per la data:
char *getDataPost(char *pBuffer)
{
	char * pBfRet = getField(pBuffer, "Date: ", "\r\n+-");
	return pBfRet;
}
Grazie infinite!
Ciao.
G.

 		return NULL;
Ovviamente:
        if(!(pBfRet = (char*) malloc((u+1U) * sizeof(char))))
		return NULL;
;)
Ciao e grazie di nuovo.
G.

 }
Ciao


 sara' sempre pari a 1) e, IMHO, penalizza ulteriormente la lettura.
Soprattutto in questo caso viene moltiplicato il *puntatore*, non la 
dimensione del buffer!! C'è un problema con le parentesi, infatti...
E.


Idem, con il +.
Forse il compilatore restituisce troppi warning  e ti danno fastidio :-) ?
--
Giorgio Silvestri
DSP/Embedded/Real Time OS   Software Engineer

 for(; u && (p[u-1] == ' ' || p[u-1] == '\t'); u--)
Andava sicuramente bene.
Se ti dico il perche' di quella U rischio di alimentare il thread con 
commenti di disappunto, essendo il motivo molto soggettivo e, lo ametto, 
pure discutibile.
Ma te lo spiego ugualmente :-)
Il fatto che caschi l'occhio in quelle U e' un fatto voluto. E, 
sostanzialmente, ha lo stesso significato del commento:
/* attenzione stiamo usando un indice "unsigned"! */
...cosi', come per parare l'evenienza che magari qualcuno, in futuro, 
modificando quel codice in quella funzione, faccia (ad esempio) il classico 
errore di confronto per u >= 0.
Per lo stesso motivo ho battezzato la variabile con il nome 'u' (e non, ad 
esempio 'i', 'n' o 'x' - che si trovano impiegate, spesso, per generici 
indici interi con segno).


invece di 1U sarebbe piu' corretto usare (size_t)1