FILE * and istream: connect the two?

Asked
Active3 hr before
Viewed126 times

6 Answers

connect
90%

You can get away by deriving std::basic_streambuf or std::streambuf classes. Something along these lines:,Asking for help, clarification, or responding to other answers., Why do we ignore the second-order terms in the following expansion? ,Connect and share knowledge within a single location that is structured and easy to search.

You can get away by deriving std::basic_streambuf or std::streambuf classes.
Something along these lines:

#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;
}
88%

Connect to Amazon EC2 file directory using FileZilla and SFTP, Video Tutorial,Suppose I "popen" an executable, I get a FILE* in return. Furthermore, suppose I'd like to "connect" this file to an istream object for easier processing, is there a way to do this?,Check this post if you have any permission issues.,Note: FileZilla automatically figures out which key to use. You do not need to specify the key after importing it as described above.

Popen doesn't capture stderr only stdout. Redirecting stderr to stdout fixes the issue.

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    std::string command("ls afskfksakfafkas 2>&1");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result << std::endl;
    std::cout << returnCode << std::endl;

    return 0;
}
load more v
72%

The second constructor initializes the base class by calling move(right). It also stores right.gcount() in the extraction count and stores zero in the extraction count for right*.,After the function extracts an element that compares equal to delimiter. In this case, the element is put back to the controlled sequence.,After the function extracts an element that compares equal to delimiter. In this case, the element is put back to the controlled sequence. ,Both groups of functions call setstate(eofbit) if they encounter end of file while extracting elements.

Syntax

template <class Char_T, class Tr=char_traits<Char_T>>
   class basic_istream : virtual public basic_ios<Char_T, Tr>
load more v
65%

classes: iostream istream wiostream wistream ,class templates: basic_iostream basic_istream ,Input/Output: <fstream> <iomanip> <ios> <iosfwd> <iostream> <istream> <ostream> <sstream> <streambuf> ,protected members: istream::operator= istream::swap

streampos tellg();
load more v
75%

Two specializations for common character types are defined: ,The following constants are also defined: ,Two global basic_istream objects are provided by the standard library. ,6 Inherited from std::basic_ios 6.1 Member types 6.2 Member functions 6.2.1 State functions 6.2.2 Formatting 6.2.3 Miscellaneous

<istream>
load more v
40%

Oftentimes, you’ll want to get user input but not discard whitespace. To do this, the istream class provides many functions that can be used for this purpose.,The iostream library is fairly complex -- so we will not be able to cover it in its entirety in these tutorials. However, we will show you the most commonly used functionality. In this section, we will look at various aspects of the input class (istream).,One important thing to note about get() is that it does not read in a newline character! This can cause some unexpected results:,This program will now only read the first 9 characters out of the stream (leaving room for a terminator). Any remaining characters will be left in the stream until the next extraction.

When reading strings, one common problem with the extraction operator is how to keep the input from overflowing your buffer. Given the following example:

char buf[10];
std::cin >> buf;
load more v

Other "connect-undefined" queries related to "FILE * and istream: connect the two?"