parameters of subroutine

Hello
I do not anderstand why when I modify a argument this is not working as I had expected

parameter 1 of the subroutine is a array of char
parameter 2 of the subroutine is an array of string that I wont to modiffy.

I can read the array but I cannot change them.
what am-I doing wrong?

char t1[14]="#aa-1-mod&"; // input

String duree_sv1 = "bbbbbbbbbbbbbbbbbb\0"; // should contain the codified value

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// send an intro:
Serial.println("\n\n subroutine parameters (char, string):");
Serial.println();
}

//
/////////////////////////////////////////////////
//
void aj_dt ( char tv[] , String sx )
{
int i=0;
Serial.print("avant tv= "); Serial.println(tv);
Serial.print("avant sx= "); Serial.println(sx);
sx="llllllllll"; // Modify sx output value
tv="fffffffffff";
}
///////

////////////////////////////////////////////
// Set up a String:
void loop() {

Serial.print("avant t1="); Serial.println(t1);
Serial.print("avant duree_sv1="); Serial.println(duree_sv1);

aj_dt ( t1, duree_sv1);

Serial.print("t1 apres s/r = "); Serial.println(t1);
Serial.print("duree_sv1 apres S/R ="); Serial.println(duree_sv1);
//

// apres l appel la variables reste inchangée pourquoi
//-----------------------------------------------------

// do nothing while true:
while (true);

}

To modify the content of a String object in a function, you must pass it as a reference.

void aj_dt ( char tv[] , String &sx  )

To modify the content of a cstring (an array of chars ended with a null), you must use special functions.

strcpy(tv, "fffffffffff");

Note: you must make sure your cstring is big enough or bad things will happen.

void aj_dt ( char tv[] , String sx )
{
.
.
.
}

I believe what you are doing here is making a copy of what ever array you pass in to the function as tv

So inside the function you are modifying the copy of the array and not the array you pass into the function.

If you want to modify the array you pass into this function then you need to do this:

void aj_dt ( char *tv , String sx )
{
.
.
.
}

And yes.....for char arrays or strings you should be using the string manipulation functions provided by Arduino as pointed out above.

boylesg:
void aj_dt ( char tv[] , String sx )
{
.
.
.
}

I believe what you are doing here is making a copy of what ever array you pass in to the function as tv

So inside the function you are modifying the copy of the array and not the array you pass into the function.

No, that's not what's going on.

t1 is a pointer to an array of characters in static memory. When you call the function, a copy of the pointer is made, and this copy is saved in tv. The pointer is copied, not the array.

When you assign a new string literal to tv, it only changes the pointer to point to the new string.

The original character array pointed to by t1 doesn't change, and t1 itself doesn't change either. The local variable tv just goes out of scope and has no effect whatsoever.

boylesg:
If you want to modify the array you pass into this function then you need to do this:

void aj_dt ( char *tv , String sx )
{
.
.
.
}

There is no difference between this function and the previous. tv is a pointer in both cases.

Pieter

Hello Pieter,

you are rigth my question is how should be the subroutine call <aj_dt ( t1, duree_sv1);>

the subroutine definetion < void aj_dt ( char tv , String sx ) > and with in the subroutine which code do i need to work with pointers such i can modify the data.

Would you be so kind to make me a short sample

string stringa="aaaaaa";
char charc="cccccc";

void samp (char charc ; srting stringa) ;

code to set set the 3rd a to a "x"

code to set set the 3rd c to a "y"

such the value

samp(stringa);

after the subroutine call should be "aaxaa"
"ccycc"

Many thanks for your help

PieterP:
No, that's not what's going on.

t1 is a pointer to an array of characters in static memory. When you call the function, a copy of the pointer is made, and this copy is saved in tv. The pointer is copied, not the array.

When you assign a new string literal to tv, it only changes the pointer to point to the new string.

The original character array pointed to by t1 doesn't change, and t1 itself doesn't change either. The local variable tv just goes out of scope and has no effect whatsoever.
There is no difference between this function and the previous. tv is a pointer in both cases.

Pieter

OK I stand corrected. I have always used the char* method for parameters, never char[].

OK so he is temporarily changing the actual pointer value(or string memory address) to the local string "fffffffffff".

But then the pointer value reverts to the original string when the function ends.

So strcpy(tv, "fffffffffff") would be the correct way to go about it.

First, please use code tags when presenting code listings. The four posts at the top of this Forum will tell you how to do that.

Second, with your cursor in the Source Code window if the IDE, press Ctrl-T. This will automatically reformat your code into a common C coding style. It makes it easier to read the code.

Third, try this program:

void setup() {
 
  char stringa[] = "aaaaaa";
  char stringc[] = "cccccc";

  Serial.begin(9600);
  
  ShowStrings(stringa, stringc);
  
  Samp(stringa, 'x', 2);
  ShowStrings(stringa, stringc);
  
  Samp(stringc, 'y', 2);
  ShowStrings(stringa, stringc);
  
}
/*****
 Purpose: To change a single letter in a string

 Argument list:
  char str[]      the string to change
  char c          the character to change
  int where       which character to change

 Return value:
  void

 CAUTION: Assumes string is long enough to hold the change
******/
void Samp(char str[], char c, int where)
{
  str[where] = c;
}

void ShowStrings(char a[], char *c)
{
  Serial.print("stringa = ");
  Serial.println(a);
  Serial.print("stringc = ");
  Serial.println(c);
  
}

void loop() {


}

I was not able to test it, but I think it will work for you. Note that when you pass any array to a C function, it is the starting memory address of that array that gets passed to the function. This is commonly called "pass by reference". Because the function now knows where the array "lives" in memory, your function can permanently change its content.

If you pass a (non-array) variable to a function, a copy of that variable is sent to the function. This means the function does NOT know where it "lives" in memory, so it cannot permanently change its value. This is commonly called "pass by value".

Passing a pointer to a variable to a function means that a (properly initialized) pointer holds the address of where that variable lives in memory, so pointers allow you to permanently change the value of the variable in a function.

Many thanks for your quick and positive response.

your solution works for char array but not for string.

I modified your code to add specific string array as parameters.

the syntax for char array and string array is different and it took quite some time to find a solution ....!

It works but I do not andersdant why....!

Any way once more Many THANKS for your help.

here is your modified code may-be you would have a better solution.


void setup() {
void setup() {

char char_a[] = "charaaaaaa";
String string_s = "stringcccccc\0";

Serial.begin(9600);

ShowChar (char_a );
Sampc(char_a, 'X', 2);
ShowChar (char_a );
Serial.println(char_a);
Serial.println("from char array works OK ");

ShowString (string_s );

Samps(string_s, 'Y', 2);

ShowString( string_s);

}
/*****
Purpose: To change a single letter in a string

Argument list:
char str[] the string to change
char c the character to change
int where which character to change

Return value:
void

CAUTION: Assumes string is long enough to hold the change
******/
void Sampc(char str[], char c, int where)
// ----
{
str[where] = c;
}

void Samps(String &str , char c, int where)
// -----
{
Serial.print("with in s/r Samps before string_s = ");
Serial.println(str);
str[where] = c;
Serial.print("with in s/r Samps after string_s = ");
Serial.println(str);
}

void ShowChar( char *c)
{
Serial.print("from s/R ShowChar string_a = ");
Serial.println(c);
}
void ShowString( String c)
{
Serial.print("with in s/r ShowString string_s = ");
Serial.println(c);

}

void loop() {

}

the printout
from s/R ShowChar string_a = charaaaaaa
from s/R ShowChar string_a = chXraaaaaa
chXraaaaaa
from char array works OK
with in s/r ShowString string_s = stringcccccc
with in s/r Samps before string_s = stringcccccc
with in s/r Samps after string_s = stYingcccccc
with in s/r ShowString string_s = stYingcccccc

Many thanks for your help.

jpl there are 2 parts to this parameter of your function.

char *tv

tv is in effect a memory address variable.

This image explains it better than I could describe it.

The only difference is that in your case the 'Var' part of it is an array of characters otherwise known as a C style string.

The way you have declared this parameter in your function means that the actual address part of it cannot be changed.

Any change that you do make inside your function e.g. tv = "ffffffffff" will be discarded once the function ends.

What you can change is the 'Var' part of your parameter or the contents of the array of characters tv points to.

But that is not what tv = "ffffffffff" is doing - it is simply temporarily changing the 'Ptr' part of it.

To change the 'Var' part of the pointer you need to do strcpy(tv, "fffffffff")

hello to all thanks for your help

below is the last version with the resolution to my problemes.

one more thanks to all

// this is a sample on how to pass parameters to a S/R
//
// using pointer of array  as Char oder String
//
//
void setup() {
 
  char char_a[] = "charaaaaaa";
  String string_s  = "stringcccccc\0";
  char v = '5'; 
  Serial.begin(9600);
  
  ShowChar (char_a );
  Sampc(char_a, 'X', 2);
  ShowChar (char_a );
  Serial.println(char_a);
  Serial.println("from char array works OK ");
  
  
  ShowString (string_s );
  
  Samps(string_s, v, 2);
  
  ShowString(  string_s);
 
}
/*****
 Purpose: To change a single letter in a string

 Argument list:
  char str[]      the string to change
  char c          the character to change
  int where       which character to change

 Return value:
  void

 CAUTION: Assumes string is long enough to hold the change
******/
void Sampc(char str[], char c, int where)
{
  str[where] = c;
}

void Samps(String &str , char c, int where)
{
  Serial.print("with in s/r Samps before string_s = ");
  Serial.println(str);
  str[where] = c;  
  Serial.print("with in s/r Samps after string_s = ");
  Serial.println(str);
}

void ShowChar( char *c)
{
  Serial.print("from s/R ShowChar string_a = ");
  Serial.println(c);
}
void ShowString( String c)
{
  Serial.print("with in s/r ShowString  string_s = ");
  Serial.println(c);
  
}

void loop() {


}
[\code]