user32219: I'm trying to send each character of a string object to a subroutine. I'm using the following code to do this, but it doesn't work:
string sInput = "some text"
for (int i=1; i < sInput.length(); i++) {
  showLetter(sInput.substring(i, i));
}

Subroutine:
void showLetter(String sInput)

My belief is that this should be iterating through the string and selecting one character (not to be confused with a char) at a time and sending it to the subroutine.
I haven't used C++ for 30 years and I am having difficulty finding why this won't work. I understand that I could use a char array, but I wanted to use this method.
If C++/Arduino coding doesn't work this way, to get credit you MUST explain why not.
Any help would be appreciated.
entire code follows...
/*
visual morse code

a dot is 1 unit
a dash is 3 units
  space between parts of the same letter is one unit
the space between letters is 3 units
the space between words is 7 units
*/

void parseString(String sInput);
void showletter(char sInput);
void dot(void); //dot
void dash(void);  //dash
void letterSeparator(void); //between letters
void wordSeparator(void); //space
int baseUnitLength = 100;

// the setup function runs once when you press reset or power the board
void setup(){
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop(){
  //call a routine with a string.  
  //the routine parses the string and blinks the dot and dash for morse code for each character

  parseString("sos ");


  //showLetter("s");
  //showLetter("o");
  //showLetter("s");
  //showLetter(" ");
}

void parseString(String sInput)
{
  for (int i=1; i<sInput.length(); i++){
    showLetter(sInput.substring(i,i));
  }
}
void showLetter(String sInput){
  if (sInput == "a")
    {
      dot();
      dash();
      letterSeparator();
    }
  else if (sInput == "b")
    {
      dash();
      dot();
      dot();
      dot();
      letterSeparator();
    }
  else if (sInput == "s")
    {
      dot();
      dot();
      dot();
      letterSeparator();
    }
  else if (sInput == "o")
    {
      dash();
      dash();
      dash();
      letterSeparator();
    }
  else if (sInput == " ")
    {
      wordSeparator();
    }
}
void dot(){
    digitalWrite(LED_BUILTIN, HIGH);   
    delay(baseUnitLength);                       
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength);                       
  }
void dash(){
    digitalWrite(LED_BUILTIN, HIGH);   
    delay(baseUnitLength * 3);                       
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength);                       
  }
void letterSeparator(){
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength * 3);                       
  }
void wordSeparator(){
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength * 6);                       
  }


user32219: Mr. jfpoilpret provided me with the answer and should be credited, as such.
It appears the subString function needs to have 1 added to the second parameter in order to properly reference the number of characters you need in the String.
In my case, iterating through a String and referencing only one character at a time means I need to do the following sInput.substring(i,i+1)
Also, the String object uses a zero based index.
EX:
   String sString = "This is a peach.";
   sString.substring(0,4)     //should return "This"
   sString.substring(8,9)     //should return "a"
   sString.substring(15,16)   //should return "."
In addition, you could also use the String function charAt (EX: sString.charAt(i)).
The charAt returns a char and if you are passing it to a function/sub you need to make sure the function/sub is expecting a char data type.
Also, it is easier to use a switch case when using the charAt function, as you don't have to do a conversion from String to char, as switch case does not work with Strings.

user7508: You got your answer, and you understood how this works. However, your
sentence “It appears the subString function needs to have 1 added to
the second parameter [...]” makes me believe you find this behavior
somewhat contrived, whereas it should be intuitive to any C or C++
programmer.
As I think this may help, I will share here the mental picture I use for
thinking about array indices. I call it the “L-shaped cursor”, and it
goes like this:
An array index can represent two different things:

a particular cell within the array
an “edge” of a cell, i.e. either the limit between two cells or an
edge of the whole array.

This is depicted in following picture of an array of length N, where
the numbers above it are the edge indices and the numbers below are the
cell indices. i and j are just two particular indices:
0   1   2           i           j               N
┌───┬───┬───┬───────┰───┬───────┰───┬───────┬───┐
│   │   │   │  ⋅⋅⋅  ┃   │  ⋅⋅⋅  ┃   │  ⋅⋅⋅  │   │
└───┴───┴───┴───────┺━━━┵───────┺━━━┵───────┴───┘
  0   1   2           i           j          N−1

Since each index can represent two things, I like to think about them as
being L-shaped cursors, like the ones I've drawn in bold for the indices
i and j.
Now, if you think about the purpose of the substring() method, it's
job is to cut a slice along the string, and you need to tell it where to
place the “knife”. Since the knife will cut along edges, it's perfectly
natural to use edge indices for that. Then
someString.substring(i, j)

will give you the slice of the string that lies between the edges i
and j. Looking at the picture above you can see this includes the cell
numbered i but not the one numbered j.
I hope this picture helps you find the behavior of substring() more
natural now. It does help me avoid fencepost
errors.

32219: <p>I'm trying to send each character of a string object to a subroutine. I'm using the following code to do this, but it doesn't work:</p>

<pre><code>string sInput = "some text"
for (int i=1; i &lt; sInput.length(); i++) {
  showLetter(sInput.substring(i, i));
}
</code></pre>

<p>Subroutine:</p>

<pre><code>void showLetter(String sInput)
</code></pre>

<p>My belief is that this should be iterating through the string and selecting one character (not to be confused with a char) at a time and sending it to the subroutine.</p>

<p>I haven't used C++ for 30 years and I am having difficulty finding why this won't work. I understand that I could use a char array, but I wanted to use this method.</p>

<p>If C++/Arduino coding doesn't work this way, to get credit you MUST explain why not.</p>

<p>Any help would be appreciated.</p>

<p>entire code follows...</p>

<pre><code>/*
visual morse code

a dot is 1 unit
a dash is 3 units
  space between parts of the same letter is one unit
the space between letters is 3 units
the space between words is 7 units
*/

void parseString(String sInput);
void showletter(char sInput);
void dot(void); //dot
void dash(void);  //dash
void letterSeparator(void); //between letters
void wordSeparator(void); //space
int baseUnitLength = 100;

// the setup function runs once when you press reset or power the board
void setup(){
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop(){
  //call a routine with a string.  
  //the routine parses the string and blinks the dot and dash for morse code for each character

  parseString("sos ");


  //showLetter("s");
  //showLetter("o");
  //showLetter("s");
  //showLetter(" ");
}

void parseString(String sInput)
{
  for (int i=1; i&lt;sInput.length(); i++){
    showLetter(sInput.substring(i,i));
  }
}
void showLetter(String sInput){
  if (sInput == "a")
    {
      dot();
      dash();
      letterSeparator();
    }
  else if (sInput == "b")
    {
      dash();
      dot();
      dot();
      dot();
      letterSeparator();
    }
  else if (sInput == "s")
    {
      dot();
      dot();
      dot();
      letterSeparator();
    }
  else if (sInput == "o")
    {
      dash();
      dash();
      dash();
      letterSeparator();
    }
  else if (sInput == " ")
    {
      wordSeparator();
    }
}
void dot(){
    digitalWrite(LED_BUILTIN, HIGH);   
    delay(baseUnitLength);                       
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength);                       
  }
void dash(){
    digitalWrite(LED_BUILTIN, HIGH);   
    delay(baseUnitLength * 3);                       
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength);                       
  }
void letterSeparator(){
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength * 3);                       
  }
void wordSeparator(){
    digitalWrite(LED_BUILTIN, LOW);    
    delay(baseUnitLength * 6);                       
  }
</code></pre>
 32219: <p>Mr. jfpoilpret provided me with the answer and should be credited, as such.
It appears the subString function needs to have 1 added to the second parameter in order to properly reference the number of characters you need in the String.<br>
In my case, iterating through a String and referencing only one character at a time means I need to do the following sInput.substring(i,i+1)
Also, the String object uses a zero based index.
EX:<br>
   String sString = "This is a peach.";
   sString.substring(0,4)     //should return "This"
   sString.substring(8,9)     //should return "a"
   sString.substring(15,16)   //should return "."</p>

<p>In addition, you could also use the String function charAt (EX: sString.charAt(i)).
The charAt returns a char and if you are passing it to a function/sub you need to make sure the function/sub is expecting a char data type.
Also, it is easier to use a switch case when using the charAt function, as you don't have to do a conversion from String to char, as switch case does not work with Strings.</p>
 7508: <p>You got your answer, and you understood how this works. However, your
sentence “<em>It appears the subString function needs to have 1 added to
the second parameter [...]</em>” makes me believe you find this behavior
somewhat contrived, whereas it should be intuitive to any C or C++
programmer.</p>

<p>As I think this may help, I will share here the mental picture I use for
thinking about array indices. I call it the “L-shaped cursor”, and it
goes like this:</p>

<p>An array index can represent two different things:</p>

<ul>
<li>a particular cell within the array</li>
<li>an “edge” of a cell, i.e. either the limit between two cells or an
edge of the whole array.</li>
</ul>

<p>This is depicted in following picture of an array of length <code>N</code>, where
the numbers above it are the edge indices and the numbers below are the
cell indices. <code>i</code> and <code>j</code> are just two particular indices:</p>

<pre><code>0   1   2           i           j               N
┌───┬───┬───┬───────┰───┬───────┰───┬───────┬───┐
│   │   │   │  ⋅⋅⋅  ┃   │  ⋅⋅⋅  ┃   │  ⋅⋅⋅  │   │
└───┴───┴───┴───────┺━━━┵───────┺━━━┵───────┴───┘
  0   1   2           i           j          N−1
</code></pre>

<p>Since each index can represent two things, I like to think about them as
being L-shaped cursors, like the ones I've drawn in bold for the indices
<code>i</code> and <code>j</code>.</p>

<p>Now, if you think about the purpose of the <code>substring()</code> method, it's
job is to cut a slice along the string, and you need to tell it where to
place the “knife”. Since the knife will cut along edges, it's perfectly
natural to use edge indices for that. Then</p>

<pre><code>someString.substring(i, j)
</code></pre>

<p>will give you the slice of the string that lies between the edges <code>i</code>
and <code>j</code>. Looking at the picture above you can see this includes the cell
numbered <code>i</code> but not the one numbered <code>j</code>.</p>

<p>I hope this picture helps you find the behavior of <code>substring()</code> more
natural now. It <em>does</em> help me avoid <a href="https://en.wikipedia.org/wiki/Off-by-one_error#Fencepost_error" rel="nofollow noreferrer">fencepost
errors</a>.</p>
