Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Annoying strtok warning

Posted on 2006-04-19
12
Medium Priority
?
1,008 Views
Last Modified: 2012-05-05

   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
0
Comment
Question by:Oberdan_Luiz_May
  • 3
  • 3
  • 2
  • +4
12 Comments
 
LVL 16

Accepted Solution

by:
imladris earned 500 total points
ID: 16490515
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 16490966
>> 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
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16490970
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 22

Expert Comment

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

 
0
 

Author Comment

by:Oberdan_Luiz_May
ID: 16491641
  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
 
LVL 27

Expert Comment

by:Nopius
ID: 16494189
int mktree(char *Tree)
would be fine.
why do you need 'const' at all?
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16494236
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
 
LVL 27

Expert Comment

by:Nopius
ID: 16494244
Kdo, Oberdan_Luiz_May said, the string Tree has been already duplicated before that call.
0
 
LVL 16

Expert Comment

by:imladris
ID: 16498890
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
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16499038
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
 
LVL 1

Expert Comment

by:Ashwini_pandey
ID: 16550457
To remove warning just modify
"int mktree( const char *Tree )" to "int mktree( const char *Tree )"

0
 
LVL 27

Expert Comment

by:Nopius
ID: 16550528
Ashwini_pandey, I see no difference
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question