Char[] Char* and Array confusion

Question 1:

I’m simplifying my problem as much as possible and just showing the relevant code needed to ask the question. I have what I think is called an array of char arrays and an index variable into the array:

char* weather[ ] = {“Dry”, “Rain”, “Snow”, “Blizzard”}; unsigned int pickone;

I also have a simple character array:

char todaysweather[20];

The variable pickone gets assigned something between 0 and 3. I then want to assign weather[pickone] into todaysweather. I’d like to do:

todaysweather = weather[pickone];

But that apparently isn’t allowed. So how do I do this?


Question 2:

Continuing with the same problem, I can do:

Serial.print(weather[pickone]);

And that works fine.

But if I try to do:

char bigchars[100]; // a bunch of pieces will be concatenated into this variable strcpy (bigchar, “put stuff in here”); … strcat(bigchar, weather[pickone]);

The strcat doesn’t work correctly. Is there some other way to concatenate the weather array item onto bigchar?

Thanks, Ira

Make sure to put a '\0' as the first character in bigchar. strcat needs it to know where to put the new string.

IraSch:
I’m simplifying my problem as much as possible and just showing the relevant code needed to ask the question.

That’s the wrong appoach :wink: If you want to simplify, make a small compileable example sketch (or one with the same error). NOT snippets

  1. Use strcpy(), in the second part you know how to use it :wink: . With the assign operator you can only change one variable at a time and a string is multiple.

BUT, why do you want to do that? It is rarely useful. Just use the string you have. This is wasting memory.

  1. Again, concatenating it first to simply print it is wasting memory. Just print it piece by piece.

And

IraSch:
The strcat doesn’t work correctly.

Is like asking us “my car doesn’t work correctly, can you fix it?”. Tell us what is happening and what you expect.

KeithRB:
Make sure to put a ‘\0’ as the first character in bigchar. strcat needs it to know where to put the new string.

As long as the bigchar is a global you have no problem because it’s initiated to 0 (which is NULL/’\n’). And instead of putting a ‘\n’ in the first char I would simply initiate it to an empty string

char bigChar[100] = "";

But again, I would not wast memory on a bigChar :smiley:

char* todaysweather; 

...

todaysweather = weather[pickone];

Regards, Ray L.

I'm probably missing the point, but this seems to work:

char*  weather[ ] = {"Dry", "Rain", "Snow", "Blizzard"};
char todaysweather[20]; 
char bigChar[100];
unsigned int pickone;


void setup() {
  Serial.begin(9600); 
}

void loop() {
  char c;
  int index;

  if (Serial.available() > 0) {
    c = Serial.read();
    index = c - '0';
    Serial.println(weather[index]);

    strcpy(todaysweather, weather[index]); 
    Serial.println(todaysweather);

    strcpy(bigChar, "put stuff here ");
    strcat(bigChar, todaysweather);
    Serial.println(bigChar);
  }
}

septillion: As long as the bigchar is a global you have no problem because it's initiated to 0 (which is NULL/'\n'). And instead of putting a '\n' in the first char I would simply initiate it to an empty string

char bigChar[100] = "";

But again, I would not wast memory on a bigChar :D

I assumed it was not global, hence the problem. I am confused about what you wrote. '\0' (NUL) is not the same as NULL [ (void *)0 ] which is not the same as '\n'.

'\0' is the correct value to terminate a string in C/C++.

Thanks for all of the information. I think you've answered my questions.

Septillion: Thanks for your information. In regard to making up bigChar out of pieces using strcat(), the resultant concatenation of text is passed to a routine which sends an SMS message, so it needs the text all in one piece. Also, I believe the null termination is accomplished by the initial strcpy() which start off the text.

Econjack: I originally did something similar to what you showed in your code. My problem was that the first time through, with pickone set to 0, the code

pickone = 0;
strcat(bigChar, weather[pickone]);
Serial.print(weather[pickone]);

inserted "Dry" in bigChar and printed "Dry" to the serial monitor.

BUT, every subsequent time through the strcat() inserted "Rain" (as if pickone was 1), while the serial.print still printed "Dry".

So my assumption (which now appears to be wrong) was that I was passing weather[pickone] incorrectly to strcat(), since my understanding of char parameter passing is limited. But it looks like the code was OK.

The actual program is very large, and running on an Uno. Memory usage for dynamic memory is close to 75%. At one point I was up to 83% and got a warning during compile about low memory, and there may be stability problems - and there certainly were strange results. At that point I re-coded some things to get down to where I did not get any warnings. Could I still be seeing a dynamic memory problem and could that account for my strange result? Based on feedback in this thread, it doesn't look like it's a parameter passing problem as I originally suspected.

Thanks to all.

IraSch: BUT, every subsequent time through the strcat() inserted "Rain" (as if pickone was 1), while the serial.print still printed "Dry".

Don't forget that strcat() is going to append to the string every time it executes. It assumes that the destination is either cleared or holds the proper string data in it when the strcat() is performed. I can't tell in your case since we don't have the complete code.

KeithRB: I assumed it was not global, hence the problem. I am confused about what you wrote. '\0' (NUL) is not the same as NULL [ (void *)0 ] which is not the same as '\n'.

'\0' is the correct value to terminate a string in C/C++.

Yeah, then you are right. But I find bigChar[100] = "" more elegant then bigChar[100] = {'\0'} although they do the same.

And I wasn't talking about the NULL pointer. I was talking about ASCII NUL, also refereed to as ASCII NULL or NULL character.

@IraSch, Do you really have to send all the data in one go? Otherwise (and I think you don't need to) I would reconsider my program structure...