2010-12-02 37 views
0

dans une fonction, qui obtient unsigned char & & longueur unsigned char,std :: Cout << stringstream.str() -> c_str() imprime rien

void pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet) 
{ 
    std::vector<unsigned char> vec(packet, packet+pkthdr->len); // optimized from foo. 
    std::stringstream scp; 
    for (int i=0;i<pkthdr->len;i++) { 
     scp<<vec[i]; 
    } 
    std::string mystr = std::string(scp.rdbuf()->str()); 
    std::cout << "WAS: " << packet << std::endl; 
    std::cout << "GOOD: " << scp.str() << std::endl; 
    std::cout << "BAD: " << scp.str().c_str() << std::endl; 
    std::cout << "TEST: " << mystr.size() << std::endl; 
    assert(mystr.size() == pkthdr->len); 
} 

Résultats:

  • ÉTAIT: rien imprime (devinez il est un pointeur sur const .. cas)
  • BON: imprime des données
  • BAD: imprime rien
  • TEST, assert: affiche que mystr.size() est égal à la taille du caractère non signé.

J'ai essayé:

  • string.assign (scp.rdbuf());
  • memcpy (char, scp.str(), 10);
  • différentes méthodes de création/allocation temporaire, cordes caractères

Aucune aide .. il voulait obtenir un std :: Cout « en mesure std :: string qui contient des données, (qui était choisi à partir de foo, qui était carbonisation non signé, qui a été données par paquets).

Deviner soit l'original foo ne peut pas être terminé par zéro, ou le problème est quelque chose comme ceci - simple, mais ne peut pas entrer .. quelles sont les choses à rechercher ici?

(ce code est une autre tentative d'utiliser libpcap, juste pour imprimer des paquets en C++ manière, sans utiliser connu C++ wrappers magiques comme libpcapp).

+5

Comment est 'std :: cout <<" BAD: "<< scp.str()-> c_str() << std :: endl;' même * compiler * ?? La fonction membre 'std :: stringstream :: str()' ne renvoie pas de pointeur. Il renvoie une instance de 'std :: string'. –

+0

@Charles Salvia, aïe. J'ai eu un faux-semblant en essayant de me souvenir de toutes les tentatives erronées pour le mâcher. –

+0

Qu'est-ce que foo_len? –

Répondre

3

Pour un test rapide, lancez une recherche de scp.str().size() == strlen(scp.str().c_str()) pour voir s'il y a des caractères '\ 0' incorporés dans la chaîne, ce qui est probablement le cas.

+0

suspecté la même chose .. et oui, l'assertion a échoué .. même chose arrive pour scp.str(). data(), maintenant c'est une question, comment transmettre un élément null-byte –

+0

'strlen (scp.str(). c_str())' est en fait 0. –

1

Vérifiez std::cout.good() après la tentative de sortie a échoué. Ma conjecture est qu'il y a un certain échec en sortie (c'est-à-dire en essayant d'écrire un caractère non imprimable sur la console), qui est en train de définir failbit sur cout.

Vérifiez également assurer la chaîne ne commence pas par un NULL, qui provoqueraient la sortie vide pour être le comportement attendu :)

(Note, s'il vous plaît utiliser reinterpret_cast pour unsigned char *ucopy = (unsigned char*)packet; si vous êtes en C++;)

+0

BAD paquet est: cout Bon 1 Eof 0 Échec 0 Mauvais 0; utilisé' const_cast' parce que l'argument d'origine est const .. –

+1

@mhambra Plutôt que d'utiliser const cast, vous devriez faire le pointeur être un ' const unsigned char * ', et supprimer le const_cast –

2

Je pense que vous allez sur ce dans le mauvais sens. Il semble que vous ayez affaire à des données binaires ici, auquel cas vous ne pouvez pas vous attendre à les afficher de façon significative à l'écran sous forme de texte. Ce dont vous avez vraiment besoin est un hex dump.

const unsigned char* ucopy = packet; 
std::ios_base::fmtflags old_flags = std::cout.flags(); 
std::cout.setf(std::ios::hex, std::ios::basefield); 

for (const unsigned char* p = ucopy, *e = p + pkthdr->len; p != e; ++p) { 
    std::cout << std::setw(2) << std::setfill('0') << static_cast<unsigned>(*p) << " "; 
} 

std::cout.flags(old_flags); 

Ceci affichera les données octet par octet, et vous permettent d'examiner les valeurs hexagonales individuelles des données binaires. Un octet nul sera simplement généré comme 00.

+0

nice .. qu'en est-il de l'ajout des valeurs de byte à un 'static char *', copiant efficacement la chaîne - vous pensez qu'une sorte de 'char [len] = strdup (? _ cast ())' le ferait? –