Pregunta

Descripción:

  • Obtener salida de un ejecutable

Nota:

  • No se compilará debido a la declaración fgets()

Pregunta:

  • ¿Cuál es la mejor alternativa a fgets, ya que fgets requiere char *?
  • ¿Hay una mejor alternativa?

Ilustración:

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;
}
¿Fue útil?

Solución

Debería usar la función string.getline para cadenas cppreference

sin embargo, en su caso, debería usar un char [] para leer.

por ejemplo

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

o su código:

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

Otros consejos

En lugar de declarar el búfer como una cadena, declararlo como algo así como:

char buffer[MY_MAX_SIZE] 

llame fgets con eso, y luego construya la cadena desde el búfer si lo necesita en esa forma en lugar de ir hacia el otro lado.

La razón por la que lo que está haciendo no funciona es que está obteniendo una copia del contenido del búfer como una cadena de estilo c, no un puntero en el intestino del búfer. Es, por diseño, de solo lectura.

- MarkusQ

Tienes razón en que no puedes leer directamente en un std::string porque es c_str y data Ambos métodos devuelven punteros constantes.Podrías leer en un std::vector<char> en cambio.

También podrías utilizar el getline función.Pero requiere un objeto iostream, no un puntero de ARCHIVO C.Sin embargo, puede pasar de uno a otro de una manera específica del proveedor.Ver "Una guía práctica para manipular manijas" para ver un diagrama y algunas sugerencias sobre cómo pasar de un tipo de archivo a otro.Llamar fileno en tu FILE* para obtener un descriptor de archivo numérico y luego usar fstream::attach asociarlo con un fstream objeto.Entonces puedes usar getline.

Pruebe la biblioteca de impulso: creo que tiene una función para crear un fstream desde un ARCHIVO *

o puede usar fileno () para obtener un identificador de archivo C estándar desde el ARCHIVO, luego use fstream :: attach para adjuntar una secuencia a ese archivo. Desde allí puede usar getline (), etc. Algo como esto:

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

No lo he probado demasiado bien, pero el siguiente parece hacer el trabajo:

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

Sin embargo, tenga en cuenta que con gusto leerá una línea de texto de 100G, por lo que debe tenerse cuidado de que este no sea un vector DoS de archivos o sockets no confiables.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top