String to char* conversion

By default the identifier of an array is a pointer and the index an offset of sizeof(type). By referencing the identifier, you are in fact referencing &array[0], so array == &array[0], array + 1 == &array[1], etc.

The function demands that the 1st argument must be a pointer variable which will point to the base address of a character type array

It most certainly does NOT. The function definition says that the 1st argument is a pointer to where you want the data written. It is perfectly acceptable to call strcpy() and tell it to write starting at the 17th element of an array.

gfvalvo:
That code is nonsense.

**That code is nonsense; because, it does not match with your pre-conceived doctrine.**That code follows the syntax as has been laid down in the following prototype of strcpy() function.

char * _CType strcpy(char *__dest, const char *__src);

Address is an integer value; it has to be passed to an integer variable before it is passed to a pointer variable.

GolamMostafa:
Address is an integer value; it has to be passed to an integer variable before it is passed to a pointer variable.

Ahhh.. I see the problem: you don't know what you're talking about. Did you try compiling that code?

C:\Users\tr001221\AppData\Local\Temp\arduino_modified_sketch_219866\sketch_nov07a.ino: In function 'void setup()':

C:\Users\tr001221\AppData\Local\Temp\arduino_modified_sketch_219866\sketch_nov07a.ino:7:12: warning: invalid conversion from 'char (*)[4]' to 'int' [-fpermissive]

   int x = &s1;

            ^

C:\Users\tr001221\AppData\Local\Temp\arduino_modified_sketch_219866\sketch_nov07a.ino:8:14: warning: invalid conversion from 'int' to 'char*' [-fpermissive]

   lookup_var = x;

              ^

gfvalvo:
Ahhh.. I see the problem: you don't know what you're talking about. Did you try compiling that code?

Please, see the following screenshots:

smxc.png

smxc.png

Please, see the following screenshots:

I'd rather be good than lucky.

GolamMostafa:
The prototype of strcpy() function is --

char * _CType strcpy(char *__dest, const char *__src);

The function demands that the 1st argument must be a pointer variable which will point to the base address of a character type array into which the source data characters (coming from another character type array being pointed by a pointer variable) would be copied.

To comply with the syntax of the strcpy() function, we have to give the following fashion to the sketch of the OP:

void setup()

{
  Serial.begin(9600);
  String temp = "1010";
  char *lookup_var;
  char s1[4];
  int x = &s1;
  lookup_var = x;

Serial.print("temp:");
  Serial.println (temp);
  strcpy(lookup_var, temp.c_str());
  Serial.print("lookUpvar:");
  Serial.println (lookup_var);
}

void loop()
{

}




Now, my question is:

Is it syntactically correct to write **strcpy(s1, temp.c_str();** other than **strcpy(lookup_var, temp.c_str();** when both forms give the same result? (s1 is a not a pointer variable though it could be thought like that.)

Your code will give the correct result only because of

  int x = &s1;
  lookup_var = x;

(it would be better to make x an unsigned int)
But, it is the same as writing

  lookup_var = s1;

and what you are doing there is to make lookup_var point to an allocated space of memory for a character array

without that bit of code, strcpy(lookup_var, temp.c_str(); will not give the correct result, unless you are very, very lucky. More often, it will overwrite other variables.

With that bit of code, the two lines do give the same result. But it is a pointless exercise and just uses up memory needlessly.

Show the compiler warnings. If you see none, turn them on.

Warnings are much more dangerous than the errors. Errors could be corrected straight forward just looking at the dictionary/cookbook. To resolve warnings, one needs to exercise sound judgment which is the faculty of knowing that 'he knows what he is doing.'

I am passing the base address (a 16-bit numerical value in the context of ATmega328P MCU) of an array to another user-defined 16-bit variable (the x). The base address will then be loaded into a pointer variable (the lookup_var) as the loading process in a pointer variable does not support the direct addressing mode. I don't need to bother the warning message in this case; I just went on in the process of uploading the sketch and found my expected result.

Knock yourself out. My original impression stands. The term I like to use is "Unpaid Test Pilot".

gfvalvo:
Knock yourself out. My original impression stands. The term I like to use is "Unpaid Test Pilot".

You are the complainer, and you are passing the verdict at the hardest level you can.

This is not fun anymore.

@GolamMostafa

Why do you go through the step of using an 'intermediate' int? You could just as well have used

char *lookup_var;
  char s1[4];
  lookup_var = s1;

The only good reason, to my knowledge, to use an int is if you want to print the address location of e.g. s1 and don't want to use sprintf; this however requires that you're sure about the sizes of the int and the pointer.

void setup() 
{
  char *lookup_var;
  char s1[4] = "101";
  lookup_var = s1;

  Serial.begin(57600);
  Serial.print("lookup_var = "); Serial.println(lookup_var);
  Serial.print("address of s1 = "); Serial.println((int)s1, HEX);
}

By the way, your variable s1 is too small to hold the four digits; so you were lucky that it worked :wink:

Lastly, from K&R's The C programming language, 2nd edition

The original definition of C frowned on, but permitted, the interchange of pointers and integers; this has long since been eliminated, and the standard now requires the proper declarations and explicit conversions that had already been enforced by good compilers.

sterretje:
@GolamMostafa

Why do you go through the step of using an 'intermediate' int? You could just as well have used

char *lookup_var;

char s1[4];
 lookup_var = s1;




By the way, your variable *s1* is too small to hold the four digits; so you were lucky that it worked ;)

I wanted to remain fully complied with the syntax of the following prototype of the strcpy() function where the 1st argument is a pointer variable which points to a character type array into which the source data would be copied. If I don't declare the 1st argument as a pointer variable, I am sure that my tutor will deduct marks in my class test. Is s1 a pointer variable? By definition, a pointer variable should have an asterisk (*) character attached to its left. For example: int *ptr;.

char * _CType strcpy(char *__dest, const char *__src);

I have the understanding that the compiler automatically appends a null-byte at the end of the last element of a character type array even though the array is declared with a dimension equal to the size of the elements that it will hold. For example:

I have the understanding that the compiler automatically appends a null-byte at the end of the last element of a character type array even though the array is declared with a dimension equal to the size of the elements that it will hold. For example:

No, it does not. Your array will contain 4 bytes. It will do what you indicate if you use something like

char s1[4] = "1234";

Please run the below code and check what happens with the integer variables.

void setup()
{
  Serial.begin(57600);
  char buffer[64];

  int x = 0x1234;
  char s1[4] = "101";
  int y = 0x5678;

  sprintf(buffer, "%p", &x);
  Serial.print("address of x =   "); Serial.println(buffer);
  sprintf(buffer, "%p", s1);
  Serial.print("address of s1 =  "); Serial.println(buffer);
  sprintf(buffer, "%p", &y);
  Serial.print("address of y =   "); Serial.println(buffer);

  Serial.print("x = "); Serial.println(x, HEX);
  Serial.print("y = "); Serial.println(y, HEX);

  strcpy(s1, "1234");

  Serial.print("x = "); Serial.println(x, HEX);
  Serial.print("y = "); Serial.println(y, HEX);

}

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

}

Using your initialisation of s1 and adding an additional print statement

void setup()
{
  Serial.begin(57600);
  char buffer[64];

  int x = 0x1234;
  //char s1[4] = "101";
  char s1[4] = {0x31, 0x32, 0x33, 0x34};
  int y = 0x5678;

  sprintf(buffer, "%p", &x);
  Serial.print("address of x =   "); Serial.println(buffer);
  sprintf(buffer, "%p", s1);
  Serial.print("address of s1 =  "); Serial.println(buffer);
  sprintf(buffer, "%p", &y);
  Serial.print("address of y =   "); Serial.println(buffer);

  Serial.print("x = "); Serial.println(x, HEX);
  Serial.print("y = "); Serial.println(y, HEX);
  Serial.println(s1);

  strcpy(s1, "1234");

  Serial.print("x = "); Serial.println(x, HEX);
  Serial.print("y = "); Serial.println(y, HEX);

}

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

}

will print garbage for s1

address of x =   0x8fa
address of s1 =  0x8f4
address of y =   0x8f8
x = 1234
y = 5678
1234xV4
x = 1234
y = 5600

GolamMostafa:
I am sure that my tutor will deduct marks in my class test. Is s1 a pointer variable?

Then you need a new tutor. In nearly all instances, the compiler implicitly converts the name of an array into a constant pointer to the type of elements in the array. And, it's set to point to the first element in the array. It's in the standard, has been since K met R. See this thread on SO: In C, are arrays pointers or used as pointers? - Stack Overflow
The first answer on this thread provides a reference to the applicable section of the standard (and a link to the PDF) if you want to look it up formally. As stated, the only exceptions to this are when the array name is used in 'sizeof()' or with the urinary '&' operator.

To check it out less formally, ask the compiler. Which way gives you fewer errors / warnings? Using the name of a char array as the first argument of strcpy() will give zero (you you do it correctly). Your "via the integer" technique will throw warnings.