Thread: Getopt, optind, question

  1. #1
    Registered User
    Join Date
    May 2016
    Posts
    2

    Question Getopt, optind, question

    Hello guys.

    I guess I need some help with a program I try to create.
    In the end I want to have a seam carving program. And yes it is kind of an homework.
    But first things first. The problem I actually have is that I try to understand
    Code:
    getopt
    and make good use of it. But I fail at a single point and don't know why.

    In my opinion, the following, incomplete, code should handle all the incoming from the console/terminal and react in some way.
    For example if I type
    Code:
    /build/carve -s /data/owl.ppm
    it should not print the error message for a not found/valid picture (data/owl.ppm is a valid picture). But it does. If someone can help me I would be very happy!

    The code I have now is:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <getopt.h>
    #include <ctype.h>
    
    
    
    
    void help ()
    {
        fprintf (stderr, "\nCarve, a procedure for seam carving.\n\nUsage: carve [OPTIONS] <File>\n\n\nOptions:\n[-h]: Opens the help menu.\n\n[-s] <File>: Shows different statistics about the picture.\n\n[-p] <File>: Shows 'Spaltenindizes' of the picture.\n\n[-n <number>] <File>: Applies the algorithm n times on the picture.\nIf no <number> is given the algorithm runs until the end.\n\n\nThe file:\n<File>: The file has to be a '*.ppm' file.\nPlease use this format.\n\n");
    }
                    
    void stats ()     
    {
        fprintf(stderr, "space3\n");
        abort ();
    }
    
    
    int main (int argc, char **argv)
    {
      int helpflag = 0;
      int statflag = 0;
      int spaltenflag =0;
      int algovalue = 0;
      int c;
      opterr = 1;
    
    
      while ((c = getopt (argc, argv, "hspn:")) != -1)
        switch (c)
          {
          case 'h': helpflag = 1;       break; 
          case 's': statflag = 1;       break;
          case 'p': spaltenflag = 1;    break;
          case 'n': algovalue = optarg; break;
            
          case '?':
            if (optopt == 'n')
              fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
              fprintf (stderr, "Unknown option '-%c'.\n", optopt);
            else
              fprintf (stderr, "Unknown option character '\\x%x'.\n", optopt);           
            return 1;
          default:
            abort ();
          }
            
        int File = ((argc-1) == optind);
        if (File == 1)
        {
            FILE *Image = fopen (argv[optind],"r");
                if ((algovalue || statflag || spaltenflag) && !Image) 
                {    
                fprintf (stderr,"Something went wrong. No picture found.\n");
                exit(EXIT_FAILURE);
                }
        }    
        if (helpflag == 1)    
            help();    
        else if (statflag == 1)
            stats();
        else if (spaltenflag == 1)
            fprintf(stderr,"space\n");    
        else if (algovalue != 0)
            fprintf(stderr,"space2\n");
      return 0;
    }
    Thanks in advance! :)

  2. #2
    Registered User
    Join Date
    May 2016
    Posts
    2
    Solved the problem which was in Line 48.
    Code:
    if ( File == 1)
    I simply had to change it to:
    Code:
     if (File != 0)
    I'm not sure why.. But now it works

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Fnord View Post
    Solved the problem which was in Line 48.
    Code:
    if ( File == 1)
    I simply had to change it to:
    Code:
     if (File != 0)
    I'm not sure why.. But now it works
    As you suspect, that makes no sense and can't actually be the source of the problem. I assume File is used to ensure there's only one extra argument. Alternatively you could process multiple filenames in a loop.

    optarg is a char* so you can't assign it directly to an int. You should have received a warning about that. To fix it, try:
    Code:
    algovalue = atoi(optarg); // or use strtol if you need to check for errors.
    It is abnormal to set opterr to 1 and also handle errors yourself. Remove the '?' case. And don't even bother setting opterr to 1 since that's its default value. If you really want to handle the errors yourself then set opterr to 0.

    I don't understand this:
    Code:
                if ((algovalue || statflag || spaltenflag) && !Image)
    Surely if the file doesn't open that's enough of an error by itself to stop the program. Why do at least one of the OR'ed values also need to be non-zero? I may be missing something but that seems odd. If this is in some way related to the help option then it would be best to handle the help option before this point. Basically, if the help option is given then, no matter what else might be on the command line, the help is printed and the program exits (put an exit in help()).

    Lines that are 100's of characters long are unusual. You can split a string constant over multiple lines like this:
    Code:
    void help () {
        fprintf(stderr,
                "Usage: carve [OPTIONS] <File>\n"
                "A procedure for seam carving.\n\n"
                "Options:\n"
                "-h             Displays this help message.\n"
                "-s             Shows different statistics about the picture.\n"
                "-p             Shows 'Spaltenindizes' of the picture.\n"           // column indices?
                "-n <number>    Applies the algorithm n times on the picture.\n"
                "If -n option is not given the algorithm runs until the end.\n\n"   // until the end?
                "<File> must be a ppm file.\n");
        exit(0);
    }

  4. #4
    Registered User
    Join Date
    May 2016
    Posts
    2
    Hello, and a big thanks algorism for your help.

    Yes you are right with my odd "OR'ing" everything, that wasnt needed.
    I also found out that
    Code:
    exit(0)
    instead of
    Code:
    abort()
    is more usefull.
    With
    Code:
    atoi()
    all warnings are gone - next thing to do is to read what atoi does.
    Code:
     opterr = 0
    has to be set 0 because as you mentioned we should handle errors ourselfs.

    One problem that still remains is that i dont get an error while I fopen a folder.
    For my purpose it should fail but as I read fopen does also open directories.

    But if I try to 'handle' that case with fscanf I get a buffer error, which makes sense since i want to fscanf from a folder..

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. GETOPT() HElP!!!
    By Manu Lakaster in forum C Programming
    Replies: 7
    Last Post: 10-29-2013, 06:51 AM
  2. getopt
    By Dr Saucie in forum C Programming
    Replies: 1
    Last Post: 03-11-2010, 12:00 PM
  3. getopt()
    By sugumar.tr in forum C Programming
    Replies: 1
    Last Post: 07-09-2009, 04:52 AM
  4. getopt question
    By -EquinoX- in forum C Programming
    Replies: 5
    Last Post: 03-26-2009, 08:42 PM
  5. What is getopt?
    By samus250 in forum C Programming
    Replies: 2
    Last Post: 03-21-2008, 11:58 AM

Tags for this Thread