Arduino - String Array with integer - arduino

In Arduino i need a simple array. The keys have to be a string and the values an integer. In PHP it would look like this:
$array["name"] = array(8,4);
$array["second"] = array(1,6);
Is there any way to solve this with Arduino?

Array of struct would be better:
typedef struct keyAndValue_ {
int key;
char value[NAMELENMAX+1];
} keyAndValue_t;
keyAndValue_t myArray[] = {
{123, "Bob"},
{345, "Harry"}
};
for (int x = 0; x <= sizeof(myArray)/sizeof(myArray[0]); x++) {
if (myID == myArray[x].key) {
Serial.println(myArray[x].value);
}
}

Related

Getting junk data when trying to retrieve elements from a PROGMEM array on Arduino

My code looks something like this:
#define SIZE_OF_ARRAY 1000
const long myArray[SIZE_OF_ARRAY] PROGMEM = {
1610514120L,
1613070480L,
1615630980L,
1618194720L,
1620759660L,
1623322440L,
1625879820L,
1628430600L,
1630975920L,
1633518300L,
1636060500L,
1638603840L,
1641148500L,
1643694540L,
... // All the way to 1000 elements
}
void setup() {
Serial.begin(115200);
for( int i = 0; i < SIZE_OF_ARRAY; i++){
long currentNumber = myArray[i];
// These also do not work:
//long currentNumber = pgm_read_word_near(myArray + i);
//long currentNumber = pgm_read_dword_near(myArray + i);
Serial.println(currentNumber);
}
}
But when I run this code, I get completely random junk data:
0
65536
0
-1195853640
8843185
-566231498
-310626819
-854754529
263210495
-325068311
-159567983
-1770239
-29784074
1054840810
-293611553
-436273185
-566231498
-310626819
-854754529
263210495
... all the way up to 1000
How can I access that array to get the data I put in it? I am not very familiar with C and the difference between variables and pointers, but it works without the PROGMEM flag so I assumed it would work with it as well.
Looks like the answer was to use:
void setup() {
Serial.begin(115200);
for( int i = 0; i < SIZE_OF_ARRAY; i++){
unsigned long currentNumber = pgm_read_dword_near(myArray + i);
Serial.println(currentNumber);
}
}
And to redefine the long array as:
const unsigned long myArray[SIZE_OF_ARRAY] PROGMEM = {
1610514120UL,
1613070480UL,
1615630980UL,
1618194720UL,
1620759660UL,
...
}
Because I was also running into long overflow errors

CS50 Pset 5 Hashtable issue

After creating a hash table and assigning each letter to a value for the table, i am noticing the first word output by the table for the beginning of every linked list is the same word. Somehow it seems I am transferring the entire dictionary to each array in the table even though I have attempted to separate them. Any assistance would be awesome! Thanks in advance
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char *word;
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 25;
// Hash table
node *table[N];
char lowerword[LENGTH+1];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
int bucketfind = 0;
int x = 0;
for (int b = word[x]; b != '\0';b = word[x], x++)
{
int lowertemp = tolower(word[x]);
if (x == 0)
{
bucketfind = lowertemp - 97;
}
char lowerfinal = lowertemp;
lowerword[x] = lowerfinal;
//printf("%c", lowerword[x]);
}
int wordlen = x + 1;
int pr = 0;
while (table[bucketfind] -> next != NULL)
{
int dwlen = strlen(table[bucketfind]-> word);
pr++;
//printf("%i, %i, %s, %i\n", pr, dwlen, table[bucketfind] -> word, bucketfind);
}
//TODO
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
int asciifirst = word[0];
int lowerfirst = tolower(asciifirst);
int bucketnum = lowerfirst - 97;
return bucketnum;
}
// Loads dictionary into memory, returning true if successful else false
int dictwords = 0;
//char *cword = (char*)malloc(sizeof(char)*46);
bool load(const char *dictionary)
{
char *cword = malloc(sizeof(char)*46);
FILE *dict = fopen(dictionary, "r");
if (dictionary == NULL)
{
return false;
}
int x = 0;
while ((fscanf(dict, "%s", cword) != EOF))
{
node *nword = malloc(sizeof(node));
nword -> word = cword;
nword -> next = NULL;
int bucket = hash(cword);
//printf("%i\n", bucket);
if (table[bucket] != NULL)
{
nword -> next = table[bucket];
table[bucket] = nword;
}
else
{
table[bucket]= nword;
}
dictwords++;
}
fclose(dict);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return dictwords;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// TODO
return false;
}
It's not just the first word; every word in the linked list is the same word (the last one read). cword gets 46 bytes of memory at a specific address here char *cword = malloc(sizeof(char)*46);. Every word from dictionary is read into that same address.

Sum using recursion

Apologies for the basic question, I'm new to java and have been stuck on this for days.
I need firstly to convert letters to numbers and then using recursion to get the sum of those numbers. I think I am close but I'm also aware it very messy
public static void main(String[] arg) {
String str= "11";
//////////////////////////
String s = "helloworld";
String t = "";
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
if (!t.isEmpty()) {
t += " ";
}
int n = (int)ch - (int)'a' + 1;
t += String.valueOf(n);
}
System.out.println(t);
//////////////////////////////
int sum=0;
int x=Integer.parseInt(t);
int y=recursion(x);
System.out.println("The Sum of the digits is: "+ y);
}
public static int recursion(int y) {
if(y/10>=1) {
int tempvar =y%10;
int remain=y/10;
return tempvar + recursion(remain);
}
else {
return y;
}
}}
Ok so first of all, this line: int x=Integer.parseInt(t); will crash the program in runtime because the string t has spaces in it. So you need to remove this:
if (!t.isEmpty()) {
t += " ";
}
Second, parsing the string t to int is a problem, because the number in string t can get like very, very large. Parsing this very..very large number to an int will also produce an exception during runtime. So a better way to do this is leaving it as a string, loop over it and just add the digits in it.
I have two solutions here:
I loop on t and add the digits.
I assume you have some constraint on the size of t so as it can be parsed to int (or long), and then use recursion as you want.
public class Main {
public static void main(String[] args) {
String s = "hew";
String t = "";
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
int n = (int)ch - (int)'a' + 1;
t += String.valueOf(n);
}
System.out.println("t: "+t);
System.out.println("sum using string: " + getSumUsingString(t));
System.out.println("sum using int: " + getSumUsingLong(Long.parseLong(t), 0));
}
// the string function
private static long getSumUsingString(String t) {
long sum = 0;
for (int i = 0; i < t.length(); i++) {
sum += t.charAt(i)-48;
}
return sum;
}
// recursive function
private static long getSumUsingLong(long num, long sum) {
if (num==0) return sum;
sum += num % 10;
return getSumUsingLong(num / 10, sum);
}
}
Note:
You can use for example, BigInteger class in Java to deal with very large numbers if you really need to parse this string t to a number.

Sizeof pointer of pointer in C [duplicate]

First off, here is some code:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Is there a way to find out the size of the array that ptr is pointing to (instead of just giving its size, which is four bytes on a 32-bit system)?
No, you can't. The compiler doesn't know what the pointer is pointing to. There are tricks, like ending the array with a known out-of-band value and then counting the size up until that value, but that's not using sizeof().
Another trick is the one mentioned by Zan, which is to stash the size somewhere. For example, if you're dynamically allocating the array, allocate a block one int bigger than the one you need, stash the size in the first int, and return ptr+1 as the pointer to the array. When you need the size, decrement the pointer and peek at the stashed value. Just remember to free the whole block starting from the beginning, and not just the array.
The answer is, "No."
What C programmers do is store the size of the array somewhere. It can be part of a structure, or the programmer can cheat a bit and malloc() more memory than requested in order to store a length value before the start of the array.
For dynamic arrays (malloc or C++ new) you need to store the size of the array as mentioned by others or perhaps build an array manager structure which handles add, remove, count, etc. Unfortunately C doesn't do this nearly as well as C++ since you basically have to build it for each different array type you are storing which is cumbersome if you have multiple types of arrays that you need to manage.
For static arrays, such as the one in your example, there is a common macro used to get the size, but it is not recommended as it does not check if the parameter is really a static array. The macro is used in real code though, e.g. in the Linux kernel headers although it may be slightly different than the one below:
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", ARRAY_SIZE(days));
printf("%u\n", sizeof(ptr));
return 0;
}
You can google for reasons to be wary of macros like this. Be careful.
If possible, the C++ stdlib such as vector which is much safer and easier to use.
There is a clean solution with C++ templates, without using sizeof(). The following getSize() function returns the size of any static array:
#include <cstddef>
template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
return SIZE;
}
Here is an example with a foo_t structure:
#include <cstddef>
template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
return SIZE;
}
struct foo_t {
int ball;
};
int main()
{
foo_t foos3[] = {{1},{2},{3}};
foo_t foos5[] = {{1},{2},{3},{4},{5}};
printf("%u\n", getSize(foos3));
printf("%u\n", getSize(foos5));
return 0;
}
Output:
3
5
As all the correct answers have stated, you cannot get this information from the decayed pointer value of the array alone. If the decayed pointer is the argument received by the function, then the size of the originating array has to be provided in some other way for the function to come to know that size.
Here's a suggestion different from what has been provided thus far,that will work: Pass a pointer to the array instead. This suggestion is similar to the C++ style suggestions, except that C does not support templates or references:
#define ARRAY_SZ 10
void foo (int (*arr)[ARRAY_SZ]) {
printf("%u\n", (unsigned)sizeof(*arr)/sizeof(**arr));
}
But, this suggestion is kind of silly for your problem, since the function is defined to know exactly the size of the array that is passed in (hence, there is little need to use sizeof at all on the array). What it does do, though, is offer some type safety. It will prohibit you from passing in an array of an unwanted size.
int x[20];
int y[10];
foo(&x); /* error */
foo(&y); /* ok */
If the function is supposed to be able to operate on any size of array, then you will have to provide the size to the function as additional information.
For this specific example, yes, there is, IF you use typedefs (see below). Of course, if you do it this way, you're just as well off to use SIZEOF_DAYS, since you know what the pointer is pointing to.
If you have a (void *) pointer, as is returned by malloc() or the like, then, no, there is no way to determine what data structure the pointer is pointing to and thus, no way to determine its size.
#include <stdio.h>
#define NUM_DAYS 5
typedef int days_t[ NUM_DAYS ];
#define SIZEOF_DAYS ( sizeof( days_t ) )
int main() {
days_t days;
days_t *ptr = &days;
printf( "SIZEOF_DAYS: %u\n", SIZEOF_DAYS );
printf( "sizeof(days): %u\n", sizeof(days) );
printf( "sizeof(*ptr): %u\n", sizeof(*ptr) );
printf( "sizeof(ptr): %u\n", sizeof(ptr) );
return 0;
}
Output:
SIZEOF_DAYS: 20
sizeof(days): 20
sizeof(*ptr): 20
sizeof(ptr): 4
There is no magic solution. C is not a reflective language. Objects don't automatically know what they are.
But you have many choices:
Obviously, add a parameter
Wrap the call in a macro and automatically add a parameter
Use a more complex object. Define a structure which contains the dynamic array and also the size of the array. Then, pass the address of the structure.
You can do something like this:
int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 };
int *ptr = days + 1;
printf("array length: %u\n", ptr[-1]);
return 0;
My solution to this problem is to save the length of the array into a struct Array as a meta-information about the array.
#include <stdio.h>
#include <stdlib.h>
struct Array
{
int length;
double *array;
};
typedef struct Array Array;
Array* NewArray(int length)
{
/* Allocate the memory for the struct Array */
Array *newArray = (Array*) malloc(sizeof(Array));
/* Insert only non-negative length's*/
newArray->length = (length > 0) ? length : 0;
newArray->array = (double*) malloc(length*sizeof(double));
return newArray;
}
void SetArray(Array *structure,int length,double* array)
{
structure->length = length;
structure->array = array;
}
void PrintArray(Array *structure)
{
if(structure->length > 0)
{
int i;
printf("length: %d\n", structure->length);
for (i = 0; i < structure->length; i++)
printf("%g\n", structure->array[i]);
}
else
printf("Empty Array. Length 0\n");
}
int main()
{
int i;
Array *negativeTest, *days = NewArray(5);
double moreDays[] = {1,2,3,4,5,6,7,8,9,10};
for (i = 0; i < days->length; i++)
days->array[i] = i+1;
PrintArray(days);
SetArray(days,10,moreDays);
PrintArray(days);
negativeTest = NewArray(-5);
PrintArray(negativeTest);
return 0;
}
But you have to care about set the right length of the array you want to store, because the is no way to check this length, like our friends massively explained.
This is how I personally do it in my code. I like to keep it as simple as possible while still able to get values that I need.
typedef struct intArr {
int size;
int* arr;
} intArr_t;
int main() {
intArr_t arr;
arr.size = 6;
arr.arr = (int*)malloc(sizeof(int) * arr.size);
for (size_t i = 0; i < arr.size; i++) {
arr.arr[i] = i * 10;
}
return 0;
}
No, you can't use sizeof(ptr) to find the size of array ptr is pointing to.
Though allocating extra memory(more than the size of array) will be helpful if you want to store the length in extra space.
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Size of days[] is 20 which is no of elements * size of it's data type.
While the size of pointer is 4 no matter what it is pointing to.
Because a pointer points to other element by storing it's address.
In strings there is a '\0' character at the end so the length of the string can be gotten using functions like strlen. The problem with an integer array, for example, is that you can't use any value as an end value so one possible solution is to address the array and use as an end value the NULL pointer.
#include <stdio.h>
/* the following function will produce the warning:
* ‘sizeof’ on array function parameter ‘a’ will
* return size of ‘int *’ [-Wsizeof-array-argument]
*/
void foo( int a[] )
{
printf( "%lu\n", sizeof a );
}
/* so we have to implement something else one possible
* idea is to use the NULL pointer as a control value
* the same way '\0' is used in strings but this way
* the pointer passed to a function should address pointers
* so the actual implementation of an array type will
* be a pointer to pointer
*/
typedef char * type_t; /* line 18 */
typedef type_t ** array_t;
int main( void )
{
array_t initialize( int, ... );
/* initialize an array with four values "foo", "bar", "baz", "foobar"
* if one wants to use integers rather than strings than in the typedef
* declaration at line 18 the char * type should be changed with int
* and in the format used for printing the array values
* at line 45 and 51 "%s" should be changed with "%i"
*/
array_t array = initialize( 4, "foo", "bar", "baz", "foobar" );
int size( array_t );
/* print array size */
printf( "size %i:\n", size( array ));
void aprint( char *, array_t );
/* print array values */
aprint( "%s\n", array ); /* line 45 */
type_t getval( array_t, int );
/* print an indexed value */
int i = 2;
type_t val = getval( array, i );
printf( "%i: %s\n", i, val ); /* line 51 */
void delete( array_t );
/* free some space */
delete( array );
return 0;
}
/* the output of the program should be:
* size 4:
* foo
* bar
* baz
* foobar
* 2: baz
*/
#include <stdarg.h>
#include <stdlib.h>
array_t initialize( int n, ... )
{
/* here we store the array values */
type_t *v = (type_t *) malloc( sizeof( type_t ) * n );
va_list ap;
va_start( ap, n );
int j;
for ( j = 0; j < n; j++ )
v[j] = va_arg( ap, type_t );
va_end( ap );
/* the actual array will hold the addresses of those
* values plus a NULL pointer
*/
array_t a = (array_t) malloc( sizeof( type_t *) * ( n + 1 ));
a[n] = NULL;
for ( j = 0; j < n; j++ )
a[j] = v + j;
return a;
}
int size( array_t a )
{
int n = 0;
while ( *a++ != NULL )
n++;
return n;
}
void aprint( char *fmt, array_t a )
{
while ( *a != NULL )
printf( fmt, **a++ );
}
type_t getval( array_t a, int i )
{
return *a[i];
}
void delete( array_t a )
{
free( *a );
free( a );
}
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#define array(type) struct { size_t size; type elem[0]; }
void *array_new(int esize, int ecnt)
{
size_t *a = (size_t *)malloc(esize*ecnt+sizeof(size_t));
if (a) *a = ecnt;
return a;
}
#define array_new(type, count) array_new(sizeof(type),count)
#define array_delete free
#define array_foreach(type, e, arr) \
for (type *e = (arr)->elem; e < (arr)->size + (arr)->elem; ++e)
int main(int argc, char const *argv[])
{
array(int) *iarr = array_new(int, 10);
array(float) *farr = array_new(float, 10);
array(double) *darr = array_new(double, 10);
array(char) *carr = array_new(char, 11);
for (int i = 0; i < iarr->size; ++i) {
iarr->elem[i] = i;
farr->elem[i] = i*1.0f;
darr->elem[i] = i*1.0;
carr->elem[i] = i+'0';
}
array_foreach(int, e, iarr) {
printf("%d ", *e);
}
array_foreach(float, e, farr) {
printf("%.0f ", *e);
}
array_foreach(double, e, darr) {
printf("%.0lf ", *e);
}
carr->elem[carr->size-1] = '\0';
printf("%s\n", carr->elem);
return 0;
}
#define array_size 10
struct {
int16 size;
int16 array[array_size];
int16 property1[(array_size/16)+1]
int16 property2[(array_size/16)+1]
} array1 = {array_size, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
#undef array_size
array_size is passing to the size variable:
#define array_size 30
struct {
int16 size;
int16 array[array_size];
int16 property1[(array_size/16)+1]
int16 property2[(array_size/16)+1]
} array2 = {array_size};
#undef array_size
Usage is:
void main() {
int16 size = array1.size;
for (int i=0; i!=size; i++) {
array1.array[i] *= 2;
}
}
Most implementations will have a function that tells you the reserved size for objects allocated with malloc() or calloc(), for example GNU has malloc_usable_size()
However, this will return the size of the reversed block, which can be larger than the value given to malloc()/realloc().
There is a popular macro, which you can define for finding number of elements in the array (Microsoft CRT even provides it OOB with name _countof):
#define countof(x) (sizeof(x)/sizeof((x)[0]))
Then you can write:
int my_array[] = { ... some elements ... };
printf("%zu", countof(my_array)); // 'z' is correct type specifier for size_t

How to split a string using a specific delimiter in Arduino?

I have a String variable and I want to extract the three substrings separeted by ; to three string variables.
String application_command = "{10,12; 4,5; 2}";
I cannot use substring method because this string can be like any of the following or similar patterns also.
String application_command = "{10,12,13,9,1; 4,5; 2}"
String application_command = "{7; 1,2,14; 1}"
The only thing that is common in these patterns is there are three sections separated by ;.
Any insight is much appreciated.
Thank you
I think you need a split-string-into-string-array function with a custom separator character.
There are already several sources on the web and at stackoverflow (e.g. Split String into String array).
// https://stackoverflow.com/questions/9072320/split-string-into-string-array
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
You can use this function as follows (with ";" as separator):
String part01 = getValue(application_command,';',0);
String part02 = getValue(application_command,';',1);
String part03 = getValue(application_command,';',2);
EDIT: correct single quotes and add semicolons in the example.
The new SafeString Arduino library (available from the library manager) provides a number of tokenizing/substring methods without the heap fragmentation of the String class
See https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
for a detailed tutorial
In this case your can use
#include "SafeString.h"
void setup() {
Serial.begin(9600);
createSafeString(appCmd, 50); // large enought for the largest cmd
createSafeString(token1, 20);
createSafeString(token2, 20);
createSafeString(token3, 20);
appCmd = "{10,12,13,9,1; 4,5; 2}";
size_t nextIdx = 1; //step over leading {
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
// can trim tokens if needed e.g. token1.trim()
Serial.println(token1);
Serial.println(token2);
Serial.println(token3);
}
void loop() {
}
Also look at pfodParser which parses these types of messages { } for use by pfodApp.
Do not forget to call delete[] to free the memory after the use of the array, that said here is my solution:
String* split(String& v, char delimiter, int& length) {
length = 1;
bool found = false;
// Figure out how many itens the array should have
for (int i = 0; i < v.length(); i++) {
if (v[i] == delimiter) {
length++;
found = true;
}
}
// If the delimiter is found than create the array
// and split the String
if (found) {
// Create array
String* valores = new String[length];
// Split the string into array
int i = 0;
for (int itemIndex = 0; itemIndex < length; itemIndex++) {
for (; i < v.length(); i++) {
if (v[i] == delimiter) {
i++;
break;
}
valores[itemIndex] += v[i];
}
}
// Done, return the values
return valores;
}
// No delimiter found
return nullptr;
}
Here is an example of how to use:
void loop() {
String test = "1,2,3,4,5";
int qtde;
String* t = split(test, ',', qtde);
for (int i = 0; i < qtde; i++) {
Serial.println(t[i]);
delay(1000);
}
delete[] t;
}

Resources