• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Converting a string to a char array without using extra memory

dr pepper

Well-Known Member
Most Helpful Member
I have a string I want to turn into a char array.
I realise toCharArray() will do this, but I'm limited with memory, the string is 35k bytes long, so I cant just convert as that would take 70k of ram.
So I want to convert each character, and each time delete one off the string as its ocnverted, this is fine as I dont need the string after.
Might be me but I'm struggling to find a means of deleting either the last or first character in a string.
 

DrG

Active Member
But that example and many others assume it is ok to have both the string and the char array existing at the same time. If I understand, the OP does not want that. The string is 35K and he wants to build the char array while decreasing the string size (and freeing memory) such that during the operation he is using no more than 35K (plus the overheads) ending up with only the char array.
 

rjenkinsgb

Well-Known Member
Most Helpful Member
You can use
stringname.c_str();

to return a character pointer to the character array contained within the C++ string.
Set a second pointer to that + the string length for the end.

Adjust those inward (and set the *end to zero any time you do move that in) to trim the ends.
The start pointer is functionally the array[].

The only things you cannot do are make it bigger; or reclaim the space, until the string is removed & it's handler reclaims the total space.
 

dr pepper

Well-Known Member
Most Helpful Member
I think I get that, kinda redefining the array without affecting the contents, 'cept for those you want to remove.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
I realise toCharArray() will do this, but I'm limited with memory, the string is 35k bytes long,
Not really a platform for C++. In C++ strings are objects and realistically only private functions have access to the string pointer.

When I use a C++ platform, I still use C syntax.. perfectly vaild..

Using stringname.c_str(), as Mr Jenkins already said, will grant you access to that portion of memory, but I'm not sure if you can operate on it.. Not without a "friend" function... I maybe wrong... I often am... But you still wont have your own array at the end...

Why don't you use a smaller array and parse the string section by section...
 

dr pepper

Well-Known Member
Most Helpful Member
Thats what I'm working on.
There are 5 measurements, so I can send each one as a chunk in the json reply.
Only I'm having trouble with that, the code I'm using is:
http_err_t send_reply_chunk(*p, buffer sizeof(buffer)
Only its not doing as expected, its sending the buffer with a load of junk ahead of it, I dont think the *p pointer is pointing to the right place.
Finding data on the esp32 server module isnt that easy.
 

Pommie

Well-Known Member
Most Helpful Member
Just tried sending your last reply to the serial monitor 50 bytes at a time. Note, this was ESP8266. As long as you can write to the string this should work.

Mike.
Code:
String Bigun =  "Thats what I'm working on.\n"
                "There are 5 measurements, so I can send each one as a chunk in the json reply.\n"
                "Only I'm having trouble with that, the code I'm using is:\n"
                "http_err_t send_reply_chunk(*p, buffer sizeof(buffer)\n"
                "Only its not doing as expected, its sending the buffer with a load of junk ahead of it, I dont think the *p pointer is pointing to the right place.\n"
                "Finding data on the esp32 server module isnt that easy.\n"
                "Red to black, black to red and blue to bits.\n";

void setup() {
  Serial.begin(115200);
  Serial.println();
}

#define len 50

void loop() {
char *p;
char temp;
  p=(char*)Bigun.c_str();
  while(strlen(p)>len){
    temp=*(p+len);
    *(p+len)=0;
    Serial.print (p);
    *(p+len)=temp;
    p=p+len;
  }
  Serial.print(p);
  while(1){
      delay(1);
  }
}
 

dr pepper

Well-Known Member
Most Helpful Member
An elegant piece of code.
I get that, .c_str() is new to me.
I suspected but didnt know clearing the last byte of a array shortens said array.
Thanks for that I'll work on that one.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
An elegant piece of code.
I get that, .c_str() is new to me.
I suspected but didnt know clearing the last byte of a array shortens said array.
Thanks for that I'll work on that one.
An array (C style string) can be pretty well any length, and it's end is marked by a 0x00 byte - for the program to find how long the string is it has to run right through the string until it finds the 0x00 - moves the zero towards the front of the string, and you effectively shorten the string - but I've no idea how that will upset the memory handling?. Unlike Pascal style strings, where the first byte signifies how long the string is, so can only be 255 chars long.

There are advantages and disadvantages to both - but the Pascal method gives you a lot better string handling routines, but are limited to only small strings - so no good for your 35K requirement :D

As I recall, Delphi (Visual Pascal for Windows) provided use of both Pascal and C style strings, but you had to use them differently.
 

dr pepper

Well-Known Member
Most Helpful Member
For the system to 'know' how long a string is, it must run a check every time you write tot it.
I can see that being one of the reasons why strings are slow & memory intensive.
 

dr pepper

Well-Known Member
Most Helpful Member
I never got into pascal.
Or fortran.
 

DrG

Active Member
Just tried sending your last reply to the serial monitor 50 bytes at a time. Note, this was ESP8266. As long as you can write to the string this should work.

Mike.
Code:
String Bigun =  "Thats what I'm working on.\n"
                "There are 5 measurements, so I can send each one as a chunk in the json reply.\n"
                "Only I'm having trouble with that, the code I'm using is:\n"
                "http_err_t send_reply_chunk(*p, buffer sizeof(buffer)\n"
                "Only its not doing as expected, its sending the buffer with a load of junk ahead of it, I dont think the *p pointer is pointing to the right place.\n"
                "Finding data on the esp32 server module isnt that easy.\n"
                "Red to black, black to red and blue to bits.\n";

void setup() {
  Serial.begin(115200);
  Serial.println();
}

#define len 50

void loop() {
char *p;
char temp;
  p=(char*)Bigun.c_str();
  while(strlen(p)>len){
    temp=*(p+len);
    *(p+len)=0;
    Serial.print (p);
    *(p+len)=temp;
    p=p+len;
  }
  Serial.print(p);
  while(1){
      delay(1);
  }
}
Just a different point of view....
If you are going to use the String class, the reason would be that you want to use the operators and functions that the class offers. Otherwise, just stay with a string (i.e., a c string).

Given String, I would use this to do what you have done.

Code:
String Bigun =  "Thats what I'm working on.\n"
                "There are 5 measurements, so I can send each one as a chunk in the json reply.\n"
                "Only I'm having trouble with that, the code I'm using is:\n"
                "http_err_t send_reply_chunk(*p, buffer sizeof(buffer)\n"
                "Only its not doing as expected, its sending the buffer with a load of junk ahead of it, I dont think the *p pointer is pointing to the right place.\n"
                "Finding data on the esp32 server module isnt that easy.\n"
                "Red to black, black to red and blue to bits.\n";                

void setup() {
  Serial.begin(115200);
  Serial.println();
}

#define len 50

void loop() {
  int to=len,from=0;
  while(to<Bigun.length()){
    Serial.print(Bigun.substring(from,to));
    from=to;
    to+=len;
  }
  Serial.print(Bigun.substring(from));
  while(1){
      delay(1);
  }
}
Not saying there is a thing wrong with your code and it is, in fact, smaller on my machine using an ESP32 [probably faster too although I did not try and time it]. I could argue that mine is easier to read, but that can be a matter of preference. Just trying to make the point that if you bother to use String, use the advantages it offers.

BTW: I still do not know what the OP is actually trying to do.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
I never got into pascal.
Historically Pascal was what was taught at Universities, as it's a highly structured language, and a lot of modern languages are influenced by it. If you'd ever used the Borland Turbo Pascal compliers they were lightning fast, both in compiling the code, and the speed of the exe files. I once had occasion to use the Microsoft Pascal compiler - I couldn't believe how long it took to compile a program :D

I still hate curly brackets - I much prefered the Pascal Begin/End instead.
 

dr pepper

Well-Known Member
Most Helpful Member
Yep I've been hung on both brackets a few times.
 

Latest threads

EE World Online Articles

Loading

 
Top