Problem with structs and strings in C

Discussion in 'C Programming' started by Bleakcabal, Feb 9, 2004.

  1. Bleakcabal

    Bleakcabal Guest

    Keep in mind my program is written in C ( not C++ ).

    I have a function which takes two structs as parameters is supposed to
    put the values of the source struct in the destination struct. Only
    the first character is put into the destination struct for each field.


    void AssignValues(info *source, info *destination)
    {
    *destination->name = *source->name;
    *destination->class = *source->class;
    *destination->alignment = *source->alignment;
    }


    Name, class and alignment are defined as
    char variableName[20];
    In a struct called info.

    If my source is : test, TEST example
    The destination is : t, T, e

    Why is that ?

    Thanks for your help.
    Bleakcabal, Feb 9, 2004
    #1
    1. Advertising

  2. Bleakcabal <> wrote:
    > Keep in mind my program is written in C ( not C++ ).
    >
    > I have a function which takes two structs as parameters is supposed to
    > put the values of the source struct in the destination struct. Only
    > the first character is put into the destination struct for each field.


    Use strcpy() or similar to copy strings.

    Stig

    --
    brautaset.org
    Stig Brautaset, Feb 9, 2004
    #2
    1. Advertising

  3. Bleakcabal

    pete Guest

    Bleakcabal wrote:
    >
    > Keep in mind my program is written in C ( not C++ ).
    >
    > I have a function which takes two structs as parameters is supposed to
    > put the values of the source struct in the destination struct. Only
    > the first character is put into the destination struct for each field.
    >
    > void AssignValues(info *source, info *destination)
    > {
    > *destination->name = *source->name;
    > *destination->class = *source->class;
    > *destination->alignment = *source->alignment;
    > }



    void AssignValues(info *source, info *destination)
    {
    *destination = *source;
    }

    --
    pete
    pete, Feb 9, 2004
    #3
  4. Bleakcabal

    Leor Zolman Guest

    On 9 Feb 2004 05:12:27 -0800, (Bleakcabal)
    wrote:

    >Keep in mind my program is written in C ( not C++ ).
    >
    >I have a function which takes two structs as parameters is supposed to
    >put the values of the source struct in the destination struct. Only
    >the first character is put into the destination struct for each field.
    >
    >
    >void AssignValues(info *source, info *destination)
    >{
    > *destination->name = *source->name;
    > *destination->class = *source->class;
    > *destination->alignment = *source->alignment;
    >}
    >
    >
    >Name, class and alignment are defined as
    >char variableName[20];
    >In a struct called info.
    >
    >If my source is : test, TEST example
    >The destination is : t, T, e
    >
    >Why is that ?
    >

    A few solutions have been posted, and they're correct given your
    context so far [just be careful: if you use strcpy, make sure the
    source strings have been initialized properly; if you use structure
    assignment, keep in mind that it will cease to work correctly if you
    were to change the type of any of your data members from arrays to
    pointers...and that may very well end up being your next step ;-) ]

    Another hint: if code involving arrays or pointers doesn't work right,
    carefully check the /types/ of the expressions involved. In this case,
    all six main expressions are of the form:
    * array
    Remember that array names used in /most/ expressions "decay" to being
    a pointer to their first element, so type-wise that equates to:
    * (char *)
    The *'s cancel leaving "char" as the type. Hence the char-to-char
    assignment.

    Rule of thumb: There's no single C assignment expression that can
    directly copy an array (you'd have to cheat and embed the array in a
    structure and copy the structure, which is why Pete's solution works
    so nicely in this case.)
    -leor



    Leor Zolman
    BD Software

    www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
    C++ users: Download BD Software's free STL Error Message
    Decryptor at www.bdsoft.com/tools/stlfilt.html
    Leor Zolman, Feb 9, 2004
    #4
  5. Bleakcabal

    Michael Guest

    Hi Pete,
    this seems to be similar to a
    question I posted earlier. But
    won't

    > *destination = *source;


    just copy the adresses of the array,
    s.th like a non-deep copy? So both
    structs share the strings?
    Kind Regards,
    Michael
    Michael, Feb 9, 2004
    #5
  6. Bleakcabal

    Leor Zolman Guest

    On Mon, 09 Feb 2004 15:49:13 +0100, Michael <> wrote:

    >Hi Pete,
    >this seems to be similar to a
    >question I posted earlier. But
    >won't
    >
    >> *destination = *source;

    >
    >just copy the adresses of the array,
    >s.th like a non-deep copy? So both
    >structs share the strings?


    Nope, there's no problem here because we're copying values, not
    addresses. If the data members of the structure were pointers, /then/
    we'd be copying addresses and inviting all sorts of undefined behavior
    down the road when the program begins freeing them (or at least chaos
    before that if the program expects the data being pointed to by the
    two separate pointers to be distinct.)
    -leor

    Leor Zolman
    BD Software

    www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
    C++ users: Download BD Software's free STL Error Message
    Decryptor at www.bdsoft.com/tools/stlfilt.html
    Leor Zolman, Feb 9, 2004
    #6
  7. Bleakcabal

    CBFalconer Guest

    Michael wrote:
    >
    > this seems to be similar to a
    > question I posted earlier. But
    > won't
    >
    > > *destination = *source;

    >
    > just copy the adresses of the array,
    > s.th like a non-deep copy? So both
    > structs share the strings?


    You removed context quotations, including all definitions. IIR
    you defined the fields within the structures as arrays, not as
    pointers, so there is nothing deep to copy.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Feb 9, 2004
    #7
  8. Bleakcabal

    Al Bowers Guest

    CBFalconer wrote:
    > Michael wrote:
    >
    >>this seems to be similar to a
    >>question I posted earlier. But
    >>won't
    >>
    >>
    >>> *destination = *source;

    >>
    >>just copy the adresses of the array,
    >>s.th like a non-deep copy? So both
    >>structs share the strings?

    >
    >
    > You removed context quotations, including all definitions. IIR
    > you defined the fields within the structures as arrays, not as
    > pointers, so there is nothing deep to copy.
    >


    The op definitions are a little unclear. There is some evidence
    that the members are typedef char array of 20 characters. If this
    is the case, struct assignment will be safe as will using function
    strcpy.

    Example:

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

    typedef char variableName[20];
    typedef struct info
    {
    variableName name;
    variableName class;
    variableName alignment;
    }info;

    info init = {"No data","No data", "No data"};

    void AssignValues1(const info *source, info *destination)
    {
    *destination = *source;
    }

    void AssignValues2(const info *source, info *destination)
    {
    strcpy(destination->name,source->name);
    strcpy(destination->class, source->class);
    strcpy(destination->alignment,source->alignment);
    return;
    }

    void PrintInfo(const info *p)
    {
    char *s = "No Data";
    printf("Name: %s\nClass: %s\nAlignment: %s\n\n",
    p->name,p->class,p->alignment);
    }

    int main(void)
    {
    info myinfo = {"George Washington","Political Science","Junior"};
    info newinfo = init;

    puts("struct newinfo contents");
    PrintInfo(&newinfo);

    newinfo = myinfo;
    puts("Using simple assignment");
    PrintInfo(&newinfo);
    newinfo = init;

    puts("Using function AssignValues1");
    AssignValues1(&myinfo, &newinfo);
    PrintInfo(&newinfo);
    newinfo = init;

    puts("Using function AssignValues2");
    AssignValues2(&myinfo, &newinfo);
    PrintInfo(&newinfo);

    return 0;
    }
    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x to send email)
    http://www.geocities.com/abowers822/
    Al Bowers, Feb 9, 2004
    #8
  9. (Bleakcabal) writes:

    > Keep in mind my program is written in C ( not C++ ).


    Anybody who assumes otherwise is in the wrong newsgroup.

    > I have a function which takes two structs as parameters is supposed to
    > put the values of the source struct in the destination struct. Only
    > the first character is put into the destination struct for each field.


    /* You really should post _complete_, _compilable_ examples. I have
    inserted my own assumptions of what you meant; I could be wrong. */
    typedef struct {
    char name[20];
    char class[20];
    char alignment[20];
    } info;

    > void AssignValues(info *source, info *destination)
    > {
    > *destination->name = *source->name;
    > *destination->class = *source->class;
    > *destination->alignment = *source->alignment;
    > }


    > Name, class and alignment are defined as
    > char variableName[20];
    > In a struct called info.
    >
    > If my source is : test, TEST example
    > The destination is : t, T, e
    >
    > Why is that ?


    You appear to have misunderstood what all the *s mean. You're
    explicitly copying the first character only of each character array -
    your first statement above is equivalent to

    destination->name[0] = source->name[0];

    (Note also that, depending on how the object passed in as destination
    is defined, the terminating '\0's that have magically appeared in
    destination->name[1] et al may not be guaranteed. If you had shown a
    complete compilable program, we would be able to tell.)

    Try replacing it (and the other two similarly) with

    memchr(source->name, '\0', 20) ||
    strcpy(destination->name, source->name);

    (You will need to
    #include <string.h>
    somewhere earlier as well.)

    And unadorned magic numbers are bad form.

    mlp
    Mark L Pappin, Feb 10, 2004
    #9
  10. I wrote, moments ago, stuff which included:
    > (Bleakcabal) writes:


    > > *destination->name = *source->name;


    > Try replacing it (and the other two similarly) with
    >
    > memchr(source->name, '\0', 20) ||

    /*fix*/ memchr(source->name, '\0', 20) &&
    > strcpy(destination->name, source->name);
    >
    > (You will need to
    > #include <string.h>
    > somewhere earlier as well.)


    (What was I thinking? And where did the _second_ || come from?)

    And I suppose I should elaborate: If you can guarantee that each field
    in source is properly initialized with a valid ('\0'-terminated) C
    string which is no larger than the space allocated, then you can leave
    off the memchr() call above. If you can't, then you should use some
    mechanism to ensure that you do not merrily write past the end of any
    of the arrays in destination - the call to memchr() above does this,
    once the correct logical operator is used, but there are other ways
    including use of strncpy() although it may write more '\0's than it
    needs to.

    mlp
    Mark L Pappin, Feb 10, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patricia  Van Hise

    structs with fields that are structs

    Patricia Van Hise, Apr 5, 2004, in forum: C Programming
    Replies:
    5
    Views:
    635
    Al Bowers
    Apr 5, 2004
  2. Chris Hauxwell

    const structs in other structs

    Chris Hauxwell, Apr 23, 2004, in forum: C Programming
    Replies:
    6
    Views:
    557
    Chris Hauxwell
    Apr 27, 2004
  3. Paminu
    Replies:
    5
    Views:
    641
    Eric Sosman
    Oct 11, 2005
  4. Daniel Rudy
    Replies:
    15
    Views:
    1,395
    Keith Thompson
    Apr 10, 2006
  5. Tuan  Bui
    Replies:
    14
    Views:
    473
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page