Альтернатива fgets ()? - PullRequest
       10

Альтернатива fgets ()?

1 голос
/ 02 марта 2009

Описание:

  • Получить вывод из исполняемого файла

Примечание:

  • Не компилируется из-за объявления fgets ()

Вопрос:

  • Какова лучшая альтернатива fgets, поскольку fgets требует char *?
  • Есть ли лучшая альтернатива?

Иллюстрация:

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

Ответы [ 5 ]

4 голосов
/ 02 марта 2009

Вы должны использовать функцию string.getline для строк cppreference

однако в вашем случае вы должны использовать char [] для чтения.

например

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

или ваш код:

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;
        }
    }
}
1 голос
/ 02 марта 2009

Вместо того, чтобы объявлять ваш буфер в виде строки, объявите его примерно так:

char buffer[MY_MAX_SIZE] 

вызовите fgets с этим, а затем соберите строку из буфера, если вам нужно в этой форме, вместо того, чтобы идти другим путем.

Причина, по которой вы не работаете, заключается в том, что вы получаете копию содержимого буфера в виде строки в стиле c, а не указатель в кишку буфера. Это, по замыслу, только для чтения.

- MarkusQ

0 голосов
/ 08 июня 2010

Я не слишком хорошо все это проверил, но, кажется, ниже работает:

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

Имейте в виду, однако, что это с радостью прочитает текстовую строку размером 100 ГБ, поэтому следует позаботиться о том, чтобы это был не DoS-вектор из ненадежных исходных файлов или сокетов.

0 голосов
/ 02 марта 2009

Попробуйте библиотеку наддува - я считаю, что она имеет функцию для создания fstream из ФАЙЛА *

или вы можете использовать fileno (), чтобы получить стандартный дескриптор C-файла из FILE, а затем использовать fstream :: attach для присоединения потока к этому файлу. Оттуда вы можете использовать getline () и т. Д. Примерно так:

FILE *condorData = _popen ("condor_q", "r");
std::ifstream &stream = new std::ifstream();
stream.attach(_fileno(condorData));
0 голосов
/ 02 марта 2009

Вы правы, что не можете читать напрямую в std::string, потому что оба метода c_str и data возвращают константные указатели. Вы могли бы читать в std::vector<char> вместо.

Вы также можете использовать функцию getline. Но для этого требуется объект iostream, а не указатель C FILE. Вы можете перейти от одного к другому, однако, в зависимости от поставщика. См. « Удобное руководство по работе с дескрипторами », где приведена схема и некоторые советы о том, как перейти от одного типа файла к другому. Вызовите fileno вашего FILE*, чтобы получить числовой дескриптор файла, а затем используйте fstream::attach, чтобы связать его с объектом fstream. Тогда вы можете использовать getline.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...