Pages: [1]   Go Down
Author Topic: Convert String string1 to char*  (Read 12918 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

Sorry if the subject isn't right.. I'm quite new at programming in C/C++.. I've done a fair bit of PERL but it feels quite different with the variables.

This code works:
Code:
     char* filename = "file.txt";
      if (! file.open(&root, filename, O_READ)) {
         ........
       }

But I've used String (object) to contain the filename and this code does not.

Code:
     String filename = "file.txt"
      if (! file.open(&root, filename, O_READ)) {
          ......
      }

It produces this error

Code:
error: no matching function for call to 'SdFile::open(SdFile*, String&, const uint8_t&)'
/home/shawn/arduino/arduino-0019/libraries/SdFat/SdFat.h:220: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
/home/shawn/arduino/arduino-0019/libraries/SdFat/SdFat.h:221: note:                 uint8_t SdFile::open(SdFile*, const char*, uint8_t)
/home/shawn/arduino/arduino-0019/libraries/SdFat/SdFat.h:328: note:                 uint8_t SdFile::open(SdFile&, const char*, uint8_t)
/home/shawn/arduino/arduino-0019/libraries/SdFat/SdFat.h:332: note:                 uint8_t SdFile::open(SdFile&, const char*)
/home/shawn/arduino/arduino-0019/libraries/SdFat/SdFat.h:338: note:                 uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)

I thought that perhaps I needed to pass it the pointer reference to the String and I tried using

Code:
     String filename = "file.txt"
      if (! file.open(&root, filename.toCharArray(), O_READ)) {
          ......
      }

And I get this error

error: no matching function for call to 'String::toCharArray()'
/home/shawn/arduino/arduino-0019/hardware/arduino/cores/arduino/WString.h:80: note: candidates are: void String::toCharArray(char*, unsigned int)

Can someone be kind enough to explain to me what I'm doing wrong and how I can fix this?

Thank you.
« Last Edit: September 12, 2010, 07:52:13 pm by sholland » Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 5
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm quite new at programming in C/C++
Then either you will hate what I am going to say, or you will embrace the "learning opportunity."

I have done some C++ programming but I'm a newcomer to Arduino (I started with arduino-0018 a couple of months ago).  I have downloaded arduino-0019 and am just now starting to evaluate it, so I may be missing something.  See Footnote.

Anyhow, here's what I found so far:

In arduino-0018, there was no "String" class included in the Arduino core.  We could download a String library, "WString", and import it into our sketches.

In this library there was a String class member function called cstr(), which returned a const pointer to char.  The value of the pointer was the address of the buffer that actually holds the characters of the string.

Then we could use something like
Code:
String filenameString;  // Or maybe initialize with a C-style string literal
//
// Build up the string by using various String functions and operators.
//
// Then if you have a function that needs to use that string
// but it takes a parameter that is "const char *" you do it like this:
    if (! file.open(&root, filenameString.cstr(), O_READ)) {
        ........
    }

Alas, the developers of arduino-0019, when they rewrote the String class and included it in the Arduino core, chose not to give us the cstr() function.  Go figure.

Anyhow, the way that they did give us is, in my outsider's opinion, really inconvenient and inefficient.  They kept  the toCharArray() function from the previous version.

The function toCharArray() requires us to give it the name of an array of chars and a length parameter.  The size of the array must be large enough to hold all of the characters in the String object plus one more character to hold the terminating zero.   After all of that, the function copies the characters of the String object (and the terminating zero byte) to the array.  So you can do something like
Code:
   String filenameString; // or initialize it with a "literal"
.
.   // build up the file name string somehow
.
    char filename[100]; // Or something long enough to hold the longest file name you will ever use.
    filenameString.toCharArray(filename, sizeof(filename));
    if (! file.open(&root, filename, O_READ)) {
        ........
    }

Alternatively, you can add a "cstr()" function to arduino-0019/hardware/arduino/core/arduino/WString.h

Find the line that starts the //general methods declarations (It's line 56 in my Linux distribution)

Insert a line as follows
Code:
   // general methods // <=== this was line 56
    const char * cstr() const {return _buffer;} // This is the new function.
    char charAt( unsigned int index ) const; // <=== this was line 57

Now you should be able to use it like we used to:
Code:
   if (! file.open(&root, fileameString.cstr(), O_READ)) {
.
.
.


Regards,

Dave

Footnote:
If I am missing something, and there really is a convenient and efficient way that doesn't require modifying the arduino-0019 core library String class, I would appreciate some illumination on the subject.
« Last Edit: September 13, 2010, 03:37:04 am by davekw7x » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Dave,

Thanks for the detailed response. I will have to read over your reply more carefully. For now I was able to accomplish what I needed with:
Code:
     char filename[11];
      int i = 0;
      while (i <= string.length() -1) {
        if (i>11) {
           i = 11;
           break;
        }
        filename[i] = string.charAt(i);
        i++;
      }
      filename[i] = 0;
      if (! file.open(&root, filename, O_READ)) {
        .......
      }


--
Shawn
« Last Edit: September 13, 2010, 11:29:43 am by sholland » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
     char filename[100];
      filenameString.toCharArray(filename, 100);
      if (! file.open(&root, filename, O_READ)) {
          ......
      }

This is much better. Thank you.

I didn't realize that it took your string and "sent" it to a Char array.. The arduino documentation on this method is misleading.

http://arduino.cc/en/Reference/StringToCharArray

--
Shawn
Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 5
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@sholland:
Quote
The arduino documentation on this method is misleading
The wonders of open source:  The source code is available for our edification.  (See Footnote.)
Code:
void String::toCharArray(char *buf, unsigned int bufsize)
{
  if (!bufsize || !buf) return;
  unsigned int len = bufsize - 1;
  if (len > _length) len = _length;
  strncpy(buf, _buffer, len);
  buf[len] = 0;
}

It just copies the internal buffer contents to the char array that you supply.  Note that part of the description is not just "misleading."  It's flat wrong:
From the description: "Modifying the returned array will also modify the String itself." In fact, that is not true.  Nothing that you change in your array will change anything in the string itself.



Regards,

Dave

"The Source, Luke! Use the Source!"
---Obi-wan Arduino
« Last Edit: September 13, 2010, 12:51:44 pm by davekw7x » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually modifying the WString.h works more like how I want it to

Thanks again for this information. It's really helped.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I modified my WString.h and WString.cpp files to make toCharArray match the documentation.  Does anyone see a potential problem with this?

WString.h
Code:
char* toCharArray();

WString.cpp
Code:
char* String::toCharArray()
{
      return _buffer;
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46113
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Whatever you hand that pointer back to can modify the string. The initial toCharArray() makes a copy of the String contents.
Logged

Pages: [1]   Go Up
Jump to: