dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 10:24 am

hello,
how can I avoid compile warnings about
ISO C++ forbids converting a string constant to ‘char*’
?
as I am using C functions like
char * strstr ( );
I need using char * ,

but when call the function then I need to pass e.g. both

char haystack[256]="ljdsfwfjassHSIZSWQSDDHGGtoken=kogpogpomz";
char needle[30]="token";
char * pch;
pch=strstr(haystack, needle);
and
pch=strstr(haystack, "kogpog");

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 10:33 am

Does it help if you use

const char * pch;

String constants (as in "abc" ) are always read only.

I think the example code is incomplete.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 10:49 am

yes, it's incomplete, it'a part of a more complex thing:

Code: Select all

int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
{
   char *p = strstr(haystack, needle);
   if (p) return p - haystack;
   return -1;   // Not found = -1.
}


char * cstringarg( char* haystack, char* vname, char* sarg ) {
   int i=0, pos=-1;
   unsigned char  ch=0xff;
   const char*  kini = "&";       // start of varname: '&'
   const char*  kin2 = "?";       // start of varname: '?'
   const char*  kequ = "=";       // end of varname, start of argument: '='
   char  needle[TOKLEN] = "";     // complete pattern:  &varname=abc1234


   strcpy(sarg,"");
   strcpy(needle, kini);
   strcat(needle, vname);
   strcat(needle, kequ);
   pos = strstrpos(haystack, needle); 
   if(pos==-1) {
      needle[0]=kin2[0];
      pos = strstrpos(haystack, needle);
      if(pos==-1) return sarg;
   }
   pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
   while( (ch!='&')&&(ch!='\0') ) {
      ch=haystack[pos+i];    
      if( (ch=='&')||(ch==';')||(ch==' ')||(ch=='\0') ||(ch=='\n')
        ||(i+pos>=strlen(haystack))||(i>TOKLEN-1) ) {
           sarg[i]='\0';
           return sarg;
      }       
      if( (ch!='&') ) {
          sarg[i]=ch;          
          i++;       
      }      
   } 
   return sarg;
}


//
int main() {
   char cbuf[256]="&xval=10;&GPIO13=1;&yval=200;\n ";
   char cval[30];
   int x, y;
  
   cstringarg(cbuf, "GPIO13", cval);     
   if(strlen(cval)>0) {          
      digitalWrite(13, atoi(cval) );     
   }  
   cstringarg(cbuf, "xval", cval);     
   if(strlen(cval)>0) {          
      x=atoi(cval) ;     
   }  
   //
}

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 11:14 am

I don't get your error message exactly, but
There were a few other problems which I fixed below.

1) subtracting two pointers returns a type "ptrdiff_t" which is much larger than a int16_t, so I added a cast to avoid complaints about the narrowing conversion.
2) strlen() returns size_t which is unsigned and may be larger than an int.
3) vname was declared "char *", yet you passed it "GPIO13" which is read only (changed to const char *).

It compiles cleanly now with GCC 9.1 and all the warnings switched on.

Code: Select all

int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
{
   char *p = strstr(haystack, needle);
   if (p) return (int16_t)(p - haystack);
   return -1;   // Not found = -1.
}


char * cstringarg( char* haystack, const char* vname, char* sarg ) {
   int i=0, pos=-1;
   unsigned char  ch=0xff;
   const char*  kini = "&";       // start of varname: '&'
   const char*  kin2 = "?";       // start of varname: '?'
   const char*  kequ = "=";       // end of varname, start of argument: '='
   char  needle[TOKLEN] = "";     // complete pattern:  &varname=abc1234


   strcpy(sarg,"");
   strcpy(needle, kini);
   strcat(needle, vname);
   strcat(needle, kequ);
   pos = strstrpos(haystack, needle);
   if(pos==-1) {
      needle[0]=kin2[0];
      pos = strstrpos(haystack, needle);
      if(pos==-1) return sarg;
   }
   pos += (int)strlen(vname) + 2; // start of value = kini+vname+kequ
   while( (ch!='&')&&(ch!='\0') ) {
      ch=haystack[pos+i];
      if( (ch=='&')||(ch==';')||(ch==' ')||(ch=='\0') ||(ch=='\n')
        ||(i+pos>= (int)strlen(haystack))||(i>TOKLEN-1) ) {
           sarg[i]='\0';
           return sarg;
      }
      if( (ch!='&') ) {
          sarg[i]=ch;
          i++;
      }
   }
   return sarg;
}


//
int main() {
   char cbuf[256]="&xval=10;&GPIO13=1;&yval=200;\n ";
   char cval[30];

   cstringarg(cbuf, "GPIO13", cval);
   if(strlen(cval)>0) {
      digitalWrite(13, atoi(cval) );
   }
   //
}
You could do

#define length(s) (int)strlen(s)

to make strlen look a bit nicer!
or make strstrpos() return a size_t (my choice)

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 11:36 am

thank you very much @jahboater, #3
const char* vname
resolved the issue!
The rest of your advices also have been processed!
thx a lot!

PS,
now passing a char[] as a vname failes (error):

char test[30];
strcpy(test, "xpos");
cstringarg(cbuf, test, cval);

I think I have to live with the warnings... ;)

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 12:05 pm

dsyleixa123 wrote:
Thu May 30, 2019 11:36 am
now passing a char[] as a vname failes (error):

char test[30];
strcpy(test, "xpos");
cstringarg(cbuf, test, cval);

I think I have to live with the warnings... ;)
What is the warning?
There doesn't seem anything wrong with that, and it compiles cleanly for me.

Please never ignore warnings.
Its true that sometimes they are benign, but in other cases not.
Let the machine find as many problems as possible!

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 2:04 pm

the warning is still
warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
when I remove the "const" vname, in order to be able to pass also char c[] instead of "token"

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 2:40 pm

I don't understand - sorry.

When marking a formal function pointer parameter as "const" you are declaring that the function does not alter the item that the pointer points to.
Take a look at the strcpy() signature.

char *strcpy(char *dest, const char *src);

here, as we know, strcpy() writes to "dest", but does not alter "src".
Or better said, strcpy() writes to the memory pointed to by "dest", but does not write to the memory pointed to by "src". It only reads from src.

Note this is very different from declaring the pointers themselves as const.
Look at this:

int foo( const int num, char * const ptr )

here its saying that "num" will never change within the function, neither will the pointer "ptr". However the function could write to the memory that ptr refers to. The fact that "num" will never change within the function is of no interest to any of its callers (it is a copy).

int foo( const int num, char const * const ptr )

Here we don't change the ptr and we don't change anything it points to.

Perhaps its worth spending some time with a simple "hello world" program and get used to how const works - otherwise you are just poking around in the dark - bad news.

:) when you understand const, take a look at "restrict" :) - (a joke).

Some coding standards require that absolutely everything that doesn't change is declared const. Something I agree with.
The code will be more correct, safer, and possibly faster.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu May 30, 2019 2:48 pm

it's actually not crucial...

if I declare in the strstrpos function
char* vname
then I can pass from main:
char c[30];
strcpy(c, "token")
and then passing c is fine,
but if I pass just
"token"
then I get the warning ISO C++ forbids converting a string constant to ‘char*’ .

instead, if I declare
const char* vname
then I can pass e.g. "token",
but if I use
char c[30];
strcpy(c, "token")
and then passing c,
then I get an error about char* cannot be converted to const char*.

Appearently I cannot have both ways optionally, arbitrarily, simultaneously.

swampdog
Posts: 196
Joined: Fri Dec 04, 2015 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 12:02 am

Appearently I cannot have both ways optionally, arbitrarily, simultaneously.
It's because you're inadvertently attempting to remove the "constness". Back in the bad of days of K&R compilers what you are attempting was perfectly possible and the source of maddening bugs. I could write this..

"token"[1]='a';

..which would actually write into the string literal "token" and change it "taken". One problem was this..

char d1[6],d2[6];
strcpy(d1,"token");
"token"[1]='a';
strcpy(d2,"token");
printf("[%s][%s]\n",d1,d2);

..would output..
[taken][taken]

This was because, during the compilation phrase the K&R compiler would see the string literal "token" used multiple times and only declare space for it once. Buried inside the generated code you'd see some (pseudo) assembler akin to this..

.d1 char 6
.d2 char 6
.foo ascii "token" '\0'

..where ".foo" is some internal name generated by the compiler. Each time it sees "token" it replaces it with ".foo" (ie strcpy(d1,foo) strcpy(d2,foo)).

It gets worse because if you burn this code to rom the output would become..
[token][token]

..because the write would fail and nothing sensibly priced, had hardware memory protection, so the fault would not be detected at runtime.

@jahboater has explained already but if it helps, whenever you write a string literal (ie anything like "fred" or "wibble") then mentally visualise it as declared thus..

const char X[]="fred"; //aka const char *const X="fred";
const char Y[]="wibble"; //aka const char *const Y="wibble";

..where X,Y are some random unique names that don't matter. const char for the characters not being changeable and const for the pointer not being changeable. This latter const is implicit in the first (shorter) notation.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 7:48 am

yes, thank you, of course I understood the basic difference betwen a const and a variable string, but to me a string is a string is a string and I want to handle all strings by the same way when passed to a function (of course not expecting that function to change the constant one, but instead accepting a variable as a parameter if a const already would fit, as sort of a subset).
So what I actually was looking for is a compiler setting not to throw warnings if I arbitrarily pass a variable, when the function allows (even) constants.
But as stated, this is probably simply a limiting fundamental (illiberal, hidebound) C definition I have to live with.

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 8:23 am

dsyleixa123 wrote:
Thu Jun 06, 2019 7:48 am
But as stated, this is probably simply a limiting fundamental (illiberal, hidebound) C definition I have to live with.
No! Its either a faulty compiler, possibly incorrect options given to it, or your problem description is missing something.

Your strstrpos() function does not write to the strings pointed to by its arguments. It does not alter them.
So both arguments should be declared "const char *".

"abc" is always a const string. It will stored in read-only memory and will be shared if the same string is used more than once (as noted above). Therefore you cannot write to it, and you should not pass it to a function that declares that it might write to it.

Now, here is the problem.
You can of course pass a writeable string such as "char c[30]" to a function that declares that it wont write to its arguments.
If your compiler is complaining then get a new compiler!
Last edited by jahboater on Thu Jun 06, 2019 8:45 am, edited 1 time in total.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 8:43 am

yes, strstrpos does not alter the needle or haystack strings, nevertheless I also need to use this function arbitrarily to check for variable needles in variable haystacks.
And sometimes for constant needles in variable haystacks.
And perhaps sometimes also coincidentally in a constant haystack, exceptionally.
But as to general usage the string length will never be a constant at all, e.g. like for strcat, strstr, strspn, strchr, and all that.

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 8:50 am

I personaly would declare it as:-

Code: Select all

static ptrdiff_t  
strstrpos(char const * const haystack, char const * const needle)   // find 1st occurrence of substr in str
{
   char const * const p = strstr(haystack, needle);
   if (p) 
      return p - haystack;
   return -1;   // Not found = -1.
}
But if you don't like so many const's :)

Code: Select all

static long  
strstrpos(const char *haystack, const char *needle)   // find 1st occurrence of substr in str
{
   char *p = strstr(haystack, needle);
   if (p) 
      return p - haystack;
   return -1;   // Not found = -1.
}
Please note the signature for strstr()

char *strstr(const char *haystack, const char *needle);

Note how they are both declared not to write to their arguments.
Since you pass your function arguments directly to strstr() its probably best to make sure they all agree.
Last edited by jahboater on Thu Jun 06, 2019 8:57 am, edited 1 time in total.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 8:57 am

that would probably be the worst case, because I have to check mostly variable needle strings in variable haystacks or constant needle strings in variable haystacks, so eventually I need to have all options.
Last edited by dsyleixa123 on Thu Jun 06, 2019 8:59 am, edited 1 time in total.

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 8:59 am

dsyleixa123 wrote:
Thu Jun 06, 2019 8:57 am
that would probably be the worst case, because I have to check mostly variable needles in variable haystacks.
That's absolutely fine.
Again, see how strstr() is declared (look at "man strstr"):-

char *strstr(const char *haystack, const char *needle);

Note that both its arguments are declared const.
That doesn't stop you passing a variable string like "char c[30]" to it!!!!!!!!!!
Last edited by jahboater on Thu Jun 06, 2019 9:03 am, edited 1 time in total.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 9:00 am

if I use all possible options arbitrarily (both for strstrpos and for cstringarg), I get warnings or even errors, as stated.
dsyleixa123 wrote:
Thu May 30, 2019 11:36 am
now passing a char[] as a vname failes (error):

char test[30];
strcpy(test, "xpos");
cstringarg(cbuf, test, cval);

I think I have to live with the warnings... ;)
Last edited by dsyleixa123 on Thu Jun 06, 2019 9:06 am, edited 1 time in total.

jahboater
Posts: 4437
Joined: Wed Feb 04, 2015 6:38 pm

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 9:05 am

dsyleixa123 wrote:
Thu Jun 06, 2019 9:00 am
if I use all possible options arbitrarily, I get warnings or even errors, as stated.
Then your code is wrong.
Or, unlikely, the compiler is faulty.
What compiler are you using?

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 9:06 am

the standard gcc coming with Stretch.
The code is just as it is, like published.
compile flag -Wall.
and again, it's not crucial actually, just undesirable and a bit confusing among other (perhaps important) warnings.

swampdog
Posts: 196
Joined: Fri Dec 04, 2015 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 2:47 pm

You're going to have to post short complete compilable code (and gcc compile options) which demonstrates the issue. We can then figure out where you're getting confused. ;-)

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 4:03 pm

I did that already (more or less): ;)

Code: Select all



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <pthread.h>

#include <wiringPi.h>
#include <wiringSerial.h>


#define TOKLEN 30

int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
{
   char *p = strstr(haystack, needle);
   if (p) return p - haystack;
   return -1;   // Not found = -1.
}


char * cstringarg( char* haystack, char* vname, char* sarg ) {
   int i=0, pos=-1;
   unsigned char  ch=0xff;
   const char*  kini = "&";       // start of varname: '&'
   const char*  kin2 = "?";       // start of varname: '?'
   const char*  kequ = "=";       // end of varname, start of argument: '='
   char  needle[TOKLEN] = "";     // complete pattern:  &varname=abc1234


   strcpy(sarg,"");
   strcpy(needle, kini);
   strcat(needle, vname);
   strcat(needle, kequ);
   pos = strstrpos(haystack, needle); 
   if(pos==-1) {
      needle[0]=kin2[0];
      pos = strstrpos(haystack, needle);
      if(pos==-1) return sarg;
   }
   pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
   while( (ch!='&')&&(ch!='\0') ) {
      ch=haystack[pos+i];    
      if( (ch=='&')||(ch==';')||(ch=='\0') ||(ch=='\n')
        ||(i+pos>=strlen(haystack))||(i>TOKLEN-1) ) {
           sarg[i]='\0';
           return sarg;
      }       
      if( (ch!='&') ) {
          sarg[i]=ch;          
          i++;       
      }      
   } 
   return sarg;
}


//
int main() {
   char cbuf[256]="&xval=10;&GPIO13=1;&yval=200;\n ";
   char cval[30];
   int x, y, GPIO13;
  
   cstringarg(cbuf, "GPIO13", cval);     
   if(strlen(cval)>0) {          
      GPIO13=atoi(cval);     
   }  
   cstringarg("&xval=10;&GPIO13=1;&yval=200;\n ", "xval", cval);     
   if(strlen(cval)>0) {          
      x=atoi(cval) ;     
   }  

   char test[20];
   strcpy(test, "yval");
   cstringarg(cbuf, test, cval);     
   if(strlen(cval)>0) {          
      y=atoi(cval) ;     
   }  
   
   printf("x=%d, y=%d, GPIO=%d \n", x,y,GPIO13);
   return 0;


   //
}

edit, c+p mistake fixed
edit 2: code corrected
edit 3: these are the warnings -
but it compiles and runs just fine:
g++ -Wall -pthread -o "Tokens0001" "Tokens0001.c" -lwiringPi (im Verzeichnis: /home/pi/raspiProgs/UARTprogs/UARTArdPiTokens)
Tokens0001.c: In function ‘char* cstringarg(char*, char*, char*)’:
Tokens0001.c:48:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
||(i+pos>=strlen(haystack))||(i>TOKLEN-1) ) {
~~~~~^~~~~~~~~~~~~~~~~~
Tokens0001.c: In function ‘int main()’:
Tokens0001.c:67:35: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
cstringarg(cbuf, "GPIO13", cval);
^
Tokens0001.c:71:63: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
cstringarg("&xval=10;&GPIO13=1;&yval=200;\n ", "xval", cval);
^
Tokens0001.c:71:63: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
Kompilierung erfolgreich beendet.
g++ -Wall -o "%e" "%f" -pthread -lwiringPi (Geany preferences)
Last edited by dsyleixa123 on Fri Jun 07, 2019 9:09 am, edited 4 times in total.

swampdog
Posts: 196
Joined: Fri Dec 04, 2015 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 10:13 pm

The code you posted does not produce the error. I don't know what the Geany preferences are but from the (gcc 4.9.2) command line..

Code: Select all

[email protected]:/wrk/T $ gcc -o c -Wall -pedantic a.c -lpthread -lwiringPi
a.c:16:55: warning: C++ style comments are not allowed in ISO C90
 int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
                                                       ^
a.c:16:55: warning: (this will be reported only once per input file)
a.c: In function ‘main’:
a.c:75:4: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]
    char test[20];
    ^
a.c:64:11: warning: variable ‘y’ set but not used [-Wunused-but-set-variable]
    int x, y;
           ^
a.c:64:8: warning: variable ‘x’ set but not used [-Wunused-but-set-variable]
    int x, y;
        ^
a.c:84:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
..and I had to pull a value out of thin air for TOKLEN. Obviously you're omitting the part which is causing you trouble!

User avatar
Paeryn
Posts: 2563
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Thu Jun 06, 2019 11:49 pm

swampdog, dsylexia123 is compiling the code as C++, not C (the clue is in the error message :roll: ), C++ will complain about attempts to pass string literals to non-const char* arguments as it violates the const-ness of string literals.

The code only needs const adding in the function definitions (and in one of the locals in strstrpos)

For cstringarg() you need to make this change (the commented line is the original)

Code: Select all

//  char * cstringarg( char* haystack, char* vname, char* sarg ) {

char * cstringarg( const char* haystack, const char* vname, char* sarg ) {
For strstrpos(), as well as the function declaration you also need to add const to the local variable p (because strstr() returns a const if its arguments are const), and I've added in a type cast to suppress a warning about trying to return an int as an int16_t

Code: Select all

//  int16_t  strstrpos(char * haystack,  char * needle)   // find 1st occurance of substr in str
//  {
//     char *p = strstr(haystack, needle);
//     if (p) return p - haystack;
//     return -1;   // Not found = -1.
//}

int16_t  strstrpos(const char * haystack, const char * needle)   // find 1st occurance of substr in str
{
   const char *p = strstr(haystack, needle);
   if (p) return static_cast<int16_t>(p - haystack);  // Added cast to tell the compiler we know (p - haystack) could be larger than an int16_t can hold but we are daft enough to do it anyway.
   return -1;   // Not found = -1.
}
She who travels light — forgot something.

dsyleixa123
Posts: 293
Joined: Mon Jun 11, 2018 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Fri Jun 07, 2019 9:41 am

thank you, Paeryn, now I got it:
this code now compiles and works fine:

Code: Select all



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <pthread.h>

#include <wiringPi.h>
#include <wiringSerial.h>


#define TOKLEN 30

int16_t  strstrpos(const char * haystack, const char * needle)   // find 1st occurance of substr in str
{
   const char *p = strstr(haystack, needle);
   if (p) return static_cast<int16_t>(p-haystack);
   return -1;   // Not found = -1.
}


char * cstringarg( const char* haystack, const char* vname, char* sarg ) {
   int i=0, pos=-1;
   unsigned char  ch=0xff;
   const char*  kini = "&";       // start of varname: '&'
   const char*  kin2 = "?";       // start of varname: '?'
   const char*  kequ = "=";       // end of varname, start of argument: '='
   char   needle[TOKLEN] = "";     // complete pattern:  &varname=abc1234


   strcpy(sarg,"");
   strcpy(needle, kini);
   strcat(needle, vname);
   strcat(needle, kequ);
   pos = strstrpos(haystack, needle); 
   if(pos==-1) {
      needle[0]=kin2[0];
      pos = strstrpos(haystack, needle);
      if(pos==-1) return sarg;
   }
   pos=pos+strlen(vname)+2; // start of value = kini+vname+kequ   
   while( (ch!='&')&&(ch!='\0') ) {
      ch=haystack[pos+i];    
      if( (ch=='&')||(ch==';')||(ch=='\0') ||(ch=='\n')
        ||(i+pos>=(int)strlen(haystack))||(i>TOKLEN-2) ) {
           sarg[i]='\0';
           return sarg;
      }       
      if( (ch!='&') ) {
          sarg[i]=ch;          
          i++;       
      }      
   } 
   return sarg;
}


//
int main() {
   char cbuf[256]="&xval=10;&GPIO13=1;&yval=200;\n ";
   char cval[30];
   int x, y, GPIO13;
  
   cstringarg(cbuf, "GPIO13", cval);     
   if(strlen(cval)>0) {          
      GPIO13=atoi(cval);     
   }  
   cstringarg("&xval=10;&GPIO13=1;&yval=200;\n ", "xval", cval);     
   if(strlen(cval)>0) {          
      x=atoi(cval) ;     
   }  

   char test[20];
   strcpy(test, "yval");
   cstringarg(cbuf, test, cval);     
   if(strlen(cval)>0) {          
      y=atoi(cval) ;     
   }  
   
   printf("x=%d, y=%d, GPIO=%d \n", x,y,GPIO13);
   return 0;


   //
}

Last edited by dsyleixa123 on Fri Jun 07, 2019 3:51 pm, edited 1 time in total.

swampdog
Posts: 196
Joined: Fri Dec 04, 2015 11:22 am

Re: avoid compile warnings about ISO C++ forbids converting a string constant to ‘char*’

Fri Jun 07, 2019 10:39 am

@Paeryn
swampdog, dsylexia123 is compiling the code as C++, not C (the clue is in the error message :roll: )
Doh!

I did similar at work once. "What [insert flowery language] wrote this pile of [insert flowery language]?". (silence). "It was me, wasn't it?".

I've always loved The Clangers! :-)

Return to “C/C++”