2009-03-02 11 views
1

Description:Alternative à fgets()?

  • Pour obtenir une sortie d'un exécutable

Note:

  • ne compilera pas, en raison de la déclaration fgets()

Question:

  • Quelle est la meilleure alternative à fgets, comme fgets exige char *?
  • Existe-t-il une meilleure alternative?

Illustration:

void Q_analysis (const char *data) 
{ 
string buffer; 
size_t found; 
found = buffer.find_first_of (*data); 

FILE *condorData = _popen ("condor_q", "r"); 
while (fgets (buffer.c_str(), buffer.max_size(), condorData) != NULL) 
{ 
    if (found == string::npos) 
    { 
     Sleep(2000); 
    } else { 
     break; 
    } 
} 
return; 
} 

Répondre

4

Vous devez utiliser la fonction string.getline pour les chaînes cppreference

mais dans votre cas, vous devriez utiliser un char [] pour lire en .

par exemple

string s; 
char buffer[ 4096 ]; 
fgets(buffer, sizeof(buffer), condorData); 
s.assign(buffer, strlen(buffer)); 

ou votre code:

void Q_analysis(const char *data) 
{ 
    char buffer[ 4096 ]; 

    FILE *condorData = _popen ("condor_q", "r"); 
    while(fgets(buffer, sizeof(buffer), condorData) != NULL) 
    { 
     if(strstr(buffer, data) == NULL) 
     { 
       Sleep(2000); 
     } 
     else 
     { 
       break; 
     } 
    } 
} 
+0

Ne fonctionne pas avec FICHIER * –

+0

ya, j'ai relu la question et j'ai réalisé qu'il s'agissait d'un tuyau. – sfossen

1

Au lieu de vous déclarer tampon comme une chaîne déclarer quelque chose comme:

char buffer[MY_MAX_SIZE] 

fgets d'appel avec qui, et puis construisez la chaîne à partir du tampon si vous en avez besoin sous cette forme au lieu de passer de l'autre côté.

La raison pour laquelle ce que vous faites ne fonctionne pas est que vous obtenez une copie du contenu du tampon comme une chaîne de style c, pas un pointeur dans l'intestin de la mémoire tampon. C'est, par conception, en lecture seule.

- MarkusQ

0

Vous avez raison que vous ne pouvez pas lire directement dans un std::string parce que ses c_str et data renvoient toutes les deux pointeurs const. Vous pouvez lire dans un std::vector<char> à la place. Vous pouvez également utiliser la fonction getline. Mais il nécessite un objet iostream, pas un pointeur C FILE. Vous pouvez passer de l'un à l'autre, cependant, d'une manière spécifique au fournisseur. Voir "A Handy Guide To Handling Handles" pour un diagramme et quelques suggestions sur la façon de passer d'un type de fichier à un autre. Appelez fileno sur votre FILE* pour obtenir un descripteur de fichier numérique, puis utilisez fstream::attach pour l'associer à un objet fstream. Ensuite, vous pouvez utiliser getline.

+0

Mais notez que le vecteur ne va pas grandir comme je pense que le PO attend –

0

Essayez la bibliothèque Boost - Je crois qu'il a une fonction pour créer un fstream partir d'un fichier *

ou vous pouvez utiliser fileno() pour obtenir un descripteur de fichier standard C à partir du fichier, puis utilisez fstream :: attacher pour attacher un flux à ce fichier. De là, vous pouvez utiliser getline(), etc. Quelque chose comme ceci:

FILE *condorData = _popen ("condor_q", "r"); 
std::ifstream &stream = new std::ifstream(); 
stream.attach(_fileno(condorData)); 
0

Je ne l'ai pas testé trop bien, mais apparaît ci-dessous pour faire le travail:

//! read a line of text from a FILE* to a std::string, returns false on 'no data' 
bool stringfgets(FILE* fp, std::string& line) 
{ 
    char buffer[1024]; 
    line.clear(); 

    do { 
    if(!fgets(buffer, sizeof(buffer), fp)) 
     return !line.empty(); 

    line.append(buffer); 
    } while(!strchr(buffer, '\n')); 
    return true; 
} 

Soyez au courant Cependant, cela va heureusement lire une ligne de 100G, donc il faut veiller à ce que ce ne soit pas un vecteur DoS provenant de fichiers sources ou de sockets non approuvés.