Solved

argv substr() question

Posted on 2003-10-30
9
642 Views
Last Modified: 2012-08-14
Hello all,
I am mostly a c++ programmer, now programming UPC on a cray so please bare with me.
I am trying to parse a string from argv and am having a few troubles.
ex: entering the following "./CraPov -[option] povrayfile.pov"
I would like to parse argv to return [povrayfile] (without the ".pov" extention)

I was wondering if there is a simple function to do this for me or if i have to use substr() and write my own. Thankz for your help in advance.

Simplified version of code is as follows:

int main(int argc, char **argv) {
      int pf;
      char povf[32];

      pf = argc - 1;
      sprintf(povf,"%s",argv[pf]);
        // Code to parse string
      printf("%s",povf);
      printf("\n");

Thankz,
LoKi
0
Comment
Question by:loki982
  • 2
  • 2
  • 2
  • +3
9 Comments
 

Expert Comment

by:not_an_xpert
ID: 9655597
refer to the function  strtok
dat wud help u
0
 

Expert Comment

by:not_an_xpert
ID: 9655619
0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 9655643
I guess u can use strtok

char *str ;
str = strtok ( povf, "." ) ;
0
 
LVL 6

Expert Comment

by:Ajar
ID: 9655918
//suppose  you have argv[1] ="abc.prov"
// then use following code

char buf[32],*tmp;
strcpy(buf,argv[1]);

tmp = buf;

while( *tmp !='.') tmp++;
// you have found a '.' so terminate the string by making this character as \0 or null

if(*tmp == '.') *tmp ='\0';

// this makes buffer to be  "abc"
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 23

Expert Comment

by:brettmjohnson
ID: 9656075
All previous solutions will fail on "./povrayfile.pov", "./povrayfile", or "abc.tar.gz"

#include <string.h>
#include <libgen.h>

/* check for '.' in just the basename first so you don't trip on "./filename"  
 * use rindex so you strip off only the last extension
*/

if (rindex(basename(arg), '.'))
     * rindex(arg, '.') = '\0';

0
 
LVL 45

Expert Comment

by:Kdo
ID: 9657694

Hi loki982,

Lot's of suggestions here.  All seem to trip on the issue of embedded periods.  It would seem that the key item isn't just the period, but the slash.  As several posts have pointed out, the file name could also be a path.

int main (int argc, char *argv)
{
  char *FileName;

  FileName = GetFileName (arvg[argc-1]);  /* Sanity check required for parameter count!  */

  fprintf (stdout, "File name is '%s'\n", FileName);
}

/*
  Return the file name portion of a path
  If the file name contains an extension, drop the extension
*/

char *GetFileName (char *FileName)
{
  char *cc, *oc;
  char *tfn;
  char *Fn = strdup (FileName);  /* Make our own string so as to not change the original!  */

/*  Look for the LAST '/' delimeter  */

  occ = FileName;
  while (cc = strchr (occ, '/'))
    occ = cc;

  tfn = occ;  /*  tfn points to the filename portion of the path*/

/*  Now look for the LAST '.' in the file name */

  while (cc = strchr (occ, '.'))
    occ = cc;

  if (*occ == '.')  /*  The file name contained at least one period so we'll end the string at the last one */
    *occ = 0;

  tfn = strdup (occ);  /*  Make a string that is the desired filename  */
  free (Fn);              /*  Free the scratch buffer that contained the original path  */
  return (tfn);
}


Let me caution that this is dangerous.  Instead of arbitrarily dropping the extension, the function should check that the extension is an allowed type.  If so, it can then drop the extension, if not the function should probably return NULL so that the calling function can inform the user that an an invalid file was entered.  To make this happen, replace:

  if (*occ == '.')
    *occ = 0;

with

  if (*occ == '.')  /*  The file name included an extension  */
  {
    if (strcmp (occ+1, "pov") == 0)  /*  Valid extension  */
      *occ = 0;
    else
    {
      free (Fn);
      return (NULL);
    }
  }


Cray programmer huh?  I'm and old CDCer with experience on everything that they made after the 3000 series.  Another common poster here is grg99 who goes back to CDC's 160A days!  How about sending me a note offline -- my e-mail address is in my profile.


Kent
0
 
LVL 3

Author Comment

by:loki982
ID: 9666911
kent,
sorry it took so long to respond(halloween &all)
overall this seems to work quite well...
though the options are still giving me bit of a headache

i am trying to get the arguments before the povfile
i have a working version within main but i'm trying
like hell to get it into a function with no luck
i just don't know how to increment PovOp correctly
any help would be greatly appreciated


when executed:

$ ./a.out -foo -bar hello.pov
File name is 'hello'
Povray Options are '-foo -bar '
Povray Options are '-foo'


Code is as follows:

#include <stdio.h>
#include <string.h>

char *GetFileName(char * FileName);
char *GetOptions(char * PovOp, int OpLen);

int main(int argc, char **argv) {
      char *FileName,*FN;
      char *Options;
      char OP[256][256];
      char PovOp[256];
      int i,pop;

      FileName = GetFileName(argv[argc-1]);

      // options works in main...
      if(argc>2) {
            strcpy(PovOp,argv[1]);
            strcat(PovOp," ");
            if(argc>3) {
                  for(i=2;i<argc-1;i++) {
                        strcat(PovOp,argv[i]);
                        strcat(PovOp," ");
                  }
            }
      }
      else {
            sprintf(PovOp,"");
      }

      Options = GetOptions(argv[1],argc-1);

      fprintf(stdout,"File name is '%s'\n",FileName);
      fprintf(stdout,"Povray Options are '%s'\n",Options);      
      fprintf(stdout,"Povray Options are '%s'\n",PovOp);
}

char * GetOptions(char *PovOp, int OpLen)
{
      int pl,i;
      char PO[256];
      char *pf;
      char *poptr;
      char *tfn;
      pl = OpLen;
      if(pl>2) {
            strcpy(PO,PovOp);
            strcat(PO," ");
            if(pl>3) {
                  for(i=2;i<pl-1;i++) {
                        strcat(PO,PovOp);
                        strcat(PO," ");
                        // unshure how to increment PovOp
                  }
            }
      }
      else {
            sprintf(PovOp,"");
      }
      return(PovOp);
}

char *GetFileName(char *FileName)
{
      char *a2F, *a2E;
      char *fnptr;
      char *tfn;
      char *Fn = strdup(FileName);
      fnptr = FileName;
      while(a2F = strchr(fnptr,'/')) {
            fnptr = a2F;
            fnptr++;
      }
      a2E = fnptr;
      while(a2F = strchr(a2E,'.')) {
            a2E = a2F;
            a2E++;
      }
      a2E--;
      if(*a2E=='.') {
            if(strcmp(a2E+1,"pov")==0) {
                  *a2E = 0;
            }
            else {
                  fprintf(stderr,"Filename Mismatch");
                  exit(1);
            }
      }
      free(Fn);
      return(fnptr);
}
0
 
LVL 45

Accepted Solution

by:
Kdo earned 50 total points
ID: 9670500

Hi loki,

I'm unsure of where you're trying to go so I'll venture a guess:

If you want the function to build the options table just as main() does now:

  Just move the code in main() to the function and call it as GetOptions (argc, argv);  Note that main() doesn't really BUILD an options table.  It constructs a string that is the concatenation of all of the options on the command line.  (This is probably not real useful to you.)  The reason that the function seems to be failing is that the function call:

  Options = GetOptions(argv[1],argc-1);

advances to start with the first parameter after the command name by incrementing the index and decrementing the count.  GetOptions() and main() are hard-coded to look for a parameter by position.  Note that main checks by "if (argc > 2)" and "if (argc > 3)".  The functions uses these exact same checks (with variable *pl*).  *pl* is derived from OpLen, which has the value of argc-1 so you seem to miss the last options parameter.


Note also that there's an easier way.

strcpy (PovOP, "");
for (int idx = 1; idx < argc; idx++)
  if (*argv[idx] == '-')
  {
    strcat (PovOP, argv[idx]);
    atrcat (PobOP, " ");
  }


This builds the string from all of the parameters that begin with "-".  Perhaps not what you need, but in some instances this could be exactly what you want.  Consider the command line:

Cmd [<options> Filename1 ...] ...

This expands to something like this:

Cmd -a -s -d -r -t -f F1 F2 F3 -a -q -w -e -r F4 F5 F6 F6 -s -d -f F7 (etc...)

Using the snippet above (with breaks at the file names) you can capture the appropriate flags, process the files associated with those flags and move on.

Very few commands actually use this format, but there are a few.

Kent

0
 
LVL 3

Author Comment

by:loki982
ID: 9676418
Everything works perfectly!
Thankz for the help all,
LoKi
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

762 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now