Thread: Need help with simple, simple program.

  1. #1
    Registered User
    Join Date
    Sep 2005
    Posts
    41

    Need help with simple, simple program.

    Hiya I have a really simple program here that basically repeats what the user types at prompt. Here is an example run:

    dell4(1)>./driver -h
    Synopsis: Matt's Shell - it doesn't do much.
    Usage: driver [option]
    -h, --help prints this help message
    -p, --pwd tells the shell to include the current working directory in
    the prompt
    dell4(2)>./driver -h -p
    Synopsis: Matt's Shell - it doesn't do much.
    Usage: driver [option]
    -h, --help prints this help message
    -p, --pwd tells the shell to include the current working directory in
    the prompt
    dell4(3)>./driver -p
    dell4:/afs/umr.edu/users/matt/data/284/program1:>ls
    You typed: ls
    dell4:/afs/umr.edu/users/matt/data/284/program1:>word up
    You typed: word up
    dell4:/afs/umr.edu/users/matt/data/284/program1:>this is a test
    You typed: this is a test
    dell4:/afs/umr.edu/users/matt/data/284/program1:>!!
    You typed: this is a test
    dell4:/afs/umr.edu/users/matt/data/284/program1:>!!
    You typed: this is a test
    dell4:/afs/umr.edu/users/matt/data/284/program1:>exit

    Goodbye.

    dell4(4)>./driver
    dell4:>hellow world
    You typed: hellow world
    dell4:>The time is 4:13 pm....
    You typed: The time is 4:13 pm....
    dell4:>!!
    You typed: The time is 4:13 pm....
    dell4:>exit

    Goodbye.

    dell4(5)>


    Here is my code, I keep getting a segmentation fault when trying to compile:

    Code:
    #include <stdio.h>
    #include <getopt.h>
    #include <string.h>
    
    /* Precondition: pwdYESNO is passed from main without any mods
     * Postcondition: rest of program is ran */
    void ProcedeWithProg(int pwdYESNO);
    
    /* Precondition: none
     * Postcondition: help message is printed */
    void PrintHelpMessage();
    
    int main(int argc, char *argv[])
    {
       int userNeedsHelp = 0;
       int oc = 0;
       int pwdYESNO = 0;
    
       struct option longopts[] =
       {
          {"help", no_argument, NULL, 'h'},
          {"pwd",  no_argument, NULL, 'p'},
          {0, 0, 0, 0}
       };
    
       while((oc = getopt_long(argc, argv, "hp", longopts, NULL)) != -1)
       {
          switch(oc)
          {
             case 'h':
                PrintHelpMessage();
                userNeedsHelp = 1;
                break;
             case 'p':
    	        pwdYESNO = 1;
    	        break;
             case 0:
                /* getopt_long set a variable - nothing to do */
                break;
             case ':':
                /* missing option argument */
                fprintf(stderr, "%s: option '-%c' requires an argument\n",
                   argv[0], optopt);
                break;
             case '?':
                /* Invalid option */
             default:
                /* Invalid option */
                fprintf(stderr, "%s: option '-%c' is invalid: ignored\n",
                   argv[0], optopt);
                break;
          }
       }
    
       if(!userNeedsHelp)
       {
          ProcedeWithProg(pwdYESNO);
       }
    
       return 0;
    
    }
    
    void PrintHelpMessage()
    {
       printf("Synopsis: This program doesn't really do anything.\n");
       printf("Usage: driver [option]\n");
       printf("   -h, --help      prints this help message.\n");
       printf("   -p, --pwd       tells the shell to include the working dir in the prompt");
    }
       
    void ProcedeWithProg(int pwdYESNO)
    {
       char * string;
       char * prompt;
       char * hostNamePtr = getenv("HOSTNAME");
       char * pwdPtr = getenv("PWD");
       char * colon = ":";
       
       int bytes_read;
       int nbytes = 100;
       
       /*build prompt */
       if(!pwdYESNO)
       {
          strcpy(prompt, hostNamePtr);
       }
       else
       {
          strcpy(prompt, hostNamePtr);
          strcat(prompt, colon);
          strcat(prompt, pwdPtr);
       } 
    
       printf("%s:> ", prompt);
       string = (char *) malloc (nbytes + 1);
       bytes_read = getline (&string, &nbytes, stdin);
       
       if (bytes_read == -1)
       {
          printf("%s:> ERROR!\n", prompt);
       }
       else
       {
          printf("%s You Typed: %s\n", prompt,  string);
       }
       
    }
    any help/suggestions is greatly appreciated.

  2. #2
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by LightsOut06
    Here is my code, I keep getting a segmentation fault when trying to compile: any help/suggestions is greatly appreciated.
    You might want to look at is this section of code:
    Code:
       char * string;
       char * prompt;
       char * hostNamePtr = getenv("HOSTNAME");
       char * pwdPtr = getenv("PWD");
       char * colon = ":";
       
       int bytes_read;
       int nbytes = 100;
       
       /*build prompt */
       if(!pwdYESNO)
       {
          strcpy(prompt, hostNamePtr);   /* BOOM! SIGSEGV (sementation violation) */ 
       }
       else
       {
          strcpy(prompt, hostNamePtr);
          strcat(prompt, colon);
          strcat(prompt, pwdPtr);
       } 
    
       printf("%s:> ", prompt);
    Where is the pointer variable prompt ever initialised? What are you copying into 'prompt' with all of your strcpy() action? I don't think that is what you want anyway.

    Also, you ought to #include all of the necessary header files - you forgot <stdlib.h> for starters, and if you are using GNU getline, you need to factor in its proper usage as well.

    Further, you should read the FAQ about casting malloc().
    Last edited by kermit; 09-01-2005 at 06:41 PM.

  3. #3
    Registered User
    Join Date
    Sep 2005
    Posts
    41
    Quote Originally Posted by kermit
    Where is the pointer variable prompt ever initialised? What are you copying into 'prompt' with all of your strcpy() action? I don't think that is what you want anyway.

    Also, you ought to #include all of the necessary header files - you forgot <stdlib.h> for starters, and if you are using GNU getline, you need to factor in its proper usage as well.

    Further, you should read the FAQ about casting malloc().
    thanks for the faq, even though I still dont see what I did wrong. I wasn't awrae the the prompt variable had to be initialized. I'm copying the HOSTNAME and PWD variable from the linux enviroment into prompt and adding a : inbetween each. There's probably a much easier way to do this.

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by LightsOut06
    thanks for the faq, even though I still dont see what I did wrong. I wasn't awrae the the prompt variable had to be initialized. I'm copying the HOSTNAME and PWD variable from the linux enviroment into prompt and adding a : inbetween each. There's probably a much easier way to do this.
    Your code:

    Code:
    string = (char *)malloc (nbytes + 1);
    As you can see, you used a cast, which is not necessary any more (as per the FAQ, which you might want to read again). You can use something like the following instead:

    Code:
    string = malloc (nbytes + 1);
    As for the other matter, if you are going to use a pointer, you need to actually initialise it to point to an adress of some space that you can legally
    use.

    This is a simpler example of the sort of thing you have:
    Code:
        int *p;
        .....
        *p = 46;
    Where is the value 46 being stored? Declaring the variable p as a pointer to int did not allocate any space, that is for sure. You need to initialise the variable p something like this:

    Code:
        int *p;
        int q;
    
        .....
    
        p = &q;
        *p = 46;
    For your case, you might try malloc'ing some memory and point your pointer at that - then you will have some space to strcat() your variables in to it.
    Last edited by kermit; 09-01-2005 at 07:54 PM.

  5. #5
    Registered User
    Join Date
    Sep 2005
    Posts
    41
    Quote Originally Posted by kermit
    Your code:

    Code:
    string = (char *)malloc (nbytes + 1);
    As you can see, you used a cast, which is not necessary any more (as per the FAQ, which you might want to read again). You can use something like the following instead:

    Code:
    string = malloc (nbytes + 1);
    As for the other matter, if you are going to use a pointer, you need to actually initialise it to point to an adress of some space that you can legally use. You might try malloc'ing some memory and point your pointer at that - then you will have some space to strcat() your variables in to it.
    I actually got it working now. What I did was instead of initializing prompt as a pointer I initialized it like so:

    char prompt[100]="";

    For future reference, when would I want to initialize char variables as pointers and when would I want to initialize them without pointers. Also, I dont like initializing char variables with a limit on how big they can be. I know in C++ you could initialize them with a [] and they wouldn't have a size limit. How could I do this in C?

  6. #6
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by LightsOut06
    I actually got it working now. What I did was instead of initializing prompt as a pointer I initialized it like so:

    char prompt[100]="";
    Ah, yes - you allocated some actual space to hold your various strings which were strcat'd.

    For future reference, when would I want to initialize char variables as pointers and when would I want to initialize them without pointers.
    I think I did not explain things clearly enough - perhaps one of our more articulate members could do a better job explaining. When you need a pointer, use it - just be sure to initialise it before you use it (i.e, you need to store the address of another variable or perhaps some space already allocated by malloc and the like). As to which you use, it really depends on the requirements of the program.

    Also, I dont like initializing char variables with a limit on how big they can be. I know in C++ you could initialize them with a [] and they wouldn't have a size limit. How could I do this in C?
    Assuming that by 'char variables' you are referring to an array of type char, and by 'initializing' you mean 'declaring' - You will always have some sort of limit on the size of the array, or the amount of returned memory from malloc. You just have to learn to deal with memory limitations.

    Not knowing a whole lot about C++, I won't deal with it at all. In C, you can initialise a string like so:

    Code:
    char array[] = "Hello, Bob";
    The compiler will look after allocating enough space for the characters plus the '\0' to terminate the string. This notation is handy enough, but of course it is not exactly what you would call dynamic memory allocation I guess.

    For your case, I would say your best bet - not knowing the sizes of the strings to be appended to the 'prompt' string, I would get the length of each string with strlen(), and then add up all the sizes, and then malloc() a chunk of memory to be the correct size (including enough space for the terminating null character) and then do the strcpy() and strcat() operations.
    Last edited by kermit; 09-02-2005 at 04:16 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  2. [Help] Simple Array/Pointer Program
    By sandwater in forum C Programming
    Replies: 3
    Last Post: 03-30-2007, 02:42 PM
  3. simple silly program
    By verbity in forum C Programming
    Replies: 5
    Last Post: 12-19-2006, 06:06 PM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. Need help with simple DAQ program
    By canada-paul in forum C++ Programming
    Replies: 12
    Last Post: 03-15-2002, 08:52 AM