Characters and strings are driving me mad!

I hope someone can help me out with this as it is driving me mad.

All I want to do is center text on one of the lines of a 16x2 display. So I wrote a function;

int center(char instr) { return (16 - sizeof(instr)) / 2; }

I have an array of strings defined as follows:

char* txt_str[] = {,"SYSTEM ARMED","SYSTEM IDLE"};

if I try and pass txt_str[0] into the function I get the error: "error: invalid conversion from char* to char" If I type in the string into the function call it works, if I pass a char single character variable it works 'A' for example. If I assign either a character to a variable or a length of test to a variable it works. If I try and programattically assign text to a variable it moans about updating a const char even though it is not defined as such. I feel like banging my head against a brick wall. As for the string library I can't get that to do anything reasonable with this requirment

Any help would be gratefully received.

if I try and pass txt_str[0] into the function I get the error: "error: invalid conversion from char* to char"

I can see no reason for that error message, but then I can see no code either. "sizeof" inside a function operating on a function parameter which may (but isn't in this case) be a pointer will always return 2 on an AVR, which is probably not what you really want.

All I want to do is center text on one of the lines of a 16x2 display. So I wrote a function;

That function takes a single character as input. Is that useful?

The function needs to take a pointer to char:

int center(char *instr) 
{
 return (16 - sizeof(instr)) / 2;
}

And, of course, the size of a pointer is useless information for determining the length of the string. There is a strlen() function that you should investigate.

Thanks for the replys. I still have no idea how to get a sring character Fred or whatever into the function, or how to assign text programatically.

chat txt ='A';

works

char txt="Fred";

works

char txt;; txt = "FRED";

fails as txt as the compiles thinks txt has been defined as a constant! Which it has not.

None of it makes much sense, as for sizeof not working with a pointer fair enough but I really don't want to pass a pointer. Surely txt[1] is a string or character array like "FRED" not a pointer. it is output as such to the console and the lcd, it's all inconsistent.

Any way I have decided not to bother and do something productive with my time.

Surely txt[1] is a string or character array like "FRED" not a pointer.

It depends what "txt" is declared as. A string is a character array, but like all arrays in C, it is normally referred to as a pointer.

chat txt ='A';

works

char txt="Fred";

works

You need to define what "works" means to you.

Rob_Bradford: All I want to do is center text on one of the lines of a 16x2 display.

Try this:

char * armed = "SYSTEM ARMED";
char * idle = "SYSTEM IDLE";
char * statuses[] = { armed, idle };

int center(char *instr)
{
 return (16 - strlen(instr)) / 2; 
}

void main()
{
 lcd.init();
 lcd.clear();
 // show centered idle status
 lcd.printxy(1, center(statuses[1]), statuses[1]);
}

I didn't test it, but it looks right..

I just can’t leave this alone.

I have fixed the character array to function issue as follows:

int center(char *instr) {
 return (16 - sizeof(instr)) / 2;
}

It seems that the sizeof function only to work on character arrays defined at compile time. See below ( I have omitted pin definitions).

This works:

#include <LiquidCrystal.h>
char* txt_str[] = {"Test 0N","Test 0FF","SYSTEM IDLE"};

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

int txtLength;

void setup() {
    lcd.begin(16, 2);
 }

void loop() {
  lcd.setCursor(0, 0);
  lcd.print("Fred");
  txtLength = sizeof("Fred");
  lcd.setCursor(0, 1);
  lcd.print(txtLength);
}

This does not! It returns 2 all the time.

#include <LiquidCrystal.h>
char* txt_str[] = {"Test 0N","Test 0FF","SYSTEM IDLE"};

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

int txtLength;

void setup() {
    lcd.begin(16, 2);
 }

void loop() {
  lcd.setCursor(0, 0);
  lcd.print(txt_str[2]);
  txtLength = sizeof(txt_str[2]);
  lcd.setCursor(0, 1);
  lcd.print(txtLength);
}

I haven’t seen anything about that restriction documented anywhere, although it does seem to be acknowledged in the C programming world.

Rob

Moderator edit: Multiple tags added

j514

Thanks for the info, and thanks to everyone else.

As for defining what works means, it means in the general sense behaves as expected; in this case returns the expected value.

Rob

As for defining what works means, it means in the general sense behaves as expected; in this case returns the expected value.

It’s just that, the examples I pointed-out in reply #4 cannot be said to “work” in any normally-accepted sense of the word - both would return compilation errors, so couldn’t even run.

chat txt ='A';
char  txt="Fred";

void setup ()
{}

void loop ()
{}
sketch_oct31a:1: error: 'chat' does not name a type
sketch_oct31a:2: error: invalid conversion from 'const char*' to 'char'

It seems that the sizeof function only to work on character arrays defined at compile time. See below ( I have omitted pin definitions).

I pointed out in Reply #1 that sizeof was NOT the correct function to be using. Why are you still trying to use it?

PaulS

You did but you didn't say why. Plus I don't take kindly to being spoken to like that. I am no longer using it but needed a better understanding of it's operation so that I will know when to use it and when not to.

Rob

You did but you didn't say why.

He did, but not in so many words -

There is a strlen() function that you should investigate.

Plus I don't take kindly to being spoken to like that.

Perhaps you should modify your profile, then, to properly set your "thin-skinned" ranking.

No I just point out inappropriate language where appropriate. I will converse on this no further.

As for the programming issue I have it sorted, and if this is the sort of "Help" I can expect I doubt I will be posting further.

Rob

No I just point out inappropriate language where appropriate.

Before you wander off, perhaps you could quote what I posted, and what show you would have preferred to see/what you took offense to. I don't see anything in what I said that I would change.

Rob_Bradford if you don't understand the PaulS tip perhaps you should had tried discover what he was trying to tell you. You cannot blame PaulS for your weak knowledge and blindness.You should do some home work in programming and when have a question ask it here.

You did but you didn't say why. Plus I don't take kindly to being spoken to like that. I am no longer using it but needed a better understanding of it's operation so that I will know when to use it and when not to.

This is your home work.What you have done to find the answer?(In some google search you find it in 2 min ...) Don't came here crying

here's a rundown:

sizeof() : "the unary operator sizeof is used to calculate the size of any datatype, measured in the number of bytes required to represent the type."

Example:

/* This program computes the size of variable using sizeof operator.*/
int main()
{
int a;
float b;
double c;
char d;

printf("Size of int: %d bytes\n",sizeof(a));
printf("Size of float: %d bytes\n",sizeof(b));
printf("Size of double: %d bytes\n",sizeof(c));
printf("Size of char: %d byte\n",sizeof(d));
return 0;
}

strlen() :

Parameters str: pointer to the null-terminated byte string to be examined Return value: The length of the null-terminated string str.

Example:

int main()
{
    const char str[] = "How many characters in this string?";

    printf("without null character: %d\n", strlen(str));
    printf("with null character: %d\n", sizeof(str));

    return 0;
}

Hope this helps!

No it doesn't. strlen() and sizeof() will work fine with an array of characters, but only strlen() will work when you pass that array in a function, because the function only gets the pointer to the string. That is the problem.

sizeof() :
"the unary operator sizeof is used to calculate the size of any datatype,

The thing to remember is that C does NOT have a “string” datatype. You either have an array of chars, in which case the 'size of the datatype" is the size of the array:

char array[20] = "the";
 Serial.print(sizeof(array));   // prints "20"

Or you have a pointer to a char (probably an array, but…), in which case the size of the datatype is 2. (on AVR, anyway.)
The whole “double-quoted character string” thing is just a compile-time convenience, and does not correspond to an actual C data type. “put together a character array terminated by a 0, and return a pointer to the first character.”

It also helps to remember that sizeof() is an operator that works at compile-time, and thus it cannot provide the correct size of anything whose size changes at runtime.

I don’t know if that will help, or just cause you to curse C…
The lack of native support for strings is one of C’s weakest points; a lot of the bugs you see in C programs are because of people doing their own string manipulation, wrong. OTOH, real string support is “expensive” to implement (causing a similar number of problems when people try to use C++ strings on small microcontrollers.)