Alternative and probable better way to printf

Discussion in 'C Programming' started by Rudra Banerjee, May 3, 2013.

  1. Hello friends,
    I am writing some string to a gstring using printf as:

    g_string_append_printf (ustring, "@%s{%s,\n",string1, string0);
    if( strlen(string2)!=0 ||string2!=NULL)
    g_string_append_printf (ustring,"\tAuthor=\"%s\",\n", string2);
    if( strlen(string3)!=0 ||string3!=NULL)
    g_string_append_printf (ustring,"\tYear=\"%s\",\n", string3);
    if( strlen(string4)!=0 ||string4!=NULL)
    g_string_append_printf (ustring, "\tTitle=\"%s\",\n", string4);

    GLib's are probably not exactly important here. Consider it as

    printf ("\tAuthor=\"%s\",\n", string<i>)

    When this works rather fine, it seems not the best way(i have strings string<1> to string<30>) and I am looking for some better way.

    Some points to consider:
    Any string may be empty/NULL, as checked by every line before the printf.
    Any better way of implementing this?
     
    Rudra Banerjee, May 3, 2013
    #1
    1. Advertising

  2. Probably obvious, but the declaration for the string is
    char *string<i>
     
    Rudra Banerjee, May 3, 2013
    #2
    1. Advertising

  3. Rudra Banerjee

    Eric Sosman Guest

    On 5/3/2013 8:54 AM, Rudra Banerjee wrote:
    > Hello friends,
    > I am writing some string to a gstring using printf as:
    >
    > g_string_append_printf (ustring, "@%s{%s,\n",string1, string0);
    > if( strlen(string2)!=0 ||string2!=NULL)


    Aside: This test (and the others like it) should be

    if (string2 != NULL && strlen(string2) != 0)

    .... or (for fanatical cycle-shavers)

    if (string2 != NULL && *string2 != '\0')

    > g_string_append_printf (ustring,"\tAuthor=\"%s\",\n", string2);
    > if( strlen(string3)!=0 ||string3!=NULL)
    > g_string_append_printf (ustring,"\tYear=\"%s\",\n", string3);
    > if( strlen(string4)!=0 ||string4!=NULL)
    > g_string_append_printf (ustring, "\tTitle=\"%s\",\n", string4);
    >
    > GLib's are probably not exactly important here. Consider it as
    >
    > printf ("\tAuthor=\"%s\",\n", string<i>)
    >
    > When this works rather fine, it seems not the best way(i have strings string<1> to string<30>) and I am looking for some better way.
    >
    > Some points to consider:
    > Any string may be empty/NULL, as checked by every line before the printf.
    > Any better way of implementing this?


    C has a feature called the "array," which is quite helpful in
    situations like this. You could use one string[] array instead of
    string2,string3,...,string30 (they'd now be called string[0] through
    string[28]), and a similar keyword[] array

    static const char *keyword[29] = {
    "Author", "Year", "Title", ... };

    Then,

    g_string_append_printf (ustring, "@%s{%s,\n",string1, string0);
    for (int i = 0; i < 29; ++i) {
    if (string != NULL && string[0] != '\0') {
    g_string_append_printf(ustring, "\t%s=\"%s\",\n",
    keyword, string);
    }

    I've left string0 and string1 as special cases, partly because
    their formatting looks different from all the others and partly
    because their order is swapped, but with sufficient ingenuity
    you could subsume them in the loop, too.

    Aside: The quotes you're adding around the data fields may
    not be enough -- in particular, a data field that contains a
    quote is likely to mess things up. See, for example, Harlan
    Ellison's

    "Repent, Harlequin!" Said the Ticktockman

    --
    Eric Sosman
    d
     
    Eric Sosman, May 3, 2013
    #3
  4. On Friday, May 3, 2013 1:54:30 PM UTC+1, Rudra Banerjee wrote:
    > Hello friends,
    >
    > I am writing some string to a gstring using printf as:
    >
    >
    >
    > g_string_append_printf (ustring, "@%s{%s,\n",string1, string0);
    >
    > if( strlen(string2)!=0 ||string2!=NULL)
    >
    > g_string_append_printf (ustring,"\tAuthor=\"%s\",\n", string2);
    >
    > if( strlen(string3)!=0 ||string3!=NULL)
    >
    > g_string_append_printf (ustring,"\tYear=\"%s\",\n", string3);
    >
    > if( strlen(string4)!=0 ||string4!=NULL)
    >
    > g_string_append_printf (ustring, "\tTitle=\"%s\",\n", string4);
    >
    >
    >
    > GLib's are probably not exactly important here. Consider it as
    >
    >
    >
    > printf ("\tAuthor=\"%s\",\n", string<i>)
    >
    >
    >
    > When this works rather fine, it seems not the best way(i have strings
    > string<1> to string<30>) and I am looking for some better way.
    >
    >
    >
    > Some points to consider:
    > Any string may be empty/NULL, as checked by every line before the printf.
    > Any better way of implementing this?
    >

    Write a function on top of g_string_append_printf() which modifies it slightly
    so that it takes a name and a string value as parameters, and appends a Perl-
    parseable ? line in the form name = "value".
    Make sure you handle the empty string, the null string, and the string
    containing quote characters as the parser expects.
    Then the higher level code is just a list of calls to this function, as before,
    but with all the special cases and difficulty of adding the = sign stripped
    out.

    --
    Visit Malcolm's website, a great C programmers' resource.
    http://www.malcolmmclean.site11.com/www
     
    Malcolm McLean, May 3, 2013
    #4
  5. Rudra Banerjee <> writes:
    [...]
    > if( strlen(string2)!=0 ||string2!=NULL)

    [...]

    This test is incorrect. Calling strlen() on a null pointer has
    undefined behavior, so you want to do the NULL check first, and you want
    "&&", not "||":

    if (string2 != NULL && strlen(string2) != 0)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 3, 2013
    #5
  6. Rudra Banerjee

    Noob Guest

    Eric Sosman wrote:

    > Aside: This test (and the others like it) should be
    >
    > if (string2 != NULL && strlen(string2) != 0)
    >
    > ... or (for fanatical cycle-shavers)
    >
    > if (string2 != NULL && *string2 != '\0')


    And fanatical character-shavers may write

    if (string2 && *string2)

    Regards.
     
    Noob, May 3, 2013
    #6
  7. Rudra Banerjee

    Eric Sosman Guest

    On 5/3/2013 11:37 AM, Noob wrote:
    > Eric Sosman wrote:
    >
    >> Aside: This test (and the others like it) should be
    >>
    >> if (string2 != NULL && strlen(string2) != 0)
    >>
    >> ... or (for fanatical cycle-shavers)
    >>
    >> if (string2 != NULL && *string2 != '\0')

    >
    > And fanatical character-shavers may write
    >
    > if (string2 && *string2)


    What's with all that wasteful white space, huh? :)

    A true story concerning cycle-shaving: I once got a
    substantial speedup by making exactly the change shown above.
    The program in question frequently used strlen() as the O.P.
    does, in "Is this string empty?" queries where one doesn't
    really need to know the length, just whether it's zero. All
    was well on the machines where the program was developed and
    on a few others it was ported to ...

    .... and then we ported it to something called the MicroVAX II.
    This was a small DEC machine, cost-reduced by implementing the
    VAX architecture on just a few chips. Chips were smaller in
    those days (ca. 1985), and there wasn't room for all of the
    VAX' famously rich instruction set. So some instructions were
    omitted: The hardware trapped, and a trap handler decoded the
    offending instruction and emulated it in software.

    All (or most) of VAX' string-handling instructions were
    absent from MicroVAX, but the system shipped with the same C
    library that grown-up VAXen used. Anybody want to speculate
    on what VAX capabilities the <string.h> functions used, and on
    how well MicroVAX ran them?

    Ugh.

    --
    Eric Sosman
    d
     
    Eric Sosman, May 3, 2013
    #7
  8. Rudra Banerjee

    BartC Guest

    "Rudra Banerjee" <> wrote in message
    news:...
    > Hello friends,
    > I am writing some string to a gstring using printf as:
    >
    > g_string_append_printf (ustring, "@%s{%s,\n",string1, string0);
    > if( strlen(string2)!=0 ||string2!=NULL)
    > g_string_append_printf (ustring,"\tAuthor=\"%s\",\n", string2);
    > if( strlen(string3)!=0 ||string3!=NULL)
    > g_string_append_printf (ustring,"\tYear=\"%s\",\n", string3);
    > if( strlen(string4)!=0 ||string4!=NULL)
    > g_string_append_printf (ustring, "\tTitle=\"%s\",\n", string4);


    > printf ("\tAuthor=\"%s\",\n", string<i>)
    >
    > When this works rather fine, it seems not the best way(i have strings
    > string<1> to string<30>) and I am looking for some better way.


    Create two arrays: one with the labels ("Author", "Year", etc), another with
    pointers to the strings (or form string/2/3/etc into an array).

    Then a simple loop will call a function on each corresponding pair of
    strings, that will contain the print statement as well as any checks needed,
    eg:

    if (text)
    . ..print("\t%s=%s",label,text);



    --
    Bartc
     
    BartC, May 3, 2013
    #8
  9. Rudra Banerjee

    Siri Cruise Guest

    In article <kASgt.166828$7>, "BartC" <> wrote:

    > "Rudra Banerjee" <> wrote in message
    > news:...
    > > Hello friends,
    > > I am writing some string to a gstring using printf as:
    > >
    > > g_string_append_printf (ustring, "@%s{%s,\n",string1, string0);
    > > if( strlen(string2)!=0 ||string2!=NULL)
    > > g_string_append_printf (ustring,"\tAuthor=\"%s\",\n", string2);
    > > if( strlen(string3)!=0 ||string3!=NULL)
    > > g_string_append_printf (ustring,"\tYear=\"%s\",\n", string3);
    > > if( strlen(string4)!=0 ||string4!=NULL)
    > > g_string_append_printf (ustring, "\tTitle=\"%s\",\n", string4);

    >
    > > printf ("\tAuthor=\"%s\",\n", string<i>)
    > >
    > > When this works rather fine, it seems not the best way(i have strings
    > > string<1> to string<30>) and I am looking for some better way.

    >
    > Create two arrays: one with the labels ("Author", "Year", etc), another with
    > pointers to the strings (or form string/2/3/etc into an array).
    >
    > Then a simple loop will call a function on each corresponding pair of
    > strings, that will contain the print statement as well as any checks needed,
    > eg:
    >


    if (text && *text)

    > . ..print("\t%s=%s",label,text);

    --
    Mommy wants to take up a collection to send Daddy into space. Once he's
    there Mommy says she might take up another collection to bring him back.
    :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
     
    Siri Cruise, May 3, 2013
    #9
    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. neblackcat
    Replies:
    0
    Views:
    395
    neblackcat
    Jul 15, 2004
  2. Tim Golden
    Replies:
    2
    Views:
    694
    Mark Hammond
    Jul 19, 2004
  3. Pierre Quentel
    Replies:
    21
    Views:
    671
  4. Ronald Fischer
    Replies:
    0
    Views:
    120
    Ronald Fischer
    Jun 18, 2007
  5. Ruby Quiz

    [QUIZ] Probable Iterations (#141)

    Ruby Quiz, Sep 28, 2007, in forum: Ruby
    Replies:
    14
    Views:
    217
    Eugene Kalenkovich
    Oct 4, 2007
Loading...

Share This Page