pointer to a structure (simple question for a real C programmer) 
Author Message
 pointer to a structure (simple question for a real C programmer)

I am a long time mainframe assembler programmer that is struggling
with what is probably a simple issue.

I have a C program that is called by an assembler program.  The
assembler program passes an address of a piece of storage to the C
program.

The storage contains a variety of fields.  I want to be able to access
one of those fields in the C program.  It is a fullword binary field.

I know I need a struct.   My problem is getting addressablity to the
struct.

Program snippets follow:
********************************************************************
<snip>
typedef struct jrbdsub_type{
  char jrbdsub_subcode[4];
  char jrbdsub_filler[44];
  int jrbdsub_suberrno;

Quote:
} jrbdsub;

<snip>
int main(int argc, char **argv)
<snip>
struct jrbdsub_type *st_ptr;
<snip>
subptr = (int) argv[5];
<snip>
st_ptr = (jrbdsub*) subptr;
if (st_ptr->jrbdsub_subcode=='SUB ')
{
 printf( "found the subcode\n");
Quote:
}

********************************************************************

When I compile the C program I receive:

CBC3076 Character constant 'SUB ' has more than one character. No more
than rightmost 4 characters are used.
CBC3068 Operation between types "unsigned char*" and "int" is not
allowed.

I know that subptr contains a good pointer to the storage (because an
assembler program I call later can use it successfully).

1) am I loading the st_ptr correctly in order to get addressability to
jrbdsub?
2) How can I get rid of the compile errors.
3) How many other ways am I screwing this up?

Thanks very much.



Mon, 10 Oct 2005 02:59:21 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

> I am a long time mainframe assembler programmer that is struggling
> with what is probably a simple issue.
> I have a C program that is called by an assembler program.  The
> assembler program passes an address of a piece of storage to the C
> program.
> The storage contains a variety of fields.  I want to be able to access
> one of those fields in the C program.  It is a fullword binary field.
> I know I need a struct.   My problem is getting addressablity to the
> struct.
> Program snippets follow:
> ********************************************************************
> <snip>
> typedef struct jrbdsub_type{
>   char jrbdsub_subcode[4];
>   char jrbdsub_filler[44];
>   int jrbdsub_suberrno;
> } jrbdsub;
> <snip>
> int main(int argc, char **argv)
> <snip>
> struct jrbdsub_type *st_ptr;
> <snip>
> subptr = (int) argv[5];

argv[5] isn't a value but a string (if it exists). A C program gets a
number (argc) of strings (i.e char arrays, with a 0 as the last element)
as its arguments. You will have convert it back to the type you need
before you can use it. Just casting won't help you, if you pass a
program e.g. "534" on the command line, the program will get a string
(i.e. an char array containing the characters '5', '3', '4' and '\0')
and not an int with a value of 534.

But in this case I doubt that it will work at all if you want to pass
your program an address belonging to a different program unless you
are working on a system where each process can access the memory of
all other processes (and it's getting quite off-topic for c.l.c. since
standard C does not know about the mere existence of more than one
process). Under normal modern OSes each process has its own memory
space and an address passed to it from another process will mean
nothing to the program...

And even if this works because your system allows it, the layout of the
structure may look quite different from what you expect. The compiler
can insert as many padding bytes between the elements of the structure
as it thinks necessary or prudent (and a different compiler is allowed
to have different opinions). This would be one of the cases where you
wouldn't use a structure directly but do the unpacking manually byte
by byte and the push the extracted data into a structure.

Quote:
> <snip>
> st_ptr = (jrbdsub*) subptr;
> if (st_ptr->jrbdsub_subcode=='SUB ')

You can't compare strings in C using '==' (and 'SUB ' isn't be a
string anyway, you would need "SUB ", i.e. in double quotes), with
'==' you compare if the address stored in 'st_ptr->jrbdsub_subcode'
is identical to the address 'SUB '. But since 'SUB ' isn't a pointer
but is treated as an int, you get your compiler warning. If you want
to compare strings you need the function strcmp(), and strncmp() if
you want to compare only some parts of two strings.

And here you will need strncmp() because 'st_ptr->jrbdsub_subcode'
can't hold the string "SUB ", this string requires 5 chars (a string
must always end in a '\0' character. So you must restrict the
comparison to the first four bytes anyway, strcmp() will only stop
when it finds a '\0' in one of the strings and thus would compare
past the end of what's stored in 'st_ptr->jrbdsub_subcode'.

                                     Regards, Jens
--
      _  _____  _____

  _  | |  | |    | |
 | |_| |  | |    | |          http://www.physik.fu-berlin.de/~toerring
  \___/ens|_|homs|_|oerring



Mon, 10 Oct 2005 04:17:12 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

> typedef struct jrbdsub_type{
>   char jrbdsub_subcode[4];
>   char jrbdsub_filler[44];
>   int jrbdsub_suberrno;
> } jrbdsub;
> if (st_ptr->jrbdsub_subcode=='SUB ')
> When I compile the C program I receive:

> CBC3076 Character constant 'SUB ' has more than one character. No more
> than rightmost 4 characters are used.
> CBC3068 Operation between types "unsigned char*" and "int" is not
> allowed.

1. String literals in C are defined using full quote (") delimiters. To
define the string, use "SUB ".

2. You can't compare arrays with the == operator. For strings, use the
strcmp() function.

3. Get a good book on C and read it through before trying to write any
code.

Brian Rodenborn



Mon, 10 Oct 2005 04:04:04 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:


> > typedef struct jrbdsub_type{
> >   char jrbdsub_subcode[4];
> >   char jrbdsub_filler[44];
> >   int jrbdsub_suberrno;
> > } jrbdsub;

> > if (st_ptr->jrbdsub_subcode=='SUB ')

> > When I compile the C program I receive:

> > CBC3076 Character constant 'SUB ' has more than one character. No more
> > than rightmost 4 characters are used.
> > CBC3068 Operation between types "unsigned char*" and "int" is not
> > allowed.

> 1. String literals in C are defined using full quote (") delimiters. To
> define the string, use "SUB ".

> 2. You can't compare arrays with the == operator. For strings, use the
> strcmp() function.

    I suspect strcmp() won't work here.  `jrbdsub_subcode'
is a four-character array and is apparently expected to hold
the four characters 'S','U','B',' ' -- and that isn't a
"string" as defined by the C library because it lacks the
terminating '\0' byte.  strcmp() requires two properly-
formed strings, and trying to use it on a non-string array
invites disaster.

    To compare two arbitrary four-byte arrays (not necessarily
"strings"), use the memcmp() function:

        if (memcmp(st_ptr->jrbdsub_subcode, "SUB ", 4) == 0)
            ...

(The literal "SUB " actually creates a properly-terminated
string, a five-byte array containing 'S','U','B',' ','\0'.
But the final '\0' won't confuse memcmp(), because it's been
told to inspect only the first four characters of each array.)

--



Mon, 10 Oct 2005 05:06:52 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

> > 2. You can't compare arrays with the == operator. For strings, use the
> > strcmp() function.

>     I suspect strcmp() won't work here.  `jrbdsub_subcode'
> is a four-character array and is apparently expected to hold
> the four characters 'S','U','B',' ' -

Good pickup.

Quote:
>     To compare two arbitrary four-byte arrays (not necessarily
> "strings"), use the memcmp() function:

Or strncmp().

Brian Rodenborn



Mon, 10 Oct 2005 07:10:21 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:


> > > 2. You can't compare arrays with the == operator. For strings, use the
> > > strcmp() function.

> >     I suspect strcmp() won't work here.  `jrbdsub_subcode'
> > is a four-character array and is apparently expected to hold
> > the four characters 'S','U','B',' ' -

> Good pickup.

> >     To compare two arbitrary four-byte arrays (not necessarily
> > "strings"), use the memcmp() function:

> Or strncmp().

    strncmp() would work in this case, but is not the
right choice for general N-byte arrays which might
contain embedded zero bytes.  I'd suggest memcmp() even
for the O.P.'s case (where embedded zeroes seem not to
be an issue), simply because it's, well, simpler.

--



Mon, 10 Oct 2005 22:20:51 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:


... snip ...

> > > To compare two arbitrary four-byte arrays (not necessarily
> > > "strings"), use the memcmp() function:

> > Or strncmp().

>     strncmp() would work in this case, but is not the
> right choice for general N-byte arrays which might
> contain embedded zero bytes.  I'd suggest memcmp() even
> for the O.P.'s case (where embedded zeroes seem not to
> be an issue), simply because it's, well, simpler.

No, strncmp won't work.  It stops on the first '\0'.  N869:

7.21.4.4  The strncmp function

Synopsis

[#1]
        #include <string.h>
        int strncmp(const char *s1, const char *s2, size_t n);

Description

[#2]   The   strncmp  function  compares  not  more  than  n
characters (characters that follow a null character are  not <--
compared)  from  the  array  pointed  to  by s1 to the array
pointed to by s2.

Returns

[#3] The strncmp function returns an integer  greater  than,
equal  to,  or  less  than zero, accordingly as the possibly
null-terminated array pointed to  by  s1  is  greater  than,
equal  to,  or  less than the possibly null-terminated array
pointed to by s2.

--

   Available for consulting/temporary embedded and systems.
   <http://cbfalconer.home.att.net>  USE worldnet address!



Mon, 10 Oct 2005 23:13:41 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:



> > > typedef struct jrbdsub_type{
> > >   char jrbdsub_subcode[4];
> > >   char jrbdsub_filler[44];
> > >   int jrbdsub_suberrno;
> > > } jrbdsub;

> > > if (st_ptr->jrbdsub_subcode=='SUB ')

> > > When I compile the C program I receive:

> > > CBC3076 Character constant 'SUB ' has more than one character. No more
> > > than rightmost 4 characters are used.
> > > CBC3068 Operation between types "unsigned char*" and "int" is not
> > > allowed.

> > 1. String literals in C are defined using full quote (") delimiters. To
> > define the string, use "SUB ".

> > 2. You can't compare arrays with the == operator. For strings, use the
> > strcmp() function.

>     I suspect strcmp() won't work here.  `jrbdsub_subcode'
> is a four-character array and is apparently expected to hold
> the four characters 'S','U','B',' ' -- and that isn't a
> "string" as defined by the C library because it lacks the
> terminating '\0' byte.  strcmp() requires two properly-
> formed strings, and trying to use it on a non-string array
> invites disaster.

>     To compare two arbitrary four-byte arrays (not necessarily
> "strings"), use the memcmp() function:

>    if (memcmp(st_ptr->jrbdsub_subcode, "SUB ", 4) == 0)
>        ...

> (The literal "SUB " actually creates a properly-terminated
> string, a five-byte array containing 'S','U','B',' ','\0'.
> But the final '\0' won't confuse memcmp(), because it's been
> told to inspect only the first four characters of each array.)

Thanks to all who responded for your answers as well as your patience.


Mon, 10 Oct 2005 23:46:15 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

>     strncmp() would work in this case, but is not the
> right choice for general N-byte arrays which might
> contain embedded zero bytes.  I'd suggest memcmp() even
> for the O.P.'s case (where embedded zeroes seem not to
> be an issue), simply because it's, well, simpler.

That doesn't make any sense. He's comparing to a string literal, how
could embedded 0 characters come into play?

Brian Rodenborn



Tue, 11 Oct 2005 00:17:08 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

> No, strncmp won't work.  It stops on the first '\0'.  N869:

What's your point? He's comparing a character buffer to a string
literal. You WANT it to stop at the first '\0'.

Brian Rodenborn



Tue, 11 Oct 2005 00:18:14 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:


> >     strncmp() would work in this case, but is not the
> > right choice for general N-byte arrays which might
> > contain embedded zero bytes.  I'd suggest memcmp() even
> > for the O.P.'s case (where embedded zeroes seem not to
> > be an issue), simply because it's, well, simpler.

> That doesn't make any sense. He's comparing to a string literal, how
> could embedded 0 characters come into play?

    CBF also seemed to have trouble understanding what I
wrote, so on the "Everybody's out of step except Johnny"
principle I guess I must have mis-written.  Here are the
points I was trying to make:

    1)  The O.P.'s data is a four-character array, and he's
        trying to find out whether those four characters
        are 'S','U','B',' '.

    2)  The four-character array lacks a terminating '\0'
        and hence is not a string, so strcmp() is out.

    3)  If the array actually contains 'S','U','B',' '
        either memcmp() or strncmp() against the first
        four bytes of the five-byte string "SUB " will
        detect the match.

    4)  If the array actually contains something else,
        either memcmp() or strncmp() will detect the
        mismatch.

    5)  But (4) only holds because 'S','U','B',' ' has
        no embedded zero bytes.

    6)  In the more general case where the key value could
        contain embedded zeroes, memcmp() would always
        deliver the correct answer but strncmp() could be
        fooled.  For example, if the test value were
        'A',0,'B',1 (note the un-quoted digits) and the
        array held 'A',0,'X',42 strncmp() would report a
        match because it would inspect only the first
        two characters.

    7)  Since the O.P. is unfamiliar with C's world-view
        I didn't want him to get the notion that strncmp()
        was the preferred way to compare arbitrary chunks
        of memory.  strncmp() can handle non-strings, yes,
        but it still has string-ish behavior.

    8)  Therefore I recommended memcmp().

--



Tue, 11 Oct 2005 01:16:00 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:


>... snip ...

>> > > To compare two arbitrary four-byte arrays (not necessarily
>> > > "strings"), use the memcmp() function:

>> > Or strncmp().

>>     strncmp() would work in this case, but is not the
>> right choice for general N-byte arrays which might
>> contain embedded zero bytes.  I'd suggest memcmp() even
>> for the O.P.'s case (where embedded zeroes seem not to

                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Quote:
>> be an issue), simply because it's, well, simpler.
>  ^^^^^^^^^^^^
>No, strncmp won't work.  It stops on the first '\0'.  N869:

Have I ever told you to engage your brain before posting? ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Tue, 11 Oct 2005 01:19:55 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

>     7)  Since the O.P. is unfamiliar with C's world-view
>         I didn't want him to get the notion that strncmp()
>         was the preferred way to compare arbitrary chunks
>         of memory.  strncmp() can handle non-strings, yes,
>         but it still has string-ish behavior.

Horses for courses. I was addressing the given case, which did not have
two arbitrary buffers. Indeed, two character buffers, which may have
embedded '\0' characters, and for which you want to compare each byte,
cries out for memcmp(). However, that doesn't mean it's appropriate for
every case. Here, you have a character buffer compared to a string
literal (I've assumed that was the OP's intent anyway). Here we have a
very "string-ish" situation, as you put it above.

You can write the test as:

strncmp (buf, "the literal", sizeof buf);

This has certain value for the problem. You can't run off the end of
buf, because of sizeof, and you can't run off the end of the literal
since strncmp() will terminate when it hits the '\0' character.
Naturally though, it requires buf to be an actual array in that scope,
not a character pointer. As a struct member, that's not a problem IN
THIS CASE.

For the general problem of two character buffers that aren't necessarily
strings, the size of each buffer will have to be calculated first, as
there is no other way to do memcmp() safely. As in:

if (sizeof buf1 != sizeof buf2)
{
   /* obviously can't match report failure */

Quote:
}

else if (memcmp (buf1, buf2, sizeof buf1) != 0)
{
   /* report failure */

Quote:
}

else
{
   /* report success */

Quote:
}

However, I think my third point was the most important one, which is
that the OP needs to learn C and not hack around in it. It's just not a
good language for trying to slap some code together. It'll figure out a
way to getcha.

Brian Rodenborn



Tue, 11 Oct 2005 02:41:53 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:

> For the general problem of two character buffers that aren't necessarily
> strings, the size of each buffer will have to be calculated first, as
> there is no other way to do memcmp() safely. As in:

> if (sizeof buf1 != sizeof buf2)
> {
>    /* obviously can't match report failure */
> }

If you know at compile-time that the buffer sizes differ there's no
reason to wait until runtime to report the mismatch.

Jeremy.



Tue, 11 Oct 2005 04:05:18 GMT  
 pointer to a structure (simple question for a real C programmer)

Quote:


> > For the general problem of two character buffers that aren't necessarily
> > strings, the size of each buffer will have to be calculated first, as
> > there is no other way to do memcmp() safely. As in:

> > if (sizeof buf1 != sizeof buf2)
> > {
> >    /* obviously can't match report failure */
> > }

> If you know at compile-time that the buffer sizes differ there's no
> reason to wait until runtime to report the mismatch.

What did you have in mind, specifically?

Brian Rodenborn



Tue, 11 Oct 2005 05:02:38 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. a simple question (a structure of pointers)

2. The real serial.cs

3. A real simple question,Please help

4. A real simple question

5. REAL Simple Question

6. A real simple question

7. a real simple question

8. Non-CS major C programmers

9. real newbie pointer question

10. Maybe simple question for experienced programmer, help!!

11. simple question for experienced programmers

12. Simple Structure questions

 

 
Powered by phpBB® Forum Software