Domanda

Descrizione:

  • Ottieni output da un eseguibile

Nota:

  • Non verrà compilato, a causa della dichiarazione fgets ()

Domanda:

  • Qual è la migliore alternativa ai budget, poiché i budget richiedono char *?
  • Esiste un'alternativa migliore?

Illustrazione:

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;
}
È stato utile?

Soluzione

Dovresti usare la funzione string.getline per le stringhe cppreference

comunque nel tuo caso, dovresti usare un carattere [] per leggere.

es

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

o il tuo codice:

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;
        }
    }
}

Altri suggerimenti

Invece di dichiarare il tuo buffer come una stringa dichiaralo come qualcosa del tipo:

char buffer[MY_MAX_SIZE] 

chiama i budget con quello, quindi costruisci la stringa dal buffer se hai bisogno in quella forma invece di andare nell'altra direzione.

Il motivo per cui non stai funzionando è che stai ottenendo una copia del contenuto del buffer come una stringa in stile c, non un puntatore nell'intestino del buffer. Di progettazione è di sola lettura.

- MarkusQ

Hai ragione sul fatto che non puoi leggere direttamente in un std::string perché i suoi metodi c_str e data restituiscono entrambi i puntatori const. Invece potresti leggere in std::vector<char>.

Puoi anche usare la funzione getline. Ma richiede un oggetto iostream, non un puntatore C FILE. Puoi passare dall'uno all'altro, in un modo specifico per il fornitore. Vedi & Quot; Una guida pratica alla gestione delle maniglie & Quot; per un diagramma e alcuni suggerimenti su come passare da un tipo di file a un altro. Chiama fileno sul tuo FILE* per ottenere un descrittore di file numerico, quindi usa fstream::attach per associarlo a un fstream oggetto. Quindi puoi usare <=>.

Prova la libreria boost - credo che abbia una funzione per creare un flusso da un FILE *

oppure puoi usare fileno () per ottenere un handle di file C standard dal FILE, quindi usa fstream :: attach per collegare un flusso a quel file. Da lì puoi usare getline (), ecc. Qualcosa del genere:

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

Non l'ho provato troppo bene, ma il seguente sembra fare il lavoro:

//! 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;
}

Tuttavia, tieni presente che questo leggerà felicemente una riga di testo da 100 G, quindi devi fare attenzione che questo non sia un vettore DoS da file o socket di origine non attendibili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top