C++ Help. Strings and things.

27 Aug 2011

Hi all,..

ok, I'm still playing with this file transfer mbed->pc routine. I'm this -> <- close, but my C++ has let me down.

I've trawled the internet, to no avail.

I have a bunch of values sitting in an Eeprom, and I want to make them into one MASSIVE string. (about 6k)

that can be sent back from an RPC Call. The mechanism works.. (I have written a java utility that requests the file from mbed and then saves it down to disk on the pc, and it works)

EXCEPT, the following C code is soooo slow, that my mbed crashes. (it's doing other interrupt stuff).

anyway.. could someone help me to rewrite what is below, into proper code please. (except I need to up the loop to about 1000 values)

char* sendFile() {

    string c;
    c = 0x02; //start of transmission string : It's listening for this at the other end.

    float f;
    char* num;
    string b;
        
    for (int i = 30; i > 0  ; i--) {
        f = getEepromStoreValue24(i); //returns a float from the Eeprom.
        num = ftostr(f);
        b = num;
        c+=b;
        c+="\r\n";
    }

    c += 0x04; //End of transmission. (it's listening for it)

    char* p = (char*)b.c_str();
    return p;
}

char* ftostr(float myfloat) {
    char ans[20];
    snprintf(ans, 20, "%f", myfloat);
    return ans;
}


28 Aug 2011

Dave:

I don't think your code does what you think it does. The code below is what I think you are trying to do.

I wrote this very quickly and didn't test it, but you can use it as a starting point:

#include "sstream"
char* sendFile() {
    static char* workstring;                            // This must be static to assure persistence
    ostringstream FloatOut(0x02);                       // Create and initialize an output string stream
    for (int i = 30; i>0; i--)
        FloatOut << getEepromStoreValue24(i) << "\r\n"; // You can change the formatting of FloatOut as needed
    FloatOut << 0x04;                                   // Write your end of transmission byte
    delete[] workstring;                                // Clean up any workstrings from prior calls to sendFile
    workstring = new char[FloatOut.str().size()+1];     // Create an area to store the returned char string plus the terminating 0
    strcpy(workstring, FloatOut.str().c_str());         // Copy the accumulated values from a "C" string derived from a "C++" object string, derived from the output string stream
    return(workstring);
    }

Harry

28 Aug 2011

That's brilliant, thankyou,

I can follow every step of what you are doing there, and it looks exactly what I want to do. My problem was that I was converting everything to strings in order to concatenate it. I just didn't know the correct way to do that in C++.

I'm used to working in Cobol or Java, which have the power of a mainframe or our webserver behind them. So in either, I would think nothing of concatenating 1000 strings, but that doesn't quite work in the embedded world.

thanks again,..

I shall be testing that shortly.

cheers,

Dave.

28 Aug 2011

COBOL!

Wow!!! This post should go to the classics!

28 Aug 2011

There's nowt wrong with COBOL for large batch processes ;-) they've not come up with anything better yet.

30 Aug 2011

Hi all..

  ostringstream FloatOut(0x02);                       // Create and initialize an output string stream
    FloatOut << int(2);
    FloatOut << (int)2;
    FloatOut << 0x02;
    FloatOut << hex << int(2);
    FloatOut << hex << 0x02;
    FloatOut << hex << dec << 2;

These ALL put ASCII 50 into the output stream. (char "2") and I want to put an ASCII 2 in the output stream, i.e. hex02. Google is not my friend..

any ideas what I am doing wrong ?

cheers,

Dave.

30 Aug 2011

Hi Dave,

The happy little island I live on (Manhattan) was hit by hurricane Irene and I don't have power back yet so I cannot try running any mbed programs and I can only get on the Internet infrequently by imposing on friends or using public WiFi with a notebook computer.

Try this:

FloatOut << (char)0x02;

By casting the number 2 to a character type the overloaded stream operator (<<) will not try to convert the byte from a number 2 (0x02) to a character 2 (0x32).

You may also have to explicitly specify an openmode in the string stream declaration:

ostringstream FloatOut(ostringstream::binary);

or

ostringstream FloatOut(ostringstream::out);

I have found that there is a certain degree of implementation dependency on how the string stream constructor needs to be specified.

Also, there is an open source COBOL to C++ translator (http://sourceforge.net/projects/bol2cpp/). I don't recommend this approach.

Using this I have written parts of mbed programs in COBOL. Usually you'll have to manually fix up the C++ the cross compiler produces. This approach makes sense only if you're interfacing to an existing COBOL program, not if you're writing from scratch...unless you do it for fun.

Harry

30 Aug 2011

Brilliant, that works a treat. I'll make my Java utility more generic, and then publish it and the mbed side code as a way of sending stuff over from mbed to a pc.

Many thanks for the help,

Dave.

17 Jul 2012

C++ n00b here too. I have a similar challenge. I'm trying to return some dynamic content in a custom http handler.

The following freezes my MBED chip.

  // construct the info to return

  static char* resp;
  int myInt = 10;
  std::stringstream ss;
  ss << "sample data " << myInt << " times over";
  delete[] resp;
  resp = new char[ss.str().size()+1];
  strcpy(resp, ss.str().c_str());

  // if I use this commented line instead of the steps above, it works:
  //const char* resp = "Hello world from CommHandler!";
   
  // output the response chars.
  setContentLen( strlen(resp) );
  respHeaders()["Connection"] = "close";
  writeData(resp, strlen(resp));

Here are my import statements

#include <string.h>
#include <sstream>
#include <stdio.h>

notes:

  • Using ostringstream freezes as well.
  • The code compiles and runs well in codeblocks on windows PC.

could someone please help me, or show a better way?