String question

Can someone please tell me why the code below will only print the y in January in the serial monitor.

Thanks.

char janStr = 'January';

void setup() {

  Serial.begin(9600);

}

void loop() {

  Serial.println(janStr);

}

change

char janStr = 'January';

to

char janStr[] = "January";

const char janStr[] = "January";

Guix's solution is the proper one, you need the brackets ("[]") as well as the quotation marks. The reason "char janStr = 'January';" doesn't work is because "char" means character, meaning it only holds 1 character.

By using "const char janStr[] = "January";" you are forming an array of characters which makes a char array.

If you're wondering why guix and SRegan add the const data qualifier, this program might help answer the question:

char janStr[] = "January";      // Note the missing const qualifier
int val = 10;

void setup() {

  Serial.begin(9600);
  Serial.print("val = ");
  Serial.print(val);
  Serial.print("   janStr = ");
  Serial.println(janStr);
  Serial.println("============");
  strcpy(janStr, "This string is too big");
  Serial.print("val = ");
  Serial.print(val);
  Serial.print("   janStr = ");
  Serial.println(janStr);
  
}

void loop() {
}

Note that the value of val in the second series of print statements is messed up. This is because the memory allocated to janStr[] is not large enough to hold the new (larger) string. If you add the const qualifier to the string, the compiler informs you that you are trying to convert a const char to a char.

econjack:
If you're wondering why guix and SRegan add the const data qualifier, this program might help answer the question:

char janStr[] = "January";      // Note the missing const qualifier

int val = 10;

void setup() {

Serial.begin(9600);
 Serial.print("val = ");
 Serial.print(val);
 Serial.print("   janStr = ");
 Serial.println(janStr);
 Serial.println("============");
 strcpy(janStr, "This string is too big");
 Serial.print("val = ");
 Serial.print(val);
 Serial.print("   janStr = ");
 Serial.println(janStr);
 
}

void loop() {
}




Note that the value of *val* in the second series of print statements is messed up. This is because the memory allocated to *janStr[]* is not large enough to hold the new (larger) string. If you add the *const* qualifier to the string, the compiler informs you that you are trying to convert a *const char* to a *char*.

OK Thanks BUT I am still confused a bit. Not sure now why the test function is not working, apparently for the same reason. Thanks again for your help.

char janStr[] = "January";   
int val = 10;

void setup() {

  Serial.begin(9600);
  Serial.print("val = ");
  Serial.print(val);
  Serial.print("janStr = ");
  Serial.println(janStr);
  Serial.println("============");
  Serial.print("val = ");
  Serial.println(val);
  Serial.println();
  Serial.print("janStr = ");
  Serial.println(janStr);
  
}

void loop() {
 void printJan(char janStr);
 Serial.print(janStr);
 Serial.println("1");
}


  void printJan(char x){
  Serial.print("got here");
  Serial.print(x);
  Serial.println("2"); 
}
 void printJan(char janStr);

This is a function prototype, not a call to a function. Why do you have a function prototype in loop()?

To fix it, try removing the prototype Paul mentioned, so loop() reads as:

void loop() {
 Serial.print(janStr);
 Serial.println("1");
}

Also, you will likely make fewer errors if you use the auto format feature of the IDE. Just place the cursor in the Source Code window and press Ctrl-T. This will reformat your code using a standard C formatting scheme. Always do this before your post your code here...it makes it easier to read.

PaulS:

 void printJan(char janStr);

This is a function prototype, not a call to a function. Why do you have a function prototype in loop()?

Obviously I don't know what I am doing therefor the question. Any help?

roontoon:
Obviously I don't know what I am doing therefor the question. Any help?

If you want to call the function:

   printJan(janStr);

I get this error when trying to call this test function...

Arduino: 1.5.7 (Mac OS X), Board: "Arduino Uno"

test.ino: In function 'void loop()':
test.ino:9:18: error: invalid conversion from 'char*' to 'char' [-fpermissive]
test.ino:4:6: error: initializing argument 1 of 'void printJan(char)' [-fpermissive]

char janStr[] = "January";
void setup() {

  Serial.begin(9600);

}

void loop() {
  printJan(janStr);
  Serial.print(janStr);
  Serial.println("1");
}



void printJan(char x) {
  Serial.print("got here");
  Serial.print(x);
  Serial.println("2");
}

You want to make the argument char *x in the function, it should take a pointer to char - which is a string - not a char

KeithRB:
You want to make the argument char *x in the function, it should take a pointer to char - which is a string - not a char

karma++

exactly!!!

@roontoon, an array is reduced to a pointer (to the first element in the array) when passed in a function!

char arrays are sort of 'special' in that they are made up of elements of size = 1 byte, so you don't need anything but the pointer (and the NULL terminal char) and Serial.print() is happy, it knows what to do when passed a pointer to a char array! :wink:

char is a single byte
char* is a pointer to the first memory location of an array of bytes.

Serial.print(param) can understand different parameter types passed to it since it has multiple function prototypes.

Two of these are:

print(char character); // print a single character if the passed type is a single character
print(char* arrayOfCharacters); // print a string if the passed type is a pointer to a character array

char arrays are sort of 'special' in that they are made up of elements of size = 1 byte, so you don't need anything but the pointer (and the NULL terminal char) and Serial.print() is happy, it knows what to do when passed a pointer to a char array!

The fact that char arrays are one byte is rather irrelevant. Any pointer, regardless of type, when incremented by 1 will point to the next element in the array. The size of the element pointed to is used to determine the actual memory address that the pointer points to, when it is incremented by 1.

And, C programs expect a '\0' at the end of a char array to signal the end, so the size is not necessary, and why these functions go so wrong when you don't terminate the string with a '\0'.

Bear in mind that every pointer has a "scalar" associated with it that is used for pointer operations. When you define a pointer as:

char *str;

the scalar for str is sizeof(char), or 1 byte. Therefore, the statement str++ increments str by 1. If you have:

float *ptr;

its scalar is sizeof(float), or 4 bytes. Therefore, a ptr++ moves by 4 bytes. The type specifier in the pointer definition sets the size of the scalar. Obviously, trying to initialize a pointer to variable that doesn't share the same data type is just asking for trouble when you try to use the pointer.