Save String.charAt() to int

Hi, I need to parse String and save number to int array. At input I have s = E225@ a = "E" My code:

int tempC[3];
void parseTemp(String s, char a) {
  byte pos=0;
  switch ( a ) {
    case 'E':
      pos=0;
      break;
    case 'F':
      pos=1;
      break;
    case 'G':
      pos=2;
      break;
    default:
      break;    
  }  
  tempC[pos] = strtol(s.charAt(1), NULL, 10);   // line 187
}

This should make tempC[0] = 225.

Compile produce an error:

arduino.ino: In function ‘void parseTemp(String, char)’:
arduino:187: error: invalid conversion from ‘char’ to ‘const char*’
arduino:187: error: initializing argument 1 of ‘long int strtol(const char*, char**, int)’

What I do bad?

Function need to obtain a pointer to the string (e.g. &s[1]) not a character.

What I do bad?

To give a proper answer we need to see your whole program or an example that illustrates the problem.

More generally, you will be advised to use C style strings instead of Strings as they can cause less problems in the limited memory available to most Arduinos.

Budvar10: Function need to obtain a pointer to the string (e.g. &s[1]) not a character.

I don't see any strings in the code snippet. A String, yes but no strings.

s.charAt(1) returns a single character (whatever the second character is). The function strtol expects a string pointer (not just a single character)

The Strings class on the arduino can be a PIA. It's better to use char arrays.

Now if S was a char array, you could rewrite that function as

void parseTemp(char *s, char a) {
  byte pos=0;
  switch ( a ) {
    case 'E':
      pos=0;
      break;
    case 'F':
      pos=1;
      break;
    case 'G':
      pos=2;
      break;
    default:
      break;    
  }  
  tempC[pos]=atol(s+1);      //simples :)

  }
String s = "E225@";
char a = 'E';
int tempC[3];

void parseTemp(String s, char a) {
  byte pos=0;
  switch ( a ) {
    case 'E':
      pos=0;
      break;
    case 'F':
      pos=1;
      break;
    case 'G':
      pos=2;
      break;
    default:
      break;    
  }  
  tempC[pos] = strtol(s.charAt(1), NULL, 10);   // line 187
}

parseTemp(s, a);
tempC[pos] = strtol(&s.charAt(1), NULL, 10);   // line 187
tempC[pos] = strtol(*s.charAt(1), NULL, 10);   // line 187

do not work:

arduino.ino: In function ‘void parseTemp(String, char)’:
arduino:187: error: lvalue required as unary ‘&’ operand
arduino.ino: In function ‘void parseTemp(String, char)’:
arduino:187: error: lvalue required as unary ‘&’ operand
  char* tmp = s.charAt(1);
  tempC[pos] = strtol(tmp, NULL, 10);
arduino.ino: In function ‘void parseTemp(String, char)’:
arduino:187: error: invalid conversion from ‘char’ to ‘char*’

The answer is QUIT USING THE String CLASS!

What part of that don't you understand?

All the String remarks are really valid, so give them the attention they deserve

still something like this should do the job

#include <ctype.h>

String s = "E225@";

int x = 0;
int index = 0;
while (s.charAt(index) != '@')
{
  if ( isdigit(s.charAt(1)) ) 
  {
    x *= 10;
    x += s.charAt(index) - '0';
  }
  index++;
}

Code: (not tested)

Yes, it has an issue.

Hi, I need to parse String and save number to int array.

Some test code that captures a numeric value from a character string sent to the arduino.

//zoomkat 10-16-14 simple delimited '@' string parse 
//from serial port input (via serial monitor)
//and print result out serial port

String readString, subString;

void setup() {
  Serial.begin(9600);
  Serial.println("String parse test"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like E225@, F225@, or G225@
  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == '@') {
      if (readString.length() >0) {
        Serial.println(readString); //prints string to serial port out
        subString = readString.substring(1); //skips first character in readString
        int n = subString.toInt();  //convert subString into a number

        if(readString.indexOf('E') >-1) {
          Serial.print("E value is: ");
          Serial.println(n);
        }
        if(readString.indexOf('F') >-1) {
          Serial.print("F value is: ");
          Serial.println(n);
        }
        if(readString.indexOf('G') >-1) {
          Serial.print("G value is: ");
          Serial.println(n);
        }        

        //do stuff with the captured subString 
        
        readString=""; //clears variable for new input
        subString="";
      }
    }  
    else {     
      readString += c; //makes the String readString
    }
  }
}

@UKHeliBob

Function need to obtain a pointer to the string (e.g. &s[1]) not a character.

I don't see any strings in the code snippet. A String, yes but no strings.

Really? It is not about the String but about "pointer to the string" , (const char *) or (char *) in other words in C language (string = chain of characters).

@martin159

tempC[pos] = strtol(&s.charAt(1), NULL, 10);   // line 187
tempC[pos] = strtol(*s.charAt(1), NULL, 10);   // line 187

Wrong.

char* tmp = s.charAt(1);
  tempC[pos] = strtol(tmp, NULL, 10);

Wrong. Function charAt() returns a character at some position in buffer of String object. It is a copy of real memory cell so no witchery with the pointers can help. Function strtol() expects pointer to the string, a (const char *) - address of real memory place to be able go throughout character sequence controlled by String object. The &s[] does it.

tempC[pos] = strtol(&s[1], NULL, 10);

Should work fine. There is function c_str() which returns a pointer to the string.

char* tmp = (char *)s.c_str();
    tmp += 1;
    tempC[pos] = strtol(tmp, NULL, 10);

Should work also.

I don't see any strings in the code snippet. A String, yes but no strings. Really? It is not about the String but about "pointer to the string" , (const char *) or (char *) in other words in C language (string = chain of characters).

Here is the code posted by the OP

int tempC[3];
void parseTemp(String s, char a) {
  byte pos=0;
  switch ( a ) {
    case 'E':
      pos=0;
      break;
    case 'F':
      pos=1;
      break;
    case 'G':
      pos=2;
      break;
    default:
      break;    
  }  
  tempC[pos] = strtol(s.charAt(1), NULL, 10);   // line 187
}

Where is the string in that ?