Thread: strtok and strcmp pointer issues question

  1. #1
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34

    strtok and strcmp pointer issues question

    Hi everyone,
    I want to tokenise a text file with around 20 lines, and as the lines could be moved around, I want it to check the tokens for a certain word and if it contains that word, I want to equate the second token to it.

    That's probably confusing so here's an example (condensed) text file:

    Code:
    Mass (kg) = 500
    
    Wingspan (m) = 8.23
    
    Wing area (m2) = 11.4
    and the code I'm currently fighting with is
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    main ()
    
    {
           char *mass;
           float m;
           char *WINGSPAN;
           float wingspan;
           char *s;
           float S;
           char *param[40];
           char *param2[40];
    
    /* Open and print number of lines in file - all works fine */
    
     /* Problem area */
    
     /* tokenise to find actual parameters */
    char delims[]="="; 
    
    for (i=1;i<=lineno+1; i++)
    	{
    	   param[i]=strtok(arra[i],delims);
    	   param2[i]=strtok(NULL,delims);
    
    	  if (strcmp('Mass*',param[i])==0) mass=param2[i];
    	  if (strcmp('Wingspan*',param[i])==0) WINGSPAN=param2[i];
    	  if (strcmp('Wing area*',param[i])==0) s=param2[i];
    	}
    
    m=atof(mass);
    printf("Mass is %f kg\n",m); 
    
    wingspan=atof(WINGSPAN);
    printf("Wingspan is %f m\n",wingspan);
    
    S=atof(s);
    printf("Wing area is %f m2\n",S);
    
    }
    I've gotten around it by using
    Code:
    for (i=1;i<=lineno+1; i++)
    	{
    	   param[i]=strtok(arra[i],delims);
    	   param2[i]=strtok(NULL,delims);
            }
    
    mass=param2[0];
    m=atof(mass);
    printf("Mass is %f kg\n",m); 
    
    WINGSPAN=param2[2];
    wingspan=atof(WINGSPAN);
    printf("Wingspan is %f m\n",wingspan);
    
    s=param2[4];
    S=atof(s);
    printf("Wing area is %f m2\n",S);
    but this isn't helpful when lines are added to the file or switched around!

    Error messages are:
    weightest.c:204:15: warning: character constant too long for its type
    weightest.c: In function ‘main’:
    weightest.c:204: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast
    weightest.c:204: error: incompatible types in assignment
    weightest.c:205:15: warning: character constant too long for its type
    weightest.c:205: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast
    weightest.c:206:15: warning: character constant too long for its type
    weightest.c:206: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast
    weightest.c:211: warning: passing argument 1 of ‘atof’ from incompatible pointer type

    There's obviously something wrong with how I've declared the pointers but I'm really not sure how to fix it so any advice would be gratefully received! Thank you.
    Last edited by snoikey; 07-28-2010 at 02:30 AM. Reason: bad spelling

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    At a glance, you use double quotes for strings, not single quotes.

    "string"

    not

    'string'


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    Been playing with it some more and thought I'd tried this already but obviously not - changing the single quotes to double quotes in strcmp it now compiles fine but comes up with a segmentation fault when run. Any idea?

  4. #4
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    Beaten to it :P haha. *ideaS, or maybe there is just one to fix it!

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Arrays start at zero, not one, so you should be starting your loop with i=0. You never check to see if mass is not-NULL before you use it. You pretty much don't do that ever. You should really be doing two things: (1) makes sure you initialize your pointers before using them, (2) check to see they're not-null before trying to dereference them.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    Thanks for the quick replies. Ok, changed the loop and added a check for NULL.

    I'm not completely sure what you mean by initialising the pointers - a quick search of the internet says after declaring them I just need to do e.g. mass = some kind of string, which is what should be happening inside my strtok loop, but just to be sure I've done:

    Code:
           char *mass; /* or use totalmass from weight est. section */
           mass=NULL;
           float m;
           char *WINGSPAN;
           WINGSPAN=NULL;
           float wingspan;
           char *s;
           s=NULL;
           float S;
    
    for (i=0;i<=lineno; i++)
    	{
    	   param[i]=strtok(arra[i],delims);
    	   param2[i]=strtok(NULL,delims);
    
               printf("param[i] is %s\n",param[i]);
               printf("param2[i] is %s\n",param2[i]);
    
    	  if (strcmp("Mass*",param[i])==0) if(mass==NULL) mass=param2[i];
    	  if (strcmp("Wingspan*",param[i])==0) if (WINGSPAN==NULL) WINGSPAN=param2[i];
    	  if (strcmp("Wing area*",param[i])==0) if (s==NULL) s=param2[i];
    	  
    	}
    
    m=atof(mass);
    printf("Mass is %f kg\n",m); 
    
    wingspan=atof(WINGSPAN);
    printf("Wingspan is %f m\n",wingspan);
    
    S=atof(s);
    printf("Wing area is %f m2\n",S);
    still compiling, still seg faulting. It's displaying param[i] and param2[i] right to the end of the text file but not displaying 'mass is'.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    At which point is it segfaulting?
    Code:
    for( x = 0; x < FOO; x++ )
    {
        p[ x ] = strtok( stuff );
        if( p[ x ] )
        {
            NOW do stuff with p[ x ]
        }
    
    }
    Like I said, you need to make sure your functions are doing what you expect before you start blindly using the arrays you expect to have stuff in them. Also pay attention to the last line of output you actually see, that'll give you a good indicator of where things are gone wrong.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    You don't need the brackets round the 'if' statement if there's only one line involved.. only learnt that yesterday from my project supervisor, this is just one part of a program that's over 1000 lines and space-saving is also effort-saving when I need to find particular sections.

    It's not able to extract 'mass' so the strcmp part isn't working for whatever reason - 'mass', 'WINGSPAN' and 's' all come up as (null) when printed within the strtok loop.

    It seg faults right at the end of the strtok loop, without doing the atofs.

  9. #9
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    I think my question now is:

    Is there any other way of doing this other than using strcmp within the tokenising loop?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by snoikey
    You don't need the brackets round the 'if' statement if there's only one line involved.. only learnt that yesterday from my project supervisor, this is just one part of a program that's over 1000 lines and space-saving is also effort-saving when I need to find particular sections.
    Yes, it is true that if you leave out the braces, you may be able to shorten your program in terms of number of lines, but this does not necessarily make it easier to find particular sections, and in fact if you try and "squeeze" your source code, you may find it even more difficult to read and hence to find anything at a glance. Furthermore, because indentation, however important, is not what the compiler actually uses to determine scope, keeping "superfluous" braces can be useful to avoid bugs that may arise during maintenance.

    A point that you want to take note: programs that are "over 1000 lines" are actually quite common. I noticed that your sample code includes none of your own headers and comes with no other function declarations. If you want to be able to handle larger programs, then you should start defining other functions that do one thing and do it well (in separate source files, if necessary).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    True, but the long program is what my supervisor wants, and with this being my first month of C, I'm proud of it so far :P

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You completely missed the point I was making. You need to check to see that your variables have valid data before you start fiddling with them. Way to miss the obvious and distract yourself because I happen to have included a pair of braces. I suspect you'll be working on this project for a very long time.


    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    I thought since everyone on this forum has been helpful I would try and help back - I didn't know about the braces before yesterday - sorry if I insulted your intelligence.

    I -did- check the variables and there's nothing in them, meaning strcmp isn't working in the way I thought it was, and so I wanted to know if there was another way of doing it.. oh well. Thanks anyway. Not everyone's been doing this for years.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Well, what is arra? The first place where it appears in your code snippet, it is used in strtok, which implies that it must have been used earlier, otherwise it would be an example of the kind of mistake that quzah is talking about.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Jul 2010
    Location
    Liverpool
    Posts
    34
    Oh, apologies. arra is the lines of the file. So arra[1] is line 1, arra[2] is line 2. That bit works alright definitely, because printing my tokens works fine, it's just the comparing and equating section that's not.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 20q game problems
    By Nexus-ZERO in forum C Programming
    Replies: 24
    Last Post: 12-17-2008, 05:48 PM