getting weird chinese characters in NSString object - xcode4.6

when I have the following code:
NSString *shape = #"▲";
int _length = 3;
setCardContents = [shape stringByPaddingToLength:_length withString:shape startingAtIndex:0];
When I put a break point right after the last line above and then check the value setCardContents, I get some weird characters at the end of my text.
From debug:

Related

Character keeps changing even though I don't change it

I have an Arduino app in which I am creating multiple character arrays. I create one and it prints out in the monitor as the array I want. I then create another character array using an entirely different set of variables. The second character array is what I want but when I print out the first character array in the monitor it has the value of the second character array.
Here is the code:
//TEMP is stored in EEPROM and I retrieve it like this
String vvvv;
for(int i=0;i<33;i++)
{vvvv = vvvv + char(EEPROM.read(0x90+i));
}
int firstCommaIndexa = vvvv.indexOf(',');
String wstemp = vvvv.substring(0, firstCommaIndexa);
TEMP = wstemp;
//I then use this code to create my first char
char tripchar[] = "";
String tripUserString =String(TEMP) + String("/feeds/trip,aaa");
int tripCommaIndexb = tripUserString.indexOf(",");
String tripSt = tripUserString.substring(0,tripCommaIndexb);
int tripleng = tripCommaIndexb;
Serial.println("tripleng");
Serial.print(tripleng);
tripSt.toCharArray(tripchar,tripleng+1);
Serial.println("trip1");
Serial.print(tripSt); //this print out as XXXX/feeds/trip
Serial.println("tripchar1");
Serial.print(tripchar); //this prints out as XXXX/feeds/trip
// Then I create my second char with this code.
char userbattery2[] = "";
String UserString =String(TEMP) + String("/feeds/wifi-connection,aaa");
int firstCommaIndexb = UserString.indexOf(",");
String batterySt = UserString.substring(0,firstCommaIndexb);
int leng = firstCommaIndexb;
Serial.println("leng");
Serial.print(leng);
batterySt.toCharArray(userbattery2,leng+1);
Serial.println("battery");
Serial.print(batterySt); //this prints as XXXX/feeds/wifi-connection
Serial.print(userbattery2); //this prints as XXXX/feeds/wifi-connection
Serial.println("trip2");
Serial.print(tripSt); //this prints as XXXX/feeds/trip
Serial.println("tripchar2");
Serial.print(tripchar); //but this prints out as XXX/feeds/wifi-connection
I have tried various solutions but to no avail.
Can someone tell me what I am doing wrong and why this doesn't work and also SHOW me what I need to do to make this work so the Character arrays don't change but always stay the same after I set them.
I only have to change a couple things to make this work.
//This part I left the same.
//TEMP is stored in EEPROM and I retrieve it like this
String vvvv;
for(int i=0;i<33;i++)
{vvvv = vvvv + char(EEPROM.read(0x90+i));
}
int firstCommaIndexa = vvvv.indexOf(',');
String wstemp = vvvv.substring(0, firstCommaIndexa);
TEMP = wstemp;
//I then use this code to create my first char
//Here I just changed the first line so it is assigned 50 characters of memory. My longest array is 23 characters plus a username and I will make sure no-one creates a username of more than 26 characters. I also moved this from void setup() to the space above making it global.
char tripchar[50] = "";
//this is in void setup()
String tripUserString =String(TEMP) + String("/feeds/trip,aaa");
int tripCommaIndexb = tripUserString.indexOf(",");
String tripSt = tripUserString.substring(0,tripCommaIndexb);
int tripleng = tripCommaIndexb;
Serial.println("tripleng");
Serial.print(tripleng);
tripSt.toCharArray(tripchar,tripleng+1);
Serial.println("trip1");
Serial.print(tripSt); //this print out as XXXX/feeds/trip
Serial.println("tripchar1");
Serial.print(tripchar); //this prints out as XXXX/feeds/trip
// Then I create my second char with this code.
char userbattery2[50] = ""; //this is also made global with a memory of 50
String UserString =String(TEMP) + String("/feeds/wifi-connection,aaa");
int firstCommaIndexb = UserString.indexOf(",");
String batterySt = UserString.substring(0,firstCommaIndexb);
int leng = firstCommaIndexb;
Serial.println("leng");
Serial.print(leng);
batterySt.toCharArray(userbattery2,leng+1);
Serial.println("battery");
Serial.print(batterySt); //this prints as XXXX/feeds/wifi-connection
Serial.print(userbattery2); //this prints as XXXX/feeds/wifi-connection
Serial.println("trip2");
Serial.print(tripSt); //this prints as XXXX/feeds/trip
Serial.println("tripchar2");
Serial.print(tripchar); //this now prints as XXXX/feeds/wifi-connection
I can now subscribe and publish to my MQTT broker.
I hope this helps anyone who has a problem with this. I wish I could have initialized the char arrays with variable memory but I couldn't find a way. If some knows of one let me know.

Filled Array is Empty - Abort Trap:6

I have one long array, and I'm trying to figure out how to split it up into two separate arrays, the second array has the right contents but the first is empty, I'm also getting an Abort Trap:6 and I'm not sure what that means.
I have an array called entireA, which looks something like this:
HELLO:WORLD, I want to put HELLO in a separate array (firstA) and WORLD in secondA. When I print first and second array at the end, secondA has the right contents but firstA doesn't event though I'm printing to check if the right characters are being passed over and they are -- but the firstA is still empty and I'm getting and abort trap i don't understand.
I've just started learning C, why is the first array empty and what does the error mean?
#define ARRSIZE 10000
char entireA[ARRSIZE] = "";
char firstA[ARRSIZE] = "";
char secondA[ARRSIZE] = "";
strcpy(entireA,"HELLO:WORLD\n");
int firstVar = 0;
int entireVar = 0;
while(entireA[entireVar] != ':') {
if(entireA[entireVar] == ';') {
break;
}
printf("%c \n",entireA[entireVar]);
firstA[firstVar] = entireA[entireVar];
firstVar++;
entireVar++;
}
firstA[firstVar] = '\0';
int secondVar = 0;
entireVar++; //skip ':'
while(entireA[entireVar] != '\n') {
secondA[secondVar] = entireA[entireVar];
secondVar++;
entireVar++;
}
secondA[secondVar] = '\0';
printf("%s", firstA);
printf("%s", secondA);
There is nothing wrong with the code you posted.
After execution, the variables have the following values:
entireA 0x02efcdb4 "HELLO:WORLD\n" char[0x00002710]
entireVar 0x0000000b int
firstA 0x02efa69c "HELLO" char[0x00002710]
firstVar 0x00000005 int
secondA 0x02ef7f84 "WORLD" char[0x00002710]
secondVar 0x00000005 int
Whatever your problem is, it's most likely something to do with your environment. I would suggest reducing the value of ARRSIZE to, say 80 characters, and seeing if that changes your results.

C- Find array length from pointer

So I've got this here:
#include <stdio.h>
char halloString[] = "Ha::ll::o";
char perfumeString[] = "47::11";
char veryLongString[] = "47::11::GHesd::dghsr::bfdr:hfgd46dG";
char *extract (char *input) {somethinghappenshere}
where extract needs to get all characters after the last double ":" of given input:
"o" for halloString
"11" for perfumeString
"bfdr:hfgd46dG" for veryLongString
In short, my issue is finding the length of the string *input points to. As far as I understand it that won't be happening without making something really sketchy.
Am I correct in assuming the length cannot be acquired in a good way?
And if so would it be a horrible idea to do, for example:
char stringToProcessTemp1[50];
char stringToProcessTemp2[50];
char stringToProcess[50];
for (int i = 0; i < 50; i++) {
stringToProcessTemp1[i] = input + i;
}
for (int i = 0; i < 50; i++) {
stringToProcessTemp2[i] = input + i;
}
for (int i = 0; i < 50; i++) {
if (stringToProcessTemp1[i] == stringToProcessTemp2[i]) {
stringToProcessTemp[i] = stringToProcessTemp1[i];
}
}
Later checking where the first empty index is and saving everything before it as the used String as from my very limited experience in C when you go outside of an array you tend to get different outputs every time therefore making the chance both Temp strings match for an extra element directly after the last one of the original string what I'd consider low enough.
It's honestly the only idea I've got right now.
Finding the length of a string is no problem. strlen will do that for you. However, you don't even need that.
You can use the strstr function to find a substring within a string, in this case "::". When you find one, keep looking right after the last one you found until you don't find it anymore, then the last one you found is the one you want. Then you want the substring that starts right after it.
char *extract(char *input)
{
char *last = NULL, *start = input, *curr;
while ((curr == strstr(start, "::")) != NULL) {
last = curr; // keep track of the last "::" found
start = last + 1; // move the starting string to right after the last "::"
// move up 1 instead of 2 in case of ":::"
}
if (last != NULL) {
last +=2; // We found one; move just past the "::"
}
return last;
}
C strings, which are really only an array of characters, are by definition terminated by '\0'. So, for a well formed C string you can always get the length of the string by using strlen().
If, however, your string is not null-terminated, there is no way to determine it's length, and it is not a C string by definition any more, but just an array of characters.

How to rewrite an char array in c?

I've searched around for a quiet some time but surprisingly I couldn't find an answer to it:
I want to rewrite a char array starting from [0], but all what's happening is: it's always appending. Here's my code:
The algorithm is: I have a very long string which I like to break into several lines (wherever there is a blank space at the end of a line). Each line shall be saved in an array Index (lineContent);
void print_text(char* content, int menu_width, int which_selected, int menu_height, int scroll_pos)
{
int posCounter = 0;
int charCounter = menu_width-10;
int printOutCounter;
char* lineContent[400]; // 400 lines max
short spaceFound;
while (strlen(content) > menu_width) // If string is longer than 1 line
{
//Interesting Part ---------- START
char changeString [strlen(content)];
char printString [menu_width-10];
spaceFound = 0;
charCounter = menu_width-10;
lineContent[posCounter] = malloc(MAXITEMSTR);
while (spaceFound == 0)
{
if (content[charCounter] == ' ')
{
// I guess the error goes between here ...
strncpy(changeString,content,strlen(content));
strncpy(printString,content,menu_width-10);
// ...and here
memmove(&changeString[0], &changeString[charCounter], strlen(content));
content=changeString;
lineContent[posCounter]=printString;
strcat(lineContent[posCounter],"\0");
posCounter++;
spaceFound = 1;
//Interesting Part ---------- END
}
charCounter--;
if (charCounter <= 0)
spaceFound = 1;
}
}
}
As I said, in the end, when checking the content of lineContent, every entry is the same (the one from the last line).
I think this is because, strcpy just appends to the end, therefor I have to clear the array, to erase the former line. So it will start from [0] and not from the last printed letter.
Has anybody an idea how to do this? Is there a function that overwrites a char array instead of appending it?
Kind Regards
Strcat appends to the end, strcpy overwrites the value stored in the string.

Arduino (C language) parsing string with delimiter (input through serial interface)

Arduino (C language) parsing string with delimiter (input through serial interface)
Didn't find the answer here :/
I want to send to my arduino through a serial interface (Serial.read()) a simple string of three numbers delimited with comma. Those three numbers could be of range 0-255.
Eg.
255,255,255
0,0,0
1,20,100
90,200,3
What I need to do is to parse this string sent to arduino to three integers (let's say r, g and b).
So when I send
100,50,30
arduino will translate it to
int r = 100
int g = 50
int b = 30
I tried lots of codes, but none of them worked. The main problem is to translate string (bunch of chars) to integer. I figured out that there will probably be strtok_r for delimiter purpose, but that's about it.
Thanks for any suggestions :)
To answer the question you actually asked, String objects are very powerful and they can do exactly what you ask. If you limit your parsing rules directly from the input, your code becomes less flexible, less reusable, and slightly convoluted.
Strings have a method called indexOf() which allows you to search for the index in the String's character array of a particular character. If the character is not found, the method should return -1. A second parameter can be added to the function call to indicate a starting point for the search. In your case, since your delimiters are commas, you would call:
int commaIndex = myString.indexOf(',');
// Search for the next comma just after the first
int secondCommaIndex = myString.indexOf(',', commaIndex + 1);
Then you could use that index to create a substring using the String class's substring() method. This returns a new String beginning at a particular starting index, and ending just before a second index (Or the end of a file if none is given). So you would type something akin to:
String firstValue = myString.substring(0, commaIndex);
String secondValue = myString.substring(commaIndex + 1, secondCommaIndex);
String thirdValue = myString.substring(secondCommaIndex + 1); // To the end of the string
Finally, the integer values can be retrieved using the String class's undocumented method, toInt():
int r = firstValue.toInt();
int g = secondValue.toInt();
int b = thirdValue.toInt();
More information on the String object and its various methods can be found int the Arduino documentation.
Use sscanf;
const char *str = "1,20,100"; // assume this string is result read from serial
int r, g, b;
if (sscanf(str, "%d,%d,%d", &r, &g, &b) == 3) {
// do something with r, g, b
}
Use my code here if you want to parse a stream of string ex: 255,255,255 0,0,0 1,20,100 90,200,3Parsing function for comma-delimited string
Simplest, I think, is using parseInt() to do this task:
void loop(){
if (Serial.available() > 0){
int r = Serial.parseInt();
int g = Serial.parseInt();
int b = Serial.parseInt();
}
}
does the trick.
I think you want to do something like this to read in the data:
String serialDataIn;
String data[3];
int counter;
int inbyte;
void setup(){
Serial.begin(9600);
counter = 0;
serialDataIn = String("");
}
void loop()
{
if(serial.available){
inbyte = Serial.read();
if(inbyte >= '0' & inbyte <= '9')
serialDataIn += inbyte;
if (inbyte == ','){ // Handle delimiter
data[counter] = String(serialDataIn);
serialDataIn = String("");
counter = counter + 1;
}
if(inbyte == '\r'){ // end of line
handle end of line a do something with data
}
}
}
Then use atoi() to convert the data to integers and use them.
This is great!
The last comment about "thirdvalue = 0" is true from the code given in the most upvoted response by #dsnettleton. However, instead of using "lastIndexOf(',');" , the code should just add a "+1" to "secondCommaIndex" like #dsnettleton correctly did for commaIndex+1 (missing +1 is probably just a typo from the guy).
Here is the updated piece of code
int commaIndex = myString.indexOf(',');
int secondCommaIndex = myString.indexOf(',', commaIndex+1);
String firstValue = myString.substring(0, commaIndex);
String secondValue = myString.substring(commaIndex+1, secondCommaIndex);
String thirdValue = myString.substring(secondCommaIndex+1); //To the end of the string
Example)
For a myString = "1,2,3"
commaIndex = 1 (Searches from index 0, the spot taken by the character 1, to the location of the first comma)
secondCommaIndex = 3 (Searches from index 2, the spot taken by the character 2, to the location of the next comma)
firstValue reads from index 0-1 = "1"
secondValue reads from index 2-3 = "2"
thirdvalue reads from index 4-4(the last index spot of the string) = "3"
Note: Don't confuse INDEX with the LENGTH of the string. The length of the string is 5. Since the String indexOf counts starting from 0, the last index is 4.
The reason why just
String thirdValue = myString.substring(secondCommaIndex);
returns 0 when using .toInt() is because thirdValue = ",3" and not "3" which screws up toInt().
ps. sorry to write all the instructions out but as a mech eng, even I sometimes would like someone to dumb down code for me especially having been in consulting for the past 7 years. Keep up the awesome posting! Helps people like me out a lot!
For n number delimited in string
int end;
while((end=str.indexOf(","))!=-1){
String num = str.substring(0,end);
str= asc.substring(end+1,str.length());
Serial.println(num);
}
The new SafeString Arduino library (available via the library manager) provides an stoken() method and a toLong() method which handles this case and avoids the heap fragmenation problems of the String class.
see https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
for a detailed tutorial
#include "SafeString.h"
void setup() {
Serial.begin(9600);
createSafeString(appCmd, 50); // large enough for the largest cmd
createSafeString(token1, 10);
createSafeString(token2, 10);
createSafeString(token3, 10);
long r;
long g;
long b;
appCmd = "1,20a,100";
token1.clear();token2.clear();token3.clear(); // clear any old data
size_t nextIdx = 0;
nextIdx = appCmd.stoken(token1, nextIdx, ",");
nextIdx++; //step over delimiter
nextIdx = appCmd.stoken(token2, nextIdx, ",");
nextIdx++; //step over delimiter
nextIdx = appCmd.stoken(token3, nextIdx, ",");
nextIdx++; //step over delimiter
// now parse the numbers
bool have3ValidNumbers = true;
if (!token1.toLong(r)) {
have3ValidNumbers = false;
Serial.print("Red number invalid:");Serial.println(token1);
}
if (!token2.toLong(g)) {
have3ValidNumbers = false;
Serial.print("Green number invalid:");Serial.println(token2);
}
if (!token3.toLong(b)) {
have3ValidNumbers = false;
Serial.print("Blue number invalid:");Serial.println(token3);
}
if (have3ValidNumbers) {
Serial.print("The values are ");
Serial.print(" r:");Serial.print(r);
Serial.print(" g:");Serial.print(g);
Serial.print(" b:");Serial.print(b);
Serial.println();
}
}
void loop() {
}
The output for this input "1,20a,100" is
Green number invalid:20a
The 'standard' toInt() method would have returned 1 20 100 as the result.
For an input like "1,a,50" the 'standard' toInt() method would return 1 0 100
The SafeString toLong() method does more error checking when attempting to convert a string to an integer.
You should also add checks for <0 and >255 to ensure the input is valid range
#cstrutton -Excellent suggestion on using 'indexOf' . it saved me a ton of time for my project. One minor pointer though,
I noticed the thirdvalue did not get displayed (was coming back as ZERO). Upon playing with it little-bit and going through the doc at http://arduino.cc/en/Tutorial/StringIndexOf
I realized, I can use lastIndexOf for the last value.
Here are two lines of modifications that provided correct third value.
int lastCommaIndex = myString.lastIndexOf(',');
String thirdValue = myString.substring(lastCommaIndex+1); // To the end of the string
String myString = "dfsdfgsafhffgsdvbsdvdsvsdvsdsdfdfsdsff|date|recipt|weight|time|date|";
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
int Index1 = myString.indexOf('|');
int Index2 = myString.indexOf('|', Index1+1);
int Index3 = myString.indexOf('|', Index2+1);
int Index4 = myString.indexOf('|', Index3+1);
int Index5 = myString.indexOf('|', Index4+1);
int Index6 = myString.indexOf('|', Index5+1);
String secondValue = myString.substring(Index1+1, Index2);
String thirdValue = myString.substring(Index2+1, Index3);
String fourthValue = myString.substring(Index3+1, Index4);
String fifthValue = myString.substring(Index4+1, Index5);
String firstValue = myString.substring(Index5+1, Index6);
//Serial.println(Index1);
//
Serial.println(secondValue);
Serial.println(thirdValue);
Serial.println(fourthValue);
Serial.println(fifthValue);
Serial.println(firstValue);
delay(14000);
}

Resources