CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Feb 2002
    Location
    PA, USA
    Posts
    4

    STL: how to use a char array as an input stream

    My application receives BINARY word-aligned data via character arrays. In other words, the sending application has a struct containing floats, ints, chars, etc. and what the application does is basically memcpy the struct into a char buffer and sends that buffer to my application.

    My application recieves (a copy of) the buffer in a message, drops the buffer to a file, and then uses ifstream to open the file as a stream and reads data from it.

    My question is can I cut out the "dropping the buffer to a file" part and read data directly from the allocated char buffer as if it was a stream? If so, how do I set up the char buffer as an input stream?

    Thank you for your advice.

  2. #2
    Join Date
    Nov 2000
    Location
    tokyo-jp.
    Posts
    314
    Use std::stringstream.

    char *inputdata = GetCharBufData();

    std::stringstream s;
    s << inputdata;

    int i;
    s >> i;

  3. #3
    Join Date
    Jun 2002
    Posts
    1,417

    Re: STL: how to use a char array as an input stream

    Is this what you want to do?
    Code:
    typedef struct
    {
    	long	a;
    	double	b;
    	float	c;
    	char	buf[126];
    } DATA;
    
    int main(int argc, char* argv[])
    {
    	char iobuf[sizeof(DATA)];
    
    	// get iobuf from the stream
    	DATA* pData = reinterpret_cast<DATA*>(iobuf);
    	// now use pData 
    	return 0;
    }

  4. #4
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Originally posted by shridharng
    Use std::stringstream.

    char *inputdata = GetCharBufData();

    std::stringstream s;
    s << inputdata;

    int i;
    s >> i;
    This is absolutely correct. You can save line and use the
    constructor of s to initialize it with the char* too

  5. #5
    Join Date
    Feb 2002
    Location
    PA, USA
    Posts
    4
    First off, thank you for the replies. However, this:

    > Use std::stringstream.
    >
    > char *inputdata = GetCharBufData();
    >
    > std::stringstream s;
    > s << inputdata;
    >
    > int i;
    > s >> i;

    isnt exactly working. You see, the character data (inputdata) contains NULLs. The stringstream reads upto the NULL and stops. If I drop the buffer to a file and then read it as an ifstream, everthing works fine.

    What I am trying to do is reuse a method that takes in an ifstream and reads binary data from it. Like this:
    void myClass::Read(ifstream* inputStream)
    {
    //inputStream.read(data)
    //etc.
    }
    but this data can also arrive as a char buffer. So I changed the Read signature to expect an istream instead of an ifstream, and provided two constructors to the class like this:
    Read is now:
    void myClass::Read(istream* inputStream)
    //first constructor
    myClass(char* inputBuffer)
    {
    //create a stringstream as above from buffer
    //call Read with stringstream
    }

    //second constructor
    myClass(std::string inputFilename)
    {
    //create an ifstream using the inputFilename
    //call Read with ifstream
    }

    I always have the option of dropping the buffer to a temporary file and using the Read with the ifstream, but that seems wastefull to me.

    so what am I missing? Can I create an istream from a char buffer that ignores nulls?

  6. #6
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    I think there are a few problems. First, when initializing
    the stringstream with a char*, it stops at NULL. Second,
    you should read binary. One way around the NULL problem
    is to create a std::string from the buffer and use it in
    the stringstream (which increases memory requirements).
    With the following type of setup, you can use the same
    function to read the data, whether using stringstream
    or ifstream :

    Code:
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <iomanip>
    #include <fstream>
    
    using namespace std;
    
    template <class STRM>
    STRM & ReadData(STRM & strm)
    {
        int    ii;
        float  ff;
        double dd;
        int    jj;
    
        strm.read( (char*)(&ii),4);
        strm.read( (char*)(&ff),4);
        strm.read( (char*)(&dd),8);
        strm.read( (char*)(&jj),4);
    
        cout << "ii = " << ii << endl;
        cout << "ff = " << ff << endl;
        cout << "dd = " << setprecision(10) <<  dd << endl;
        cout << "jj = " << jj << endl;
    
        return strm;
    }
    
    int main()
    {
        char buf[20];
    
        int    i = 1;
        float  f = 3.14159f;
        double d = 2.718213452;
        int    j = 109;
    
        memcpy(&buf[0] ,&i,4);
        memcpy(&buf[4] ,&f,4);
        memcpy(&buf[8] ,&d,8);
        memcpy(&buf[16],&j,4);
    
        ofstream out("test.dat",ios::binary);
        out.write(buf,20);
        out.close();
    
        // read using stringstream 
    
        string strBuf(buf,buf+20);
    
        stringstream ss(strBuf);
        ReadData(ss);
    
        // read using file
    
        ifstream in("test.dat",ios::binary);
        ReadData(in);
        in.close();
    
    
        return 0;
    }
    Last edited by Philip Nicoletti; March 21st, 2003 at 04:48 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured