Premise a character to a array compile error

Hi group,
I am working on a char function that returns a array that consists of the input array wiht a premise character.
But the compiler errors on this line: STROUT[i] = STRIN[i - d];
(error= invalid types 'char[int]' for array subscript)
I am not a C++ expert so how to solve this.

char strIn[] = "123.5";

const unsigned int PRRE_BUFLEN = 5;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println( premise(PRRE_BUFLEN, "3.5", '0' ) );
}

void loop() {
  // put your main code here, to run repeatedly:
}

char premise( int MAXLEN, char STRIN, char TOKEN ) {
  //start function
  char STROUT[MAXLEN];
  int s = strlen(STRIN);
  int o = strlen(STROUT);
  int d = o - s;
  for ( int i = 0 ; i <= d - 1 ; i++ ) {
    STROUT[i] = TOKEN;
  }
  for ( int i = d ; i <= o - 1 ; i++ ) {
    STROUT[i] = STRIN[i - d];
  }
  return STROUT;
}

Scroll up in the error messages, the original error is that the 2nd argument to your premise function is a char, but you are passing it a const char*.

There are other problems.
You are returning a local variable that goes out of scope as soon as the function exits.
You declare the char array STROUT, but do not initialize it, so strlen(STROUT) will use whatever randomly happens to be in memory at that location.

There are quite a few issues with your code.

strlen determines the length of a string by looking for the string terminator character (0x00);

You can't return an array as such from a function. You can however pass one into a function, and arrays are always passed by reference.. so you can update these parameters.

Also... don't forget to terminate your new string with the null character.

Try the following...



char strIn [10] = "3.57";
char strOut[10] = {0};

void setup() 
{
  Serial.begin(115200);
  while(!Serial);

  premise(8, strIn, strOut, '0' );
  
  Serial.println(strOut);
}

void loop() 
{}

void premise( int lenOut, char inStr[], char outStr[], char filler)
{
  int lenIn = strlen(inStr);
  int d = lenOut - lenIn;
  
  for ( int i = 0 ; i < d ; i++ )
  {
    outStr[i] = filler;
  }
  
  for ( int i = d ; i < lenOut ; i++ )
  {
    outStr[i] = inStr[i - d];
  } 

   outStr[lenOut] = 0x00;
}

As I would like the function to return a array a global STROUT is not practibal, but other suggestions are usefull, so I changed the code a bit:

char premise( int MAXLEN, char STRIN, char* TOKEN ) {
  //start function
  char STROUT[MAXLEN] = {0};
  int s = strlen(STRIN);
  int o = MAXLEN;
  int d = o - s;
  for ( int i = 0 ; i <= d - 1 ; i++ ) {
    STROUT[i] = TOKEN;
  }
  for ( int i = d ; i <= o - 1 ; i++ ) {
    STROUT[i] = STRIN[i - d];
  }
  STROUT[i+1] = '\0';
  return STROUT;
}

But now I get a error (invalid types 'char[int]' for array subscript) on this: STROUT[i] = STRIN[i - d];
but both array are declared and also are i and d. So this error makes no sense to me

Strin is a single char, not an array, so the compiler doesn't like you trying to treat it as one.

char premise( int MAXLEN, char STRIN, char* TOKEN ) {

STRIN is a single character, the compiler does not like you treating it as an array.
TOKEN is being used as if it is a single char, but you are telling the compiler that it is a pointer to a char array.
You CAN NOT return a local variable from the function. Returning STROUT actually returns a pointer to the location of STROUT, which is created on the stack when the function is called. If any other functions are called afterwards, or an interrupt occurs (such as for the millis() timer, servicing the serial hardware, etc) then the STROUT array data will be overwritten. You can return STROUT if you declare it 'static', which essentially turns it into a global variable, but you cannot do that with a variable size array.

so its never possible to return a array from a char function?

I missed that in your last code, but no, you cannot return an array from a char function, a char function returns a char. You can return a char*, but the pointer cannot be to a local variable that will cease to exist when the function ends. There are a lot of string manipulating functions, such as strcpy, strcat, etc, that take a char array as an argument, then pass a pointer to that same array back as the return value. There are also functions that declare a static char array inside the function, then return a pointer to that char array - that is possible because a static char array persists after the function exits, but can only be directly accessed inside the function, and cannot vary in size dependent on an argument passed to the function.

Returning a 'static' works as long your function doesn't need to be reentrant-safe and the array size is fixed at compile time.

Otherwise, have the calling function pass the array into the called function (via pointer) along with the array's length. The latter can then fill it with data.

Just pass it in first, as per post #3.

I have changed the code in such a manor that the function prints to the serial output directly.

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

char strin[] = {"23.5"};

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.clear();
  premS(strin, 6, '0');// produces 0023.5
  premS(strin, 4, '0');// produces 23.5
  premS(strin, 2, '0');// produces nothin
}

void premS( char STRIN[], int MAXLEN, char TOKEN) {
  int sizeSTRIN = strlen( STRIN );
  int diff = MAXLEN - sizeSTRIN;
  char STROUT[MAXLEN + 1] = {'\0'};
  if (sizeSTRIN > MAXLEN) {
#error " Invalid parameters, see description" 
  }
  for (int i = 0; i <= diff; i++) {
    STROUT[i] = TOKEN;
  }
  for (int i = diff; i < + MAXLEN; i++) {
    STROUT[i] = STRIN[i - diff];
  }
  Serial.println(STROUT);
}

void loop() {
  // put your main code here, to run repeatedly:

}

for printing to a tft lcd change Serial to TFT or the name choosen.

If all you want is to print the single character followed by the char array, that is needlessly convoluted. Just print the char then the char array.

I could do that but still I have to know the input aaray is and if I have to do that on several places in the code a cost less bytes then a for loop

I did not understand what you were trying to do. I though you were just trying to add a single character at the beginning of the string. You are actually padding to the left of the string with the specified character.

Something like this:

char strin[] = {"23.5"};

void setup() {
  Serial.begin(9600);
  premS(strin, 6, '0');// produces 0023.5
  premS(strin, 4, '0');// produces 23.5
  premS(strin, 2, '0');// produces nothing
}

void premS(const char* STRIN, const size_t MAXLEN, const char TOKEN) {
  if (MAXLEN < strlen(STRIN)) {
    //error, do not print anything
  } else {
    for (size_t i = 0; i < (MAXLEN - strlen(STRIN)); i++) {
      Serial.print(TOKEN);
    }
    Serial.println(STRIN);
  }
}

void loop() {
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.