Thread: String trouble, VERY new C programmer

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    7

    String trouble, VERY new C programmer

    Ok. I'm getting very confused. To be honest, C's pointers aren't totally clear to me (despite my reading EVERYTHING out there).

    I am trying to write a "shell" basically for hw (so hints please so i can actually learn this stuff).
    I have a global
    Code:
    char *dirs[MAXPATHS];
    at the top to keep the paths of the machine around. I'm not exactly sure what the difference b/t this and char dirs[MAXPATHS] would be....

    Well, i can get the paths info in there ok. Here is where i'm stuck.


    Code:
    char *lookupPath(char *name)
    {
    char *pName; //this was suggested by instructor, but i don't know what to use it for
    
    char*workingName = NULL;
    int counter = 0;
    
    while(dirs[counter] != NULL)
      {
         if (name != NULL && name[0] == '/')
           {
           }
         else
           {
           //PROBLEM CODE!!!!
           strcat(workingName, "");
           strcat(workingName, dirs[counter]);
           strcat(workingName, "/");
           strcat(workingName, name);
           if (access(workingName, X_OK) == 0)
               return workingName;
            }
        char *workingName = NULL;
        counter++;
       }
    printf("Error %s was not found.\n", name);
    return NULL;
    }

    how do i get workingName to be the dir[counter] + / + name of the file AND get it reset after each search?


    Thanks so much for your time


    -Zany

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Have you tried something like this?
    Code:
    sprintf(workingName, "%s/%s", dirs[counter], name);
    In addition to allocating memory for workingName?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    7
    Quote Originally Posted by Dave_Sinkula View Post
    Have you tried something like this?
    Code:
    sprintf(workingName, "%s/%s", dirs[counter], name);
    In addition to allocating memory for workingName?
    how would i allocate memory for workingName?
    i tried char *workignName;
    then your suggestion and got a segfault, just like i do when i run the strcat's

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    char workingName[BUFSIZ];
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    7
    Quote Originally Posted by Dave_Sinkula View Post
    Code:
    char workingName[BUFSIZ];
    i get some warnings, but it runs thanks so much!!

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    how would i allocate memory for workingName?
    By using malloc() to allocate the memory and free() to deallocate the memory:
    Code:
    char* workingName = NULL;
    ...
    workingName = malloc( strlen( dirs[counter] ) + strlen( name ) + 1 );
    ...
    /* Then when you no longer need workingName. */
    free( workingName );

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,658
    > i get some warnings, but it runs thanks so much!!
    Bad idea, if you've got warnings, you've still got problems. The fact that it runs is as much down to dumb luck as it is to your skill.

    If you're confused about what a particular warning means, then feel free to post it and the relevant section of code it related to, then we should be able to tell you what it means.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    7
    Quote Originally Posted by Salem View Post
    > i get some warnings, but it runs thanks so much!!
    Bad idea, if you've got warnings, you've still got problems. The fact that it runs is as much down to dumb luck as it is to your skill.

    If you're confused about what a particular warning means, then feel free to post it and the relevant section of code it related to, then we should be able to tell you what it means.
    Code:
    /* This function is passed in a name of a executable file
     *	or is given an absolute file path name and then 
     *  checks to see if it exists.
     * Returns the path name if found, or null if not 
     *  found(an error is printed too). 
     */
    char *lookupPath(char *name)
    {
      char *pName;
      char *workingName[BUFSIZ];
      int counter = 0;
    
      while (dirs[counter] != NULL)
        {    
          //printf("Working on %s trying to find %s\n"
          //  , dirs[counter], name);
      
      if(name != NULL && name[0]  == '/')
        {
          if( access(name, X_OK) == 0 )
    	return name;
        }
      else 
        {	
          //This way didn't work so well...
    	  //strcat(workingName, "");
          //strcat(workingName, dirs[counter]);
          //strcat(workingName, "/");
          //strcat(workingName, name);
          
          sprintf(workingName, "%s/%s", dirs[counter], name);
          
          if( access(workingName, X_OK) == 0 )
    	return workingName;
          
          
        }
      counter++;
    }
      printf("Error %s was not found.", name);
    return NULL;
    }
    I get several warnings that i totally don't understand when i compile that. Here is the entire code so you may understand better....

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #define MAXPATHS 64
    
    char *dirs[MAXPATHS];
    
    /* This function will store the $PATH's found in the
     * global var *dirs[MAXPATHS].  Uses strtok, and is finished.
     */
    int parsePath()
    {
      //char *strtok(char *str1, const char *str2); This is the prototype
      char *path = getenv("PATH");
      char *delims = ":"; //TODO why does char delims[] = ":" also work here?
      char *result = NULL;
      result = strtok(path, delims);
      
      int counter = 0;
      while(result != NULL)
        {
          //printf("result is \"%s\"\n", result);
          dirs[counter] = result;
          counter++;
    
          /* Subisquent calls are made with 
           * NULL according to man page.*/
    
          result = strtok(NULL, delims); 
                                         
        }
      //www.elook.org/programming/c/strtok.html
    
      return 1;
    }
    
    /* This function is passed in a name of a executable file
     *	or is given an absolute file path name and then 
     *  checks to see if it exists.
     * Returns the path name if found, or null if not 
     *  found(an error is printed too). 
     */
    char *lookupPath(char *name)
    {
      char *pName;
      char *workingName[BUFSIZ];
      int counter = 0;
    
      while (dirs[counter] != NULL)
        {    
          //printf("Working on %s trying to find %s\n"
          //  , dirs[counter], name);
      
      if(name != NULL && name[0]  == '/')
        {
          if( access(name, X_OK) == 0 )
    	return name;
        }
      else 
        {	
          //This way didn't work so well...
    	  //strcat(workingName, "");
          //strcat(workingName, dirs[counter]);
          //strcat(workingName, "/");
          //strcat(workingName, name);
          
          sprintf(workingName, "%s/%s", dirs[counter], name);
          
          if( access(workingName, X_OK) == 0 )
    	return workingName;
          
          
        }
      counter++;
    }
      printf("Error %s was not found.", name);
    return NULL;
    }
    
    main(int argc, char *argv[])
    {
      int argc_dup = argc;
      parsePath();
      while (argc--)
        {
          //printf("%i", argc_dup - argc);
          if (NULL != argv[argc_dup - argc])
    	printf(lookupPath(argv[argc_dup - argc]));
    	  printf("\n");
        }
      printf("I'm done\n");
      exit(EXIT_SUCCESS);
    }

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,658
    > char *workingName[BUFSIZ];
    Given the use you have which follows, this should be
    char workingName[BUFSIZ];

    You allocated enough space, but the type was all wrong for the later usage.

    > strcat(workingName, "");
    The way to initialise a string to be empty would be one of the following
    strcpy(workingName, "");
    or
    workingName[0] = '\0';

    > return workingName;
    This is a really bad idea (did you get something like returning address of a local?)
    When the function returns, all the local variables go out of scope, and any pointer to a local becomes invalid.

    If you really need to return the working pathname as a result, then supply an additional parameter indicating where you want the result stored (see strcpy for example).

    > main(int argc, char *argv[])
    It's a good idea to be specific and say
    int main(int argc, char *argv[])
    and also have
    return EXIT_SUCCESS;
    at the end of main.

    Modern C frowns on implicit declarations, so getting into the habit of always saying what you mean is good.

    > int counter = 0;
    Strict C89 C (the most widely supported C standard) doesn't allow mixed declarations and statements. The GNU compilers will typically accept it unless you indicate otherwise.

    Likewise, // comments are a feature of C++, and of new (C99) C. A strict C89 compiler will throw them out.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    7
    Quote Originally Posted by Salem View Post
    > return workingName;
    This is a really bad idea (did you get something like returning address of a local?)
    When the function returns, all the local variables go out of scope, and any pointer to a local becomes invalid.

    If you really need to return the working pathname as a result, then supply an additional parameter indicating where you want the result stored (see strcpy for example).
    Thank you for your comments. This one i don't quite understand. So workingName here is a pointer? I though i was returning a string here...

  11. #11
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,211
    Mmmm no. This begs the question, "What do you think a string is?"

    A string is a contiguous block of memory that has a terminating '\0' element to signify the end of it. That's all a string is. It can be viewed as a char array or even a char *. What workingName will be returned as is a char **. workingName is an array of char *'s, not an array of chars.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,658
    > So workingName here is a pointer?
    In most cases, when you reference the name of an array, what you end up with is a "pointer to the first element of the array".

    So saying
    return workingName;
    is just the same as saying
    return &workingName[0];

    There is no mechanism in C to pass / return a whole array "by value". It is always passed / returned as a pointer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  2. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  3. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  4. creating class, and linking files
    By JCK in forum C++ Programming
    Replies: 12
    Last Post: 12-08-2002, 02:45 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM