2009-03-02 3 views
1

Описание:Альтернатива fgets()?

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

Примечание:

  • не будет компилировать, в связи с fgets() декларация

Вопрос:

  • Что является лучшей альтернативой fgets, так как fgets требует символ *?
  • Есть ли лучшая альтернатива?

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

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

ответ

4

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

Однако в вашем случае, вы должны использовать символ [], чтобы читать в ,

например

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

Не работает с файлом * – 2009-03-02 17:07:09

+0

ya, я перечитал вопрос и понял, что это труба. – sfossen

1

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

char buffer[MY_MAX_SIZE] 

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

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

- MarkusQ

0

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

Вы также можете использовать функцию getline. Но для этого требуется объект iostream, а не указатель C FILE. Вы можете перейти от одного к другому, тем не менее, в зависимости от поставщика. См. «A Handy Guide To Handling Handles» для диаграммы и некоторые предложения о том, как перейти из одного типа файла в другой. Позвоните fileno на свой FILE*, чтобы получить числовой дескриптор файла, а затем используйте fstream::attach, чтобы связать его с объектом fstream. Затем вы можете использовать getline.

+0

Но заметьте, что вектор не будет расти, как я думаю, OP ожидает – 2009-03-02 17:17:10

0

Попробуйте библиотеку Boost - Я считаю, что она имеет функцию для создания fstream из файла *

или вы могли бы использовать fileno(), чтобы получить стандартную ручку C файла из файла, а затем использовать fstream :: attach, чтобы прикрепить поток к этому файлу. Оттуда вы можете использовать GetLine() и т.д. Что-то вроде этого:

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

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

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

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