Thread: strings & fields

  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    strings & fields

    hi,
    The pseudo-code for my C function is this :

    getwsfield locates the specified field in the string s,
    * where a field is a non-empty string surrounded by white space.
    * The field is copied to buf, which has room for buflen bytes
    * (including a terminating '\0'). Buflen must be at least 1.
    * If the field doesn't exist, an empty string is placed in the buffer.
    * If copy_to_end is false, only the requested field is copied,
    * otherwise the rest of the string from the specified field onwards is copied.
    */

    So far i have managed to get this far:
    #include <ctype.h>
    #include <string.h>


    void getwsfield(char *s, int fieldnum, Bool copy_to_end,
    char *buf, int buflen)


    {
    char *sp; /* Cursor to identify fields in s */

    sp = s;
    while (isspace(*sp))
    sp++;

    }

    I have therefore managed to use the isspace function to skip to the start of the first field.
    However, i need to write a loop that skips unwanted fields, so that for a specified field number, the loop skips all the fields preceding it - eg field number 3 required - skip 2 fields.
    So the loop needs to skip to next space (or end of string)
    and skip over spaces between fields


    for (nf=1; nf < fieldnum; nf++) {


    }


    what should be the contents of the above loop?
    thanks.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Provide an example string. It'll be much easier to visualize what you're trying to accomplish. What you should probably do is make a function that skips a single field (to the start of a new field or tag or whatever it is you're using), and then loop through that process a given number of times.
    Code:
    for( n = 0; n < field_to_find; n++ )
        ptr = skipfield( ptr );
    Something like that.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    5
    sorry just a query - probably missing something obvious.

    is ptr - a variable that stands for pointer and skipfield a library function?

    also when you say provide a sample string - am i to use a simple scanf statement?
    thanks
    marko

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    (1) Yes. It would basicly be something like:
    Code:
    char *skipfield( char *fieldlist )
    {
        while( *fieldlist != SOMETHING )
            fieldlist++;
        return ++fieldlist;
    }
    There's a real quick hack at what you'd be looking at. Basicly you run through your data until you find the "end of a field" marker, however you have that set up, then you'd return the pointer just past that mark. Naturally you'd do error checking and what not.

    This is basicly what strchr does.


    (2) I meant, what does your data look like?

    123,mystringherethisisfield,456,thisisthe2ndfield

    Something like that or what exactly? That'd give me an easier idea of how to tell you how your function/search would work.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    Unhappy

    Thankyou for your response.

    The required function, extracts a field from a string, where a field is defined as a string surrounded by white space (spaces, tabs, newlines or carriage-returns). Although superficially similar to the string tokeniser it does not destroy the original string but returns a copy of the requested data in a buffer supplied by the caller.

    The data that is used in the file that will be accessed by this functions is in diary format:
    filename/year/month - the function will be used as part of a bigger diary record ( that part is easier )

    q1.so although strchr will help me search for the first occurence of a character (or whitespace ) and returns a pointer if true and a null if not, how would that help in skipping unwanted fields?
    if we take the string

    ***C*can*be*frustrating**
    where * indicates a whitespace

    and I want to to skip unwanted fields. How many fields are unwanted? Well, if the specified field number is 1, don't skip any. If it's 2, skip one; if 3, skip 2 and so on. The loop so far looks like this:

    for (nf=1; nf < fieldnum; nf++) {


    }




    is that where I am supposed to use your example of strchr:

    char *skipfield( char *fieldlist )
    {
    while( *fieldlist != SOMETHING )
    fieldlist++;
    return ++fieldlist;
    }

    q2.
    in the above code - where skipfield is your function, what is field list? is it the count of number of fields.

    Thanks again quzah,
    Marko

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    5
    quzah,

    I read my post and realised that it was confusing. I understand that this is an assignment based question and am not expecting too many answers here!

    Consider a line that looks like this (spaces are shown with the symbol · ):
    ····2003··COMP9021···Principles·of·Programming··
    If we have short, 10-byte buffer called shortbuf, the following table shows what the function would place in the buffer (including the null character \0): fieldnum, copy_to_end contents of shortbuf
    1, FALSE 2003\0
    4, FALSE of\0
    5, FALSE Programmin\0
    6, FALSE \0
    1, TRUE 2003··COM\0
    7, TRUE \0
    If you had a big enough buffer, the call
    getwsfield(line, 2, TRUE, bigbuf, sizeof bigbuf)
    would produce the complete string
    COMP9021···Principles·of·Programming··\0

    Therefore, the data that I am looking at is in the form
    COMP9021···Principles·of·Programming··\0

    Despite looking over your example of strchr:
    char *skipfield( char *fieldlist )
    {
    while( *fieldlist != SOMETHING )
    fieldlist++;
    return ++fieldlist;
    }

    I am unsure how this fits in with the contents of my for loop:

    for (nf=1; nf < fieldnum; nf++) {


    }


    The purpose of this is so that sp points to the start of the requested field, or points to the null-terminator if there aren't enough fields in the string.
    My query is the coding used to 'skip' to the required field?
    Sorry for any confusion
    Marko

  7. #7
    waltp
    Guest

    Try this

    Given the setup code:
    {
    char field[x];
    char line[y];

    GetField(n, line, field); // n is field number to return

    ...
    }

    // Return the pointer to ws after the returned field
    char * GetField(int f, char *ln, char *fld)
    {
    char *p;
    int i;

    p = ln;
    p = SkipWhiteSpace(p);
    for (i = 1; i < f; i++)
    {
    p = GetField(p, fld);
    p = SkipWhiteSpace(p);
    }
    p = GetField(p, fld);
    return;
    }

    SkipWhiteSpace will advance the pointer 'p' for each whitespace character

    GetField will advance the pointer 'p' for each nonwhitespace character and load the character into the fld pointer

    Add another
    p = SkipWhiteSpace(p);
    to return the pointer to to the next field instead of the whitespace.

    Hope this helps.
    Walt

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    Unhappy

    Walt,
    thank you for your response - Here is what _ have written so far:
    (the contents of the header file getwsfield.h are:

    Code:
    #ifndef DATELIB_H   /* define Bool only if needed (also in datelib.h) */
    typedef enum { FALSE, TRUE } Bool;
    #endif
    
    /* getwsfield locates the specified field in the string s,
     * where a field is a non-empty string surrounded by white space.
     * The field is copied to buf, which has room for buflen bytes
     * (including a terminating '\0'). Buflen must be at least 1.
     * If the field doesn't exist, an empty string is placed in the buffer.
     * If copy_to_end is false, only the requested field is copied,
     * otherwise the rest of the string from the specified field onwards is copied.
     */
     void getwsfield(char *s, int fieldnum, Bool copy_to_end,
            char *buf, int buflen);

    getwsfield.c:


    Code:
    * Purpose:Extracts a single field or field and trailing from a string into user-supplied buffer.*/
    
    #include "getwsfield.h"
    
    #include <ctype.h>
    #include <string.h>
    
    /* getwsfield locates the specified field in the string s,
     * where a field is a non-empty string surrounded by white space.
     * The field is copied to buf, which has room for buflen bytes
     * (including a terminating '\0'). Buflen must be at least 1.
     * If the field doesn't exist, an empty string is placed in the buffer.
     * If copy_to_end is false, only the requested field is copied,
     * otherwise the rest of the string from the specified field onwards is copied.
     */
    void getwsfield(char *s, int fieldnum, Bool copy_to_end,
            char *buf, int buflen , int s;
    
            main ()
           
    {
    
    char  *sp;  /* Cursor to identify fields in s */
    
    sp = s;
    while (isspace(*sp))
        sp++; /*isspace returns true if the character passed to it
         (which could be a pointer dereference like *sp) is a whitespace character*/
    
         }
         
        char x,y,p,f;
         {
    char field[x];
    char line[y];
    
    GetField(n, line, field); /* n is field number to return */
    
    }
    
    /*Return the pointer to ws after the returned field*/
    char * GetField(int f, char *ln, char *fld)
    {
    char *p;
    int i;
    
    p = ln;
    /*SkipWhiteSpace will advance the pointer 'p' for each whitespace character*/
    p = SkipWhiteSpace(p);
    for (i = 1; i < f; i++)
    {
    	
    /*GetField will advance the pointer 'p' for each nonwhitespace character and load
     the character into the fld pointer*/
    p = GetField(p, fld);
    p = SkipWhiteSpace(p);
    }
    p = GetField(p, fld);
    return 0;
    
         }
    When I tried to 'make' getwsfield.c, I got quite a few errors:

    gcc -Wall -g -c getwsfield.c
    getwsfield.c:23: conflicting types for `s'
    getwsfield.c:22: previous declaration of `s'
    getwsfield.c:25: parse error before "main"
    getwsfield.c: In function `getwsfield':
    getwsfield.c:27: number of arguments doesn't match prototype
    getwsfield.h:22: prototype declaration
    getwsfield.c:31: `s' undeclared (first use in this function)
    getwsfield.c:31: (Each undeclared identifier is reported only once
    getwsfield.c:31: for each function it appears in.)
    getwsfield.c: At top level:
    getwsfield.c:39: parse error before '{' token
    getwsfield.c:41: variable-size type declared outside of any function
    getwsfield.c:43: warning: type defaults to `int' in declaration of `GetField'
    getwsfield.c:43: warning: parameter names (without types) in function declaratio
    n
    getwsfield.c:43: warning: data definition has no type or storage class
    getwsfield.c:45: parse error before '}' token
    getwsfield.c:49: conflicting types for `GetField'
    getwsfield.c:43: previous declaration of `GetField'
    getwsfield.c: In function `GetField':
    getwsfield.c:55: warning: implicit declaration of function `SkipWhiteSpace'
    getwsfield.c:55: warning: assignment makes pointer from integer without a cast
    getwsfield.c:61: warning: passing arg 1 of `GetField' makes integer from pointer
    without a cast
    getwsfield.c:61: too few arguments to function `GetField'
    getwsfield.c:62: warning: assignment makes pointer from integer without a cast
    getwsfield.c:64: warning: passing arg 1 of `GetField' makes integer from pointer
    without a cast
    getwsfield.c:64: too few arguments to function `GetField'
    make: *** [getwsfield.o] Error 1

    I understand some of these errors, but not c:55 onwards.
    I was advised to use a scanf statement, after my isspace loop.. should I now use the statement after your skipwhitespace loop?
    Thanks again,
    Marko

  9. #9
    Registered User
    Join Date
    Mar 2003
    Posts
    143
    c:55 is because you have not defined or declared 'SkipWhiteSpace' (its not a library function, you have to write it) the compiler is probably making the assumption (or guess) that this function is declared externally that returns an int. This happens to be incorrect in this case so you get another error about casting int to pointer...

    The other errors are because you have called GetField() with only two parameters rather than three.

    Hope that helps you a bit,

  10. #10
    Walt
    Guest
    Marko, I apologize, DavT is correct. I forgot to mention that SkipWhiteSpace() and GetField() are routines you need to write.

    Don't forget in GetField() that just before you return, you must add a null after the last character in 'fld' to 'end the string'

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    void getwsfield(char *s, int fieldnum, Bool copy_to_end,
    char *buf, int buflen , int s;
    You forgot your closing parenthesis on your function prototype. Furthermore, your code is far from complete. You don't have a matching number of { and } pairs. That also is a problem.

    [edit]Actually, you have the correct number. They're just horribly in the wrong places. Try indenting your code at every { and unindenting at every }. It will make it much more readable.[/edit]

    Quzah.
    Last edited by quzah; 05-01-2003 at 01:44 PM.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  2. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  3. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  4. menus and strings
    By garycastillo in forum C Programming
    Replies: 3
    Last Post: 04-29-2002, 11:23 AM