• C

Annoying strtok warning


   Hello All,

   I'm trying to code a function that creates an entire directory tree. It uses strtok to split a given pathname and then creates each diretory. All works pretty fine, but always give me a warning while compiling:

 gcc mkdir.c
mkdir.c: In function `mktree':
mkdir.c:46: warning: passing arg 1 of `strtok' discards qualifiers from pointer target type

Here is the code:

/*Handle different syntax*/
#ifdef __UNIX__
  #define SLASH "/"
#else
  #define SLASH "\\"
#endif

#define PATHLENGTH 1025

#include <stdio.h>    /*Common IO*/
#include <string.h>   /*String handling*/
#include <sys/stat.h> /*System calls (mkdir)*/
#include <errno.h>    /*Error handling*/


/*Our functions*/
int mktree( const char *Tree );


/*
 * Main function
 */
int main( int argv , char *argc[] )
{
   char TargetTree[PATHLENGTH];
   
   strcpy(TargetTree , "c:\\teste1\\teste2\\teste3");

   mktree( TargetTree );
   return( 0 );
};


int mktree( const char *Tree )
{
   char *NextDir = NULL;
   char  PartialPath[PATHLENGTH];
   
   /*Clear target*/
   memset( PartialPath , 0 , PATHLENGTH );  
   
   /*First, lets split the path*/

   printf( "Target : %s\n" , Tree );
   
   NextDir = strtok( Tree , SLASH );

   /*Is it a DOS path?*/
   if(strstr( NextDir , ":" ))  
   {
      strcat( PartialPath , NextDir );
   }
   else
   {
      strcat( PartialPath , SLASH  );
      strcat( PartialPath , NextDir);
      mkdir( PartialPath , S_IRWXU );
      printf( "Created %s\n" , PartialPath );  
   }//;

   while( NextDir )
   {
      NextDir = strtok( NULL , SLASH );

      if( NextDir )
      {
        strcat( PartialPath , SLASH  );
        strcat( PartialPath , NextDir);
        mkdir( PartialPath , S_IRWXU );
        printf( "Created %s\n" , PartialPath );  
      };
   
   };
   
   return( 0 );
};


   I already tried changing the way the parameter is passed to mktree and yet I was not able to figure out why this happens. For instance, I'm using gcc 3.4.2 (MinGW) on WinXP SP2.

   Thanks in advance
Oberdan_Luiz_MayAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

imladrisCommented:
The strtok function creates tokens "in place". That is, if you give it a path:

this/directory/struc/0

By the end the string will be:

this/0directory/0struc/0

So, what the compiler is telling you is that strtok is going to ignore the const qualifier. If you need the const qualifier the simplest way around it would be to make a copy of it, and pass that to strtok.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Infinity08Commented:
>> If you need the const qualifier the simplest way around it would be to make a copy of it, and pass that to strtok.
And if you don't need the const qualifier, just leave it out, or cast it to non-const.
Kent OlsenDBACommented:
Hi Oberdan_Luiz_May,

imladris is correct.

If you're going to pass a value as a constant, you should endeavor to not alter it.  My choice would be to perform a strdup() within the function and parse the new string.  Don't forget to free() it before the function exit.

Good Luck!
Kent
SolarWinds® VoIP and Network Quality Manager(VNQM)

WAN and VoIP monitoring tools that can help with troubleshooting via an intuitive web interface. Review quality of service data, including jitter, latency, packet loss, and MOS. Troubleshoot call performance and correlate call issues with WAN performance for Cisco and Avaya calls

grg99Commented:
I'd suggest not using strtok() at all.   Its handy but bizarre behavior has tripped up many a coder.

 
Oberdan_Luiz_MayAuthor Commented:
  Hello,

   Well, imladris is in fact correct. I tried making a copy of the string before passing it to strtok and got rid of the warning. About using strtok, I know it has several problems. The problem is that I need a really small and fasrt executable file to perform some tasks. I know the best way would be use C++ strings...

Artysystem administratorCommented:
int mktree(char *Tree)
would be fine.
why do you need 'const' at all?
Kent OlsenDBACommented:
Hi Oberdan_Luiz_May,

There's nothing inherently wrong with passing a string as a const to a function.  In fact, except in certain specific conditions where you expect the string to be modified, it's preferred.

Here's your function with three lines changed to get past the error:

int mktree( const char *Buffer )  // Change the name of the passed variable
{
   char *NextDir = NULL;
   char  PartialPath[PATHLENGTH];
   char *Tree = strdup (Buffer);  // Now copy the passed string to temporary storage.
   
   /*Clear target*/
   memset( PartialPath , 0 , PATHLENGTH );  
   
   /*First, lets split the path*/

   printf( "Target : %s\n" , Tree );
   
   NextDir = strtok( Tree , SLASH );

   /*Is it a DOS path?*/
   if(strstr( NextDir , ":" ))  
   {
      strcat( PartialPath , NextDir );
   }
   else
   {
      strcat( PartialPath , SLASH  );
      strcat( PartialPath , NextDir);
      mkdir( PartialPath , S_IRWXU );
      printf( "Created %s\n" , PartialPath );  
   }//;

   while( NextDir )
   {
      NextDir = strtok( NULL , SLASH );

      if( NextDir )
      {
        strcat( PartialPath , SLASH  );
        strcat( PartialPath , NextDir);
        mkdir( PartialPath , S_IRWXU );
        printf( "Created %s\n" , PartialPath );  
      };
   
   };

   free (Tree);            // Free the temporary buffer;
   return( 0 );
};

Kent
Artysystem administratorCommented:
Kdo, Oberdan_Luiz_May said, the string Tree has been already duplicated before that call.
imladrisCommented:
If the problem is solved it is now time to select an answer(s) and grade it.

If not, perhaps a clarifying question would help.
Kent OlsenDBACommented:
Hi Nopius,

The poster said that he'd gotten rid of the warning by copying the string before calling the function.  That, in and of itself, won't get rid of the error as the function attempts to modify the passed string which is defined in the function header as const.

I merely demonstrated the "best practice" of making a copy of the string within the function so that the passed string remains unchanged.  With the exception of a very few C APIs like strtok(), C APIs don't modify passed strings as a byproduct of generating a return value.


Kent
Ashwini_pandeyCommented:
To remove warning just modify
"int mktree( const char *Tree )" to "int mktree( const char *Tree )"

Artysystem administratorCommented:
Ashwini_pandey, I see no difference
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.