Alternativa ai budget ()?
-
03-07-2019 - |
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;
}
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.