Re: Please help optimize (and standarize) this code...

From: gtippery (gtippery_at_altavista.net)
Date: 02/24/05


Date: 23 Feb 2005 23:05:37 -0800

Thanks for replying.

>> #include <stdlib.h> /* for itoa */
>
> Sorry, but itoa() is an extension that you won't always find in
> <stdlib.h>.

Yeah, I had to dig a bit to even find it, in my compiler's library -
I guess it was "depreciated" even in 1993...

>> main()
>
...
> you better make that either
>
> int main( void )
> or
> int main( int argc, char *argv[ ] )
>

Yup. I did that deliberately to provoke someone to answer.
<grin> That's gotta be either #1 or #2 on the 'most frequent"
list...

>> /* Fill the array with (test) names & extensions,
>> left-justified & space-filled (no (char)0's).
>> In the real app (...'d code), there's findfirst(),
>> findnext(), sorting, etc.*/
>> memcpy(&NameArray[0], "One 1 ", 11);
>
>
> This obviously assumes that the members of the NameExt structure are
> packed, i.e. that the 'ext' member starts immediately after the
'name'
> member without any padding in between. While you probably often will
> get away with that it's not guaranteed to work since the compiler is
> free to insert as many padding bytes between (and after) the members
> as it likes. And if it does your scheme won't work anymore. So you
> better make that
>
> memcpy( &NameArray[0].name, "One ", NAMLEN );
> memcpy( &NameArray[0].ext, "1 ", EXTLEN );
>

A good point, and exactly the sort of thing I wanted to know.

>> // Construct format string like "%8s%c%3s"
>> strcpy(fmtstr, "%");
>> strcat(fmtstr, itoa(NAMLEN, digits, 10));

> itoa() isn't a standard C function, so this will fail on systems
> where there's no itoa().

Do you suggest sprintf(), or is there a standard, specific
integer-to-characters function? BTW, do you know if itoa()
[or something equivalent] is not standardized because character
sets aren't, or is there some other reason?

>> strcat(fmtstr, "s%c%");
>> strcat(fmtstr, itoa(EXTLEN, digits, 10));
>> strcat(fmtstr, "s");
>
>
> Why don't you use sprintf() to make up the format string?
>
> sprintf( fmtstr, "%%%ds%%c%%%ds" NAMLEN, EXTLEN );
>

Argh! Because it didn't occur to me. I _did_ consider using
sprintf() to format the entire output line, but not just the
format string.

>
>> // Print according to the specified format
>> for(i=0; i<NameCnt; i++) {
>> memcpy(NAM, NameArray[i].name, NAMLEN);
>> NAM[NAMLEN] = (char)0;
>
>
> "(char)0" is probably better written as "'\0'", at least then all
> C programmers with a bit of experience will know what you mean.
>

I _knew_ there was a simpler way than (char)0, but while my
compiler accepts charvar = 0x00 and charvar = \0, neither looked
"explicit" enought. I guess I'd forgotten you could use escaped
characters in '' constants like you can in "" constants.

>> Particularly, are there easier ways to:
>> (1) initialize the NameArray records;

[Your corrected version requoted here for reference:]

> memcpy( &NameArray[0].name, "One ", NAMLEN );
> memcpy( &NameArray[0].ext, "1 ", EXTLEN );

>
> Perhaps, but that will depend on what you want to initialize the
array
> elements with in the real case.

Well, for illustration purposes, is there a better way to do
what it _does_ do (setting an array-of-char field of a
structure to a text constant) than using memcpy()?

> Since I don't know what findfirst() and
> findnext() return (they aren't standard C functions)

They're MS-DOS functions; in my library they return a pointer to
a structure full of binary values for file size, dates, etc.

What's the standard-C way to get the contents of a directory? I
have a few C reference books, but they date from the 1980's.
(And I wasn't around them when I originally posted.)

>
>> (2) specify the format string, assuming I want to stick with
constants
>> for the field widths; and
>> (3) printf the NameArray array-of-char fields without explicitly
>> converting them to strings?
>
>
> You actually don't have to do that since you specify the length of
them,
> so even without the terminating '\0' characters it will work
correctly.
> You can safely do
>
> printf( fmtstr, NameArry[ 0 ].name, '.', NameArray[ 0 ].ext );
>
> when 'fmtstr' is e.g. "%8s%c%3s".

I attempted something like that - I originally wrote "%8c%c%3c",
but then realized that wouldn't do what I wanted, and

    printf("%c%c%c%c%c%c%c%c%c%c%c%c",
        NameArray[i].name[0],
        NameArray[i].name[1],
        ...
        NameArray[i].ext[2]);
was just "over the top". <grin> C doesn't have anything like
FORTRAN's "implicit DO" does it?

I wasn't sure "%8s" was safe, 'though I can't remember now why I
thought it might not be.

> BTW, an alternative would be to use
>
> printf( "%*s%c%*s", NAMLEN, NameArray[ 0 ].name, '.',
> EXTLEN, NameArray[ 0 ].ext );
> or
> printf( "%*s%c%*s", sizeof NameArray->name, NameArray[ 0 ].name,
'.',
> sizeof NameArray->ext, NameArray[ 0 ].ext );

Ah, "%*", _that's_ what I couldn't think of.

>> Also, is there a way to get e.g.,
>> sizeof NameExt.Ext
>> (which doesn't work) at compile-time?
>
>
> Yes, if you give sizeof the name of a real instance of the NameExt
> struct, i.e.
>
> sizeof NameArray[ 0 ].ext
> or
> sizeof NameArray->ext
>

OK, I need to have that explained a bit more. Why does
sizeof(int) work? It's not a "real instance". Is that the
sizeof paren/no paren thing?

Why does NameArray->ext work, without a specific array index?

And I'm definitely confused by NameArray.ext, *NameArray.ext [or
is that *(NameArray).ext?], and NameArray->ext. Could you kindly
explain the differences? I know an array reference is (almost?)
a pointer, but I don't know for structs.

Thanks.

--
{ Don't use the "altavista.net" reply-to; it's extinct, but I don't
know how to change it in Google Groups.  Use "comcast" instead of
"altavista" if you want to email me. }


Relevant Pages

  • Re: how to represent binary code , hex code in c++ and display them on screen using prinf statement
    ... Borland C/C++ has in its library a function called itoa. ... the exact signature of the function. ... But there is no such standard ... > expects an unsigned int, so you'll need to convert or use the right type ...
    (comp.lang.cpp)
  • Re: Converting int to string
    ... >> As an old C programmer, I find itoa (or even sprintf!) most ... >using itoa is much faster. ... The function itoais not standard C or C++ and you ... If you love good programming techniques, ...
    (microsoft.public.vc.stl)
  • Re: range for int
    ... You probably want to reverse the arguments after the format string, ... Int and long are often types of identical range ... The values given in K&R2 and the standard are the minimum. ... representation. ...
    (comp.lang.c)
  • Re: function conversion
    ... I read that i.e. itoa is not! ... You can see all the functions in the standard C library by reading the ... every programming aspect? ...
    (comp.lang.c)
  • Re: one c question
    ... Those are not standard C header files. ... > itoa(int value, char *string, int radix) ... Why go to all the trouble of writing and maintaining an itoa ... Erik de Castro Lopo nospam@xxxxxxxxxxxxx ...
    (comp.lang.c)