# Converting a string to a char array without using extra memory

#### dr pepper

##### Well-Known 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.

#### Nigel Goodwin

##### Super Moderator
You might mention what language you're using - as in C a string IS a char array.

You might also mention the processor, as that's an awful lot of RAM.

Sorry,
C++
ESp32

#### DrG

##### Active Member
Might be me but I'm struggling to find a means of deleting either the last or first character in a string.
Can you post the code where this is happening?

#### Nigel Goodwin

##### Super Moderator
Plenty of examples then:

#### 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
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
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
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
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:
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
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"
"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
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
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

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
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.

#### Nigel Goodwin

##### Super Moderator
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.
Pascal strings are a lot faster, but much more limited in size.

#### dr pepper

##### Well-Known 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"
"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"
"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
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

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