• C

argv substr() question

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
LVL 3
loki982Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

not_an_xpertCommented:
refer to the function  strtok
dat wud help u
0
not_an_xpertCommented:
0
Sys_ProgCommented:
I guess u can use strtok

char *str ;
str = strtok ( povf, "." ) ;
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

AjarCommented:
//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
brettmjohnsonCommented:
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
Kent OlsenData Warehouse Architect / DBACommented:

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
loki982Author Commented:
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
Kent OlsenData Warehouse Architect / DBACommented:

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
loki982Author Commented:
Everything works perfectly!
Thankz for the help all,
LoKi
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.