I have a function that returns a char array and I want that turned into a String so I can better process it (compare to other stored data). I am using this simple for that should work, but it doesn't for some reason (bufferPos is the length of the array, buffer is the array and item is an empty String):
for(int k=0; k<bufferPos; k++){
item += buffer[k];
}
The buffer has the right values and so does bufferPos, but when I try to convert, for example 544900010837154, it only holds 54. If I add Serial.prints to the for like this:
for(int k=0; k<bufferPos; k++){
Serial.print(buffer[k]);
Serial.print("\t");
Serial.println(item);
item += buffer[k];
}
the output is this:
5
4 5
4 54
9 54
0 54
0 54
0 54
1 54
0 54
8 54
3 54
7 54
1 54
What am I missing? It feels like such a simple task and I fail to see the solution...
If you have the char array null terminated, you can assign the char array to the string:
char[] chArray = "some characters";
String String(chArray);
As for your loop code, it looks right, but I will try on my controller to see if I get the same problem.
Three years later, I ran into the same problem. Here's my solution, everybody feel free to cut-n-paste. The simplest things keep us up all night! Running on an ATMega, and Adafruit Feather M0:
void setup() {
// turn on Serial so we can see...
Serial.begin(9600);
// the culprit:
uint8_t my_str[6]; // an array big enough for a 5 character string
// give it something so we can see what it's doing
my_str[0] = 'H';
my_str[1] = 'e';
my_str[2] = 'l';
my_str[3] = 'l';
my_str[4] = 'o';
my_str[5] = 0; // be sure to set the null terminator!!!
// can we see it?
Serial.println((char*)my_str);
// can we do logical operations with it as-is?
Serial.println((char*)my_str == 'Hello');
// okay, it can't; wrong data type (and no terminator!), so let's do this:
String str((char*)my_str);
// can we see it now?
Serial.println(str);
// make comparisons
Serial.println(str == 'Hello');
// one more time just because
Serial.println(str == "Hello");
// one last thing...!
Serial.println(sizeof(str));
}
void loop() {
// nothing
}
And we get:
Hello // as expected
0 // no surprise; wrong data type and no terminator in comparison value
Hello // also, as expected
1 // YAY!
1 // YAY!
6 // as expected
Hope this helps someone!
Visit https://www.arduino.cc/en/Reference/StringConstructor to solve the problem easily.
This worked for me:
char yyy[6];
String xxx;
yyy[0]='h';
yyy[1]='e';
yyy[2]='l';
yyy[3]='l';
yyy[4]='o';
yyy[5]='\0';
xxx=String(yyy);
May you should try creating a temp string object and then add to existing item string.
Something like this.
for(int k=0; k<bufferPos; k++){
item += String(buffer[k]);
}
I have search it again and search this question in baidu.
Then I find 2 ways:
1,
char ch[]={'a','b','c','d','e','f','g','\0'};
string s=ch;
cout<<s;
Be aware to that '\0' is necessary for char array ch.
2,
#include<iostream>
#include<string>
#include<strstream>
using namespace std;
int main()
{
char ch[]={'a','b','g','e','d','\0'};
strstream s;
s<<ch;
string str1;
s>>str1;
cout<<str1<<endl;
return 0;
}
In this way, you also need to add the '\0' at the end of char array.
Also, strstream.h file will be abandoned and be replaced by stringstream
Related
I would like to send a list of elements inside a structure via serial port but the output produced by Arduino is abnormal.
A little help? What is the reason for this abnormal output?
const int menu_max_item = 20;
int menu_num_item = 0;
typedef struct item_menu{
String text;
void (*func)(void);
} t_item_menu;
t_item_menu arr_menu[menu_max_item];
void menu_add_item(String txt, void (*f)(void)){
arr_menu[menu_num_item].text = txt;
arr_menu[menu_num_item].func = f;
menu_num_item++;
}
void fn_nd_function(){
Serial.println('test');
}
void print_menu_lcd(){
for(int x = 0; x < 4 && x < menu_num_item; x++){
lcd.setCursor(0,x);
lcd.print(arr_menu[x].text);
}
}
void setup(){
Serial.begin(9600);
for(int i = 0; i < 2; i++) menu_add_item("item " + i, fn_nd_function);
}
void loop() {
print_menu_lcd();
delay(1000);
}
Real output
item
tem
em
Desired output
item 1
item 2
item 3
You have a couple of errors...
This code:
void fn_nd_function(){
Serial.println('test');
}
test is NOT a single character is it? So why do you have it in single quotes?
But more importantly this which is the cause of your bad output:
menu_add_item("item " + i, fn_nd_function);
"item" + i is NOT how you concatenate a number to the end of the character string "item". This is C++ not Java or Python. You'll have to build that string separately. Please don't be tempted to use the String class as that can cause other issues.
What is happening now is that you are passing "item" which is a pointer to the character array stored somewhere in memory holding the characters 'i', 't', 'e' and 'm'. When you add 1 to that pointer you end up with a pointer pointing to the 't' and when you add 2 you end up with a pointer pointing to the 'e'. So when you print from those pointers you only get the part after what that pointer points to.
You need to have a line ahead of that to build the string first. Something along the lines of:
char str[7] = "item "; // Note the two spaces to leave room for the digit
str[5] = i + '0'; // Add '0' to convert single digit to ascii
menu_add_item(str, fn_nd_function);
this is what i have of the function so far. This is only the beginning of the problem, it is asking to generate the random numbers in a 10 by 5 group of numbers for the output, then after this it is to be sorted by number size, but i am just trying to get this first part down.
/* Populate the array with 50 randomly generated integer values
* in the range 1-50. */
void populateArray(int ar[], const int n) {
int n;
for (int i = 1; i <= length - 1; i++){
for (int i = 1; i <= ARRAY_SIZE; i++) {
i = rand() % 10 + 1;
ar[n]++;
}
}
}
First of all we want to use std::array; It has some nice property, one of which is that it doesn't decay as a pointer. Another is that it knows its size. In this case we are going to use templates to make populateArray a generic enough algorithm.
template<std::size_t N>
void populateArray(std::array<int, N>& array) { ... }
Then, we would like to remove all "raw" for loops. std::generate_n in combination with some random generator seems a good option.
For the number generator we can use <random>. Specifically std::uniform_int_distribution. For that we need to get some generator up and running:
std::random_device device;
std::mt19937 generator(device());
std::uniform_int_distribution<> dist(1, N);
and use it in our std::generate_n algorithm:
std::generate_n(array.begin(), N, [&dist, &generator](){
return dist(generator);
});
Live demo
I am finding all strings from an array depending on the first letter:
#include<iostream>
#include<algorithm>
#include<string>
int main(){
const std::string strArray[] = {"an","blau","Bo","Boot","bos","da","Fee","fern","Fest","fort","je","jemand","mir","Mix",
"Mixer","Name","neu","od","Ort","so","Tor","Torf","Wasser"};
std::string value = "JNQ";
for_each(value.begin(), value.end(), [strArray](char c){
std::string const * iterator = find_if(strArray, strArray+23, [c](std::string str){
return toupper(str[0]) == c;
});
std::cout<<*iterator<<'\n';
});
return 0;
}
I get this output:
je
Name
an
Why is 'an' displayed?
I am using g++ 4.5 on Ubuntu.
The problem with your code is that you're NOT checking iterator against the end of the array, before this line:
std::cout<<*iterator<<'\n';
which should actually be this:
if (iterator != (strArray+23)) //print only if iterator != end
std::cout<<*iterator<<'\n';
See this. Its working now.
http://www.ideone.com/vyqlR
It doesn't print "an" anymore. :-)
iterator is not valid in 3rd case.
In this case iterator = strArray + 23 and point to element placed after array.
Look the fixed code.
Others have already told you the iterator is invalid, so I won't repeat that. However, here is a quick type-up of a solution that should work for you. As a side-note, don't use "magic numbers" to represent your array sizes. This is error-prone because if the size of the array changes (i.e. you add another element to it later) then it is easy to forget to update the 23 to 24. Consider this solution:
static unsigned const length = sizeof( strArray );
std::string const* end = strArray+length;
std::string const * iterator = find_if(strArray, end, [c](std::string str){
return toupper(str[0]) == c;
});
if( iterator != end ) {
std::cout<<*iterator<<'\n';
}
Note I couldn't compile this, as I do not have a C++0x compiler, so consider this pseudo-code if nothing else.
I am using Actionscript 2.0
In a Brand new Scene. My only bit of code is:
trace(int('04755'));
trace(int('04812'));
Results in:
2541
4812
Any idea what I am doing wrong/silly?
By the way, I am getting this source number from XML, where it already has the leading 0. Also, this works perfect in Actionscript 3.
In AS3, you can try:
parseInt('04755', 10)
10 above is the radix.
parseInt(yourString);
...is the correct answer. .parseInt() is a top-level function.
Converting a string with a leading 0 to a Number in ActionScript 2 assumes that the number you want is octal. Give this function I've made for you a try:
var val:String = '00010';
function parse(str:String):Number
{
for(var i = 0; i < str.length; i++)
{
var c:String = str.charAt(i);
if(c != "0") break;
}
return Number(str.substr(i));
}
trace(parse(val)); // 10
trace(parse(val) + 10); // 20
Basically what you want to do now is just wrap your string in the above parse() function, instead of int() or Number() as you would typically.
Bit of a simple one...
try this -
temp="120";
temp2="140";
temp3=int ( temp );
temp4=int ( temp2 );
temp5=temp4+temp3;
trace(temp5);
so, all you need is...
int("190");
I asked this question in a few interviews. I want to know from the Stackoverflow readers as to what should be the answer to this question.
Such a seemingly simple question, but has been interpreted quite a few different ways.
if your definition of a "word" is a series of non-whitespace characters surrounded by a whitespace character, then in 5 second pseudocode you do:
var words = split(inputString, " ")
var reverse = new array
var count = words.count -1
var i = 0
while count != 0
reverse[i] = words[count]
count--
i++
return reverse
If you want to take into consideration also spaces, you can do it like that:
string word = "hello my name is";
string result="";
int k=word.size();
for (int j=word.size()-1; j>=0; j--)
{
while(word[j]!= ' ' && j>=0)
j--;
int end=k;
k=j+1;
int count=0;
if (j>=0)
{
int temp=j;
while (word[temp]==' '){
count++;
temp--;
}
j-=count;
}
else j=j+1;
result+=word.substr(k,end-k);
k-=count;
while(count!=0)
{
result+=' ';
count--;
}
}
It will print out for you "is name my hello"
Taken from something called "Hacking a Google Interview" that was somewhere on my computer ... don't know from where I got it but I remember I saw this exact question inside ... here is the answer:
Reverse the string by swapping the
first character with the last
character, the second with the
second-to-last character, and so on.
Then, go through the string looking
for spaces, so that you find where
each of the words is. Reverse each of
the words you encounter by again
swapping the first character with the
last character, the second character
with the second-to-last character, and
so on.
This came up in LessThanDot Programmer Puzzles
#include<stdio.h>
void reverse_word(char *,int,int);
int main()
{
char s[80],temp;
int l,i,k;
int lower,upper;
printf("Enter the ssentence\n");
gets(s);
l=strlen(s);
printf("%d\n",l);
k=l;
for(i=0;i<l;i++)
{
if(k<=i)
{temp=s[i];
s[i]=s[l-1-i];
s[l-1-i]=temp;}
k--;
}
printf("%s\n",s);
lower=0;
upper=0;
for(i=0;;i++)
{
if(s[i]==' '||s[i]=='\0')
{upper=i-1;
reverse_word(s,lower,upper);
lower=i+1;
}
if(s[i]=='\0')
break;
}
printf("%s",s);
return 0;
}
void reverse_word(char *s,int lower,int upper)
{
char temp;
//int i;
while(upper>lower)
{
temp=s[lower];
s[lower]=s[upper];
s[upper]=temp;
upper=upper-1;
lower=lower+1;
}
}
The following code (C++) will convert a string this is a test to test a is this:
string reverseWords(string str)
{
string result = "";
vector<string> strs;
stringstream S(str);
string s;
while (S>>s)
strs.push_back(s);
reverse(strs.begin(), strs.end());
if (strs.size() > 0)
result = strs[0];
for(int i=1; i<strs.size(); i++)
result += " " + strs[i];
return result;
}
PS: it's actually a google code jam question, more info can be found here.