@Ketan
... повышает пропущенную деталь относительно намерения по сравнению с производительностью. Существуют времена, когда мы хотим использовать проход ++ вместо ++ проход.
, Очевидно, сообщение и преинкремент имеют различную семантику, и я уверен, что все соглашаются, что, когда результат используется, необходимо использовать соответствующий оператор. Я думаю, что вопрос - то, что должно каждый делать, когда результат отбрасывается (как в for
циклы). Ответ на этот вопрос (по моему скромному мнению), состоит в том, что, так как соображения производительности незначительны в лучшем случае необходимо сделать то, что является более естественным. Для меня ++i
является более естественным, но мой опыт говорит мне, что я нахожусь в меньшинстве, и использование i++
вызовет меньше металла наверху для большинство люди, читающие Ваш код.
, В конце концов, это - причина, которой язык не называют" ++C
". [*]
[*] Вставляют обязательное обсуждение [приблизительно 114] являющиеся более логическим именем.
Стандартного способа не существует, но если вам нужно быстрое решение, вы можете получить дескриптор файла с помощью fileno (), а затем использовать Josuttis ' fdstream . Могут быть подобные попытки, но я использовал это в далеком прошлом, и он работал нормально. По крайней мере, это должна быть очень хорошая карта для реализации вашего собственного.
Sure there's a way, implement your own istream
that can be constructed from a FILE*
.
If you're asking whether there is a standard way to do this, then no.
Вы можете уйти, создав классы std :: basic_streambuf или std :: streambuf.
Что-то вроде этого:
#include <stdio.h>
#include <iostream>
#define BUFFER_SIZE 1024
class popen_streambuf : public std::streambuf {
public:
popen_streambuf() : fp(NULL) {
}
~popen_streambuf() {
close();
}
popen_streambuf *open(const char *command, const char *mode) {
fp = popen(command, mode);
if (fp == NULL)
return NULL;
buffer = new char_type[BUFFER_SIZE];
// It's good to check because exceptions can be disabled
if (buffer == NULL) {
close();
return NULL;
}
setg(buffer, buffer, buffer);
return this;
}
void close() {
if (fp != NULL) {
pclose(fp);
fp = NULL;
}
}
std::streamsize xsgetn(char_type *ptr, std::streamsize n) {
std::streamsize got = showmanyc();
if (n <= got) {
memcpy(ptr, gptr(), n * sizeof(char_type));
gbump(n);
return n;
}
memcpy(ptr, gptr(), got * sizeof(char_type));
gbump(got);
if (traits_type::eof() == underflow()) {
return got;
}
return (got + xsgetn(ptr + got, n - got));
}
int_type underflow() {
if (gptr() == 0) {
return traits_type::eof();
}
if (gptr() < egptr()) {
return traits_type::to_int_type(*gptr());
}
size_t len = fread(eback(), sizeof(char_type), BUFFER_SIZE, fp);
setg(eback(), eback(), eback() + (sizeof(char_type) * len));
if (0 == len) {
return traits_type::eof();
}
return traits_type::to_int_type(*gptr());
}
std::streamsize showmanyc() {
if (gptr() == 0) {
return 0;
}
if (gptr() < egptr()) {
return egptr() - gptr();
}
return 0;
}
private:
FILE *fp;
char_type *buffer;
};
int main(int argc, char *argv)
{
char c;
popen_streambuf sb;
std::istream is(&sb);
if (NULL == sb.open("ls -la", "r")) {
return 1;
}
while (is.read(&c, 1)) {
std::cout << c;
}
return 0;
}