need C help, passing char buffer[] by-value....

Patrick Mahan mahan at mahan.org
Mon Oct 19 18:35:05 UTC 2009


See comments interspaced below -

Gary Kline wrote:
> On Mon, Oct 19, 2009 at 01:48:42AM -0400, Brad Mettee wrote:
>> Gary Kline wrote:
>>> Guys,
>>>
>>> maybe this can't be done reading in a file with fgets(buffer[128], fp),
>>> then calling skiptags(), conditionally, to while () past ',' and '>'.
>>>
[snipped]
> 
> 	It didn't core dump, but neither work.  Basically, I'm doing a read via fgets:
> 
> 	"while(fgets(buf, sizeof buf, fp_in)) {"
> 
> 	an HTML or other file with <TAGS>.  Optionally, say, given the switch -N,
> 	the program would NOT progress any of the HTML tags; It would only touch other
> 	stuff in the file.  Simply put, I have a fixed buffer, buf[1024], that I want to
> 	change --i think by-reference-----not certain-----by calling 
> 
> 	skiptags(*&buf); and skiptags() would read past the <WHATEVER="7" FOO="6" BAR="Times">
> 	and return the buffer to the place after fgets() where skiptags(&buf) is called
> 	missing all markup <TAGS>.
> 
> 	I'm better at by-refernce with ints that chars, so I don't know how far off I am
> 	here.  That's why I;'m asking you guys.
> 

Gary,

Let me restate your problem: You want to read through a file containing tags
delimited by "<>" and to skip these tags if the user has run your command with
the "-N" flag.

In C any thing passed by address is "by reference".  For a your static buffer
of 1024 characters: you can pass it by reference as:

            skiptags(buf); /* passes in the starting address of the buffer */
            skiptags(&buf[0]); /* passes in the starting address of the buffer */
            skiptags(&buf[10]); /* passes int the starting address of the buffer
                                   at the 11th character position. */

Arrays and pointers are always by reference.  Individual data types "int",
"char", etc are by value unless passed in as a pointer.  I think this is where
your confusion is around.

A couple of things to keep in mind:

    1. Remember how fgets() works.  It is entirely possible that you might have
       tags that span multiple lines.  You will need to take that into account.

    2. You can manipulate the fixed buffer two different ways:

       A. You can use pointer arithemtic, eg.

          char buf[1024];
          char *cp;

          while ((cp = fgets(buf, sizeof(buf), fp_in))) {

                if (skiptags) cp = skiptag(buf);

                /* If NULL, end of line reached */
                if (!cp) continue;

          }

          char *skiptags(char *buf)
          {
	      char *tp = buf;

               /* find the start of a tag */
               while (*tp != '\0' && *tp++ != '<');

               /* if no tag is found return start of buffer */
               if (*tp == '\0')
                  return buf;

               /* Start of tag, find the end of tag */
               while (*tp != '\0' && *tp != '\n' && *tp++ != '>');

               /* if end of line reached return NULL */
               if (*tp == '\0' || *tp == '\n')
                  return NULL;

               /* return the next character start after the end tag */
               return ++tp;
          }

        B. Using indexing, eg.

          char buf[1024];
          int  i, bsize;

          while (fgets(buf, sizeof(buf), fp_in)) {
                i = 0;
                bsize = strlen(buf);

                if (skiptags) i = skiptag(buf);

                /* If NULL, end of line reached */
                if (i >= bsize) continue;

          }

          int skiptags(char *buf)
          {
	      int c = 0;

               /* find the start of a tag */
               while (buf[c] != '\0' && buf[c] != '<')
                      c++;

               /* if no tag is found return start of buffer */
               if (buf[c] == '\0')
                  return 0;

               /* Start of tag, find the end of tag */
               while (buf[c] != '\0' && buf[c] != '\n' && buf[c] != '>')
                      c++;

               /* if end of line reached return NULL */
               if (buf[c] == '\0' || buf[c] == '\n')
                  return strlen(buf);

               /* return the next character start after the end tag */
               return ++c;
          }

Both methods should allow you to skip past any tags found in the file (provided
you handle the case of a tag spanning more than one line).


Hope this clears up your confusion and gets you on your way.

Patrick


More information about the freebsd-questions mailing list