system
July 29, 2010, 11:13pm
1
Good night
I'm having problems to concatenate strings.
Hereby follows my code.
//TURNS INTEGER IN STRINGS
char Debug[40];
char * cstr(int Parametro){
return itoa(Parametro,Debug,10);
}
//ID DIGITOS 1 A 4
int digits[4];
//#WRITE ON LCD
lcd.printIn(cstr(digits[2])); //1
delay(2000);
lcd.printIn(cstr(digits[3])); //0
delay(2000);
lcd.clear();
delay(2000);
//#
Like this, the LCD shows me '1' & '0', it means 10.
But I want to show '10' at once...
//WRITE PARTIAL INFO ON LCD
void EscreveLinha_LCD(int L, int C, char * T){
lcd.cursorTo(L,C);
lcd.printIn(T);
}
//CONCATENATE STRINGS
char StringFinal[40];
char* concatena(char * string1, char * string2) {
strcat(StringFinal, string1);
strcat (StringFinal, string2);
return StringFinal;
}
//#WRITE ON LCD
EscreveLinha_LCD(1,0,concatena(cstr(digits[2]),cstr(digits[3])));
//#
Like this, the LCD shows me '00'at once, instead '10'
I really don't know why!!
Thanks on advance
Best regards
Pedro Ferrer
system
July 30, 2010, 8:45am
2
Good morning
Perhaps on
char* concatena(char * string1, char * string2) {
StringFinal[0]=0;
I should have
char* concatena(char * string1, char * string2) {
StringFinal[0]='\0';
I don't know...
Thanks on advance
Best regards
Pedro Ferrer
system
July 30, 2010, 12:48pm
3
//CONCATENATE STRINGS
char StringFinal[40];
char* concatena(char * string1, char * string2) {
strcat(StringFinal, string1);
strcat (StringFinal, string2);
return StringFinal;
}
If StringFinal is declared outside of concatena, there is no reason for concatena to return a value.
In either case, StringFinal[0] does need to be set to NULL before string1 and string2 are copied into it. Either way you propose will work, although the 1st way is the more conventional way, since it acknowledges that the value on the left is a character.
system
July 30, 2010, 12:52pm
4
Thank you Paul
So, I must put
char StringFinal[40];
inside function? That's it?
Thanks once again
Best regards
Pedro Ferrer
system
July 30, 2010, 5:43pm
5
No, if you put StringFinal inside the function, it will be a local variable, and will go out of scope as soon as the function ends. Returning a pointer to an out-of-scope variable is not a good idea.
Since it is declared outside the function, it is a global variable. Therefore, it is not necessary to return a pointer to it.
system
August 2, 2010, 3:35pm
6
Thank you Paul
But may problem remains...
doing lcd.printIn(cstr(digits[2])) this is equal to 1 and doing lcd.printIn(cstr(digits[3])) this is equal to 0
This is correct!
Doing:
EscreveLinha_LCD(1,0,concatena(cstr(digits[2]),cstr(digits[3])));
where inside procedure I have the following:
//CONCATENA STRINGS
char StringFinal[40];
char *concatena(char *string1, char *string2) {
StringFinal[0]='\0';
lcd.printIn(string1); //1
Serial.println(string1);
delay(500);
lcd.printIn(string2); //1
Serial.println(string2);
delay (500);
lcd.clear();
return StringFinal;
}
I have both values (string1 and string2) as '0'.
It means that I lost the values pass to 'string1' and 'string2'...
I really don't understant why I'm loosing it!
Thanks on advance
Best regards
Pedro Ferrer
system
August 2, 2010, 3:52pm
7
Good afternoon
More explanations.
As this... I have on serial "00:"
char * aa1;
char * aa2;
aa1=cstr(digits[2]);
aa2=cstr(digits[3]);
Serial.println(aa1);
delay(1000);
Serial.println(aa2);
delay(1000);
Serial.println(":");
As this... I have on serial "10:"
delay(1000);
Serial.println(cstr(digits[2]));
delay(1000);
Serial.println(cstr(digits[3]));
delay(1000);
Serial.println(":");
Why I have this difference!?
Please let me know
Thanks on advance
Pedro Ferrer
I think you need to show your complete Arduino sketch (i.e. something with setup() and loop() ) complete with the output it produces. All you've show so far are different fragments that couldn't run on their own, and so we haven't got all the information needed to help you.
Andrew
system
August 2, 2010, 4:25pm
9
Hello Andrew
Follows my complete project
//CALL LIBRARY LCD
#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2);
#include <Wire.h>
//ID DIGITOS 1 A 4
int digits[4];
//CONCATENATE STRINGS
char StringFinal[40];
char *concatena(char *string1, char *string2) {
StringFinal[0]='\0';
strcat(StringFinal, string1);
strcat (StringFinal, string2);
return StringFinal;
}
//CONVERT INTEGERS AT STRINGS
char Debug[40];
char* cstr(int Parametro){
itoa(Parametro,Debug,10);
return Debug;
}
void setup() {
int display_speed;
display_speed=10;
digits[3] = display_speed % 10;
digits[2] = (display_speed / 10) % 10;
digits[1] = (display_speed / 100) % 10;
digits[0] = (display_speed / 1000) % 10;
//
Serial.begin(9600);
}
void loop() {
char *aa1;
char *aa2;
aa1=cstr(digits[2]);
aa2=cstr(digits[3]);
Serial.println(aa1);
delay(1000);
Serial.println(aa2);
delay(1000);
Serial.println(":");
//(...)
delay(1000);
Serial.println(cstr(digits[2]));
delay(1000);
Serial.println(cstr(digits[3]));
}
//END LOOP
char *aa1;
aa1=cstr(digits[2]);
Serial.println(aa1);
Gives me '0'
Serial.println(cstr(digits[2]));
Gives me '1' and is correct!
Perhaps I'm missing some call to library...
Thanks on advance
Best regards
After these lines:
aa1=cstr(digits[2]);
aa2=cstr(digits[3]);
both aa1 and aa2 point to the same place, your "Debug" variable. After the 2nd line above "Debug" contains "0", so both the printlns give "0".
When you println the cstr calls directly, you get the results of the first cstr call first ("1") then the second one ("0").
Andrew
system
August 3, 2010, 3:33pm
11
Thanks Andrew
I understand what you want to mean, but I'm not very confortable with pointers yet... that's why I strange this situation...
What do you suggest, which syntax do you recommend to use 'Debug' variable 2,3,4 times without any problems?
using 2 variables?
Debug1 = String1
Debug2 = String2
Thanks on advance
Best regards
Pedro Ferrer
system
August 3, 2010, 4:20pm
12
Once you populate the Debug array, you can use strdup to make a copy of that array, using dynamic memory.
char *aa1 = strdup(Debug);
When you are done with the memory, you must free it.
free(aa1);
aa1 = NULL;
Cheers for answering that Paul. It's ages since I've written any "proper" C, so I was loath to jump into the murky waters of memory allocation and pointers without refreshing my knowledge.
Andrew
system
August 3, 2010, 5:20pm
14
Well, you caught the major problem. I missed that. Though, of course now that you pointed it out, it's blindingly obvious.
system
August 5, 2010, 7:03pm
15
Good afternoon
Thanks once again by your prompt help.
I still with doubts... I've never thought that this was so difficult to implement...
Following your suggestions, I've done:
cstr(digits[2]);
char *aa1=strdup(Debug);
cstr(digits[3]);
char *aa2=strdup(Debug);
free(aa1);
aa1 = NULL;
free(aa2);
aa2 = NULL;
Serial.println(aa1);
delay(1000);
Serial.println(aa2);
delay(1000);
Serial.println(":");
And I get this... on serial...
à
à
:
instead:
1
0
:
I'll appreciate a lot if you can help me a little further.
Do I have to use malloc() function ?
Please let me knot
Thanks on advance
Best regards
Pedro Ferrer
system
August 5, 2010, 7:05pm
16
You are freeing the duplicated pointer before printing it. You need to free the duplicated pointer AFTER you print it.
system
August 5, 2010, 7:27pm
17
Thank you Paul!!!
It works now!
Thank you both.
Best regards
Pedro Ferrer
system
August 5, 2010, 9:19pm
18
Good night
I've changed the code and it works well.
Thanks to Paul and Andrew!
I've puted strdup function inside cstr function
char Debug[40];
char* cstr(int Parametro){
itoa(Parametro,Debug,10);
return strdup (Debug);
}
char *aa1;
char *aa2;
aa1=cstr(digits[2]);
aa2=cstr(digits[3]);
write on LCD and then...
free(aa1);
aa1 = NULL;
free(aa2);
aa2 = NULL;
Thanks to all once again
Best regards
Pedro Ferrer