• 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?
 
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.
0
 
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.
0
 
Kent OlsenData Warehouse Architect / DBACommented:
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
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

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

 
0
 
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...

0
 
NopiusCommented:
int mktree(char *Tree)
would be fine.
why do you need 'const' at all?
0
 
Kent OlsenData Warehouse Architect / DBACommented:
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
0
 
NopiusCommented:
Kdo, Oberdan_Luiz_May said, the string Tree has been already duplicated before that call.
0
 
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.
0
 
Kent OlsenData Warehouse Architect / DBACommented:
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
0
 
Ashwini_pandeyCommented:
To remove warning just modify
"int mktree( const char *Tree )" to "int mktree( const char *Tree )"

0
 
NopiusCommented:
Ashwini_pandey, I see no difference
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.