Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #101407 > unrolled thread

Correct way of doing string manipulation functions

Started by"Fernando D. Bozzo" <fdbozzo@gmail.com>
First post2017-01-10 15:43 -0800
Last post2017-01-13 18:02 -0800
Articles 20 on this page of 101 — 19 participants

Back to article view | Back to comp.lang.c


Contents

  Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-10 15:43 -0800
    Re: Correct way of doing string manipulation functions "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-10 19:36 -0500
      Re: Correct way of doing string manipulation functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-11 03:41 +0000
        Re: Correct way of doing string manipulation functions James Kuyper <jameskuyper@verizon.net> - 2017-01-11 07:19 -0500
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:36 -0800
    Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-10 16:41 -0800
      Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-10 16:54 -0800
        Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:38 -0800
          Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-11 18:24 -0800
      Re: Correct way of doing string manipulation functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-11 03:38 +0000
        Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-10 20:02 -0800
          Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-10 20:28 -0800
          Re: Correct way of doing string manipulation functions Ian Collins <ian-news@hotmail.com> - 2017-01-11 18:19 +1300
            Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-11 02:40 -0800
        Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-10 20:18 -0800
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:37 -0800
        Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-11 18:23 -0800
    Re: Correct way of doing string manipulation functions BartC <bc@freeuk.com> - 2017-01-11 01:12 +0000
      Re: Correct way of doing string manipulation functions BartC <bc@freeuk.com> - 2017-01-11 11:59 +0000
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:39 -0800
    Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-10 17:55 -0800
      Re: Correct way of doing string manipulation functions "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-01-10 18:21 -0800
      Re: Correct way of doing string manipulation functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-11 03:21 +0000
        Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-11 07:33 -0800
          Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-11 07:43 -0800
          Re: Correct way of doing string manipulation functions BartC <bc@freeuk.com> - 2017-01-11 15:50 +0000
            Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-11 08:07 -0800
              Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:46 -0800
                Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-12 03:04 -0800
                  Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-12 03:37 -0800
                    Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-12 05:47 -0800
                      Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-12 06:14 -0800
                        Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-12 06:34 -0800
                        Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-12 07:38 -0800
                          Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-12 07:59 -0800
              Re: Correct way of doing string manipulation functions Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-14 22:24 -0800
                Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-15 03:30 -0800
                  Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-15 03:52 -0800
                    Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-15 04:23 -0800
        Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:42 -0800
    Re: Correct way of doing string manipulation functions Keith Thompson <kst-u@mib.org> - 2017-01-10 19:19 -0800
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:40 -0800
    Re: Correct way of doing string manipulation functions Barry Schwarz <schwarzb@dqel.com> - 2017-01-10 20:31 -0800
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:45 -0800
    Re: Correct way of doing string manipulation functions Gareth Owen <gwowen@gmail.com> - 2017-01-11 17:20 +0000
      Re: Correct way of doing string manipulation functions "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-11 12:38 -0500
        Strings as first class citizens (Was: Correct way of doing string manipulation functions) gazelle@shell.xmission.com (Kenny McCormack) - 2017-01-11 17:53 +0000
          Re: Strings as first class citizens (Was: Correct way of doing string manipulation functions) Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-11 12:46 -0800
            Re: Strings as first class citizens (Was: Correct way of doing string manipulation functions) fir <profesor.fir@gmail.com> - 2017-01-11 14:40 -0800
            Re: Strings as first class citizens (Was: Correct way of doing string manipulation functions) Robert Wessel <robertwessel2@yahoo.com> - 2017-01-11 18:12 -0600
        Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-11 09:56 -0800
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 14:48 -0800
    Re: Correct way of doing string manipulation functions Thiago Adams <thiago.adams@gmail.com> - 2017-01-11 12:09 -0800
      Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 15:00 -0800
    Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-11 15:11 -0800
      Re: Correct way of doing string manipulation functions "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-11 19:03 -0500
        Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-12 02:46 -0800
      Re: Correct way of doing string manipulation functions Barry Schwarz <schwarzb@dqel.com> - 2017-01-12 00:08 -0800
        Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-12 03:02 -0800
          Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-12 11:38 +0000
            Re: Correct way of doing string manipulation functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-12 13:51 +0000
              Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-12 14:41 +0000
          Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-12 09:32 -0800
            Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-12 18:15 +0000
            Re: Correct way of doing string manipulation functions Keith Thompson <kst-u@mib.org> - 2017-01-12 11:46 -0800
              Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-12 13:52 -0800
            Re: Correct way of doing string manipulation functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-12 16:50 -0800
              Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-13 00:59 +0000
                Re: Correct way of doing string manipulation functions raltbos@xs4all.nl (Richard Bos) - 2017-01-13 08:59 +0000
                  Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-13 13:07 +0000
                  Re: Correct way of doing string manipulation functions Keith Thompson <kst-u@mib.org> - 2017-01-13 10:11 -0800
                    Re: Correct way of doing string manipulation functions BartC <bc@freeuk.com> - 2017-01-13 18:49 +0000
                Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 08:43 -0800
                Re: Correct way of doing string manipulation functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-13 09:45 -0800
                  Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-13 18:17 +0000
                    Re: Correct way of doing string manipulation functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-13 10:30 -0800
                      Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-13 18:48 +0000
                        Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 11:02 -0800
                          Re: Correct way of doing string manipulation functions Richard Heathfield <rjh@cpax.org.uk> - 2017-01-13 19:15 +0000
                            Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 12:18 -0800
                      Re: Correct way of doing string manipulation functions Keith Thompson <kst-u@mib.org> - 2017-01-13 12:14 -0800
                        Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 12:49 -0800
                          Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 13:19 -0800
                    Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 10:46 -0800
                      Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 11:55 -0800
                  Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 10:41 -0800
                    Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 10:51 -0800
                    Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 12:28 -0800
                      Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 13:07 -0800
                        Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 13:29 -0800
                          Re: Correct way of doing string manipulation functions BartC <bc@freeuk.com> - 2017-01-13 21:45 +0000
                            Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 13:59 -0800
                              Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 15:08 -0800
                            Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-13 14:13 -0800
                          Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 13:47 -0800
              Re: Correct way of doing string manipulation functions fir <profesor.fir@gmail.com> - 2017-01-13 08:02 -0800
        Re: Correct way of doing string manipulation functions supercat@casperkitty.com - 2017-01-12 07:50 -0800
        Re: Correct way of doing string manipulation functions Keith Thompson <kst-u@mib.org> - 2017-01-12 08:37 -0800
          Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-12 09:41 -0800
      Re: Correct way of doing string manipulation functions Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-13 17:39 -0800
        Re: Correct way of doing string manipulation functions "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-13 18:02 -0800

Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →


#101420

FromKeith Thompson <kst-u@mib.org>
Date2017-01-10 19:19 -0800
Message-ID<lnr34ap9li.fsf@kst-u.example.com>
In reply to#101407
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> "Fernando D. Bozzo" <fdbozzo@gmail.com> writes:
[...]
>>    char *text_out = malloc(sizeof(text_in));
>
>   malloc might return 0.

To be clear in case the OP isn't aware, if malloc() fails it returns a
null pointer.  A null pointer constant can be represented in source
either as 0 or as NULL.

>   And sizeof(text_in) is a compile-time constant.
>   This might not be what you had in mind.

More to the point, text_in is a pointer, so sizeof(text_in) almost
certainly isn't what you want.

[...]
-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <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"

[toc] | [prev] | [next] | [standalone]


#101480

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-11 14:40 -0800
Message-ID<b646f7d7-68d6-4934-980e-a34a9faf26c1@googlegroups.com>
In reply to#101420
Hi Keith:

I'm aware of the null termination for strings and the return value for malloc(), problem was that there are too many concepts and details that I did never have to think about because the language taked care of them.

With more practice I expect to remember all of this (I hope:)



El miércoles, 11 de enero de 2017, 4:18:14 (UTC+1), Keith Thompson  escribió:
> ram@zedat.fu-berlin.de (Stefan Ram) writes:
> > "Fernando D. Bozzo" <fdbozzo@gmail.com> writes:
> [...]
> >>    char *text_out = malloc(sizeof(text_in));
> >
> >   malloc might return 0.
> 
> To be clear in case the OP isn't aware, if malloc() fails it returns a
> null pointer.  A null pointer constant can be represented in source
> either as 0 or as NULL.
> 
> >   And sizeof(text_in) is a compile-time constant.
> >   This might not be what you had in mind.
> 
> More to the point, text_in is a pointer, so sizeof(text_in) almost
> certainly isn't what you want.
> 
> [...]
> -- 
> Keith Thompson (The_Other_Keith) kst-u@mib.org  <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"

[toc] | [prev] | [next] | [standalone]


#101428

FromBarry Schwarz <schwarzb@dqel.com>
Date2017-01-10 20:31 -0800
Message-ID<secb7cd7icvi4g8qplot9k144bg46pe0lq@4ax.com>
In reply to#101407
On Tue, 10 Jan 2017 15:43:36 -0800 (PST), "Fernando D. Bozzo"
<fdbozzo@gmail.com> wrote:

>Hi all,
>
>I'm starting at C but have a background on programmming in OOP.
>
>My question is about string manipulation functions and the correct/best/good way of doing this in C.
>
>I've made a function that returns just the filename of a given full path or url, which I use this way:
>
>
>// Suppose argv[1] is "http://www.myserver.com/file.html"
>char *text_out = justfname(argv[1]);
>printf("justfname = [%s]\n", text_out);
>free(text_out);
>
>
>
>/**
> * Returns the filename without path
> * 
> * Examples:
> *      justfname("c:\aaa\bbb\ccc\ddd.txt")             =>  "ddd.txt"
> *      justfname("http://www.myserver.com/file.html")  =>  "file.html"
> */
>char *justfname(char *text_in)
>{
>    int len = strlen(text_in);
>    char *fname = NULL;
>    char *text_out = malloc(sizeof(text_in));

Why bother to copy the file name to a new area.  You could return a
pointer to the spot in text_in where the file name starts.

>    fname = strrchr(text_in, '/');
>    if (fname == NULL)
>    {
>        fname = strrchr(text_in, '\\');
>        if (fname == NULL)
>        {
>            fname = text_in;
>        }
>        else
>        {
>            fname++; // Advance address +1 (skip "\" char)
>        }
>    }
>    else
>    {
>        fname++; // Advance address +1 (skip "/" char)
>    }
>
>    // Copy obtained data
>    strncpy(text_out, fname, len);
>
>    return text_out;

Delete the call to strncpy and return fname.

>}
>
>
>
>So my questions are:
>1) Is this implementation ok/correct, or is there a better way of doing it?

Others have pointed out that len contains the wrong value, your
allocated area is too small if the entire input string is the file
name, and the returned pointer value does not point to a string.

>2) Is usually the caller who is responsible for freeing the used pointers on the called functions?

If your function returns the address of allocated memory, then the
caller is responsible for freeing the allocation.

>3) When using pointers, are they normally created with malloc (heap) in habitual programming, or automatic var pointers (stack) are habitual too?

malloc does not create a pointer.  

Avoiding the issue of whether there is an actual heap or stack,
dynamic allocations are often referred as allocations from the heap
and defined objects are often said to exist on the stack.  If you take
the address of a defined object, the address will point to the stack.
If you allocate memory, the address will point to the heap.  For
defined objects, there is no difference between an auto var or a
static var (or any other type of object).  The address always points
to the object in question.  

Which object you choose to point to depends on what you are trying to
accomplish.  In many cases, it is unnecessary for the function to know
if the pointed to object is on the heap or the stack.  Consider your
function.  You could have copied the string pointed to by argv[1] to a
static array, an automatic array, or an allocated block of memory.
Given the four possible "types" the function could be called with, not
one line of code has to change.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#101482

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-11 14:45 -0800
Message-ID<773e925d-2364-485f-a264-c41e8b6177b9@googlegroups.com>
In reply to#101428
Hi Barry:


El miércoles, 11 de enero de 2017, 5:31:51 (UTC+1), Barry Schwarz  escribió:
> On Tue, 10 Jan 2017 15:43:36 -0800 (PST), "Fernando D. Bozzo"
> <fdbozzo-at-gmail.com> wrote:
> 
> >Hi all,
> >
> >I'm starting at C but have a background on programmming in OOP.
> >
> >My question is about string manipulation functions and the correct/best/good way of doing this in C.
> >
> >I've made a function that returns just the filename of a given full path or url, which I use this way:
> >
> >
> >// Suppose argv[1] is "http://www.myserver.com/file.html"
> >char *text_out = justfname(argv[1]);
> >printf("justfname = [%s]\n", text_out);
> >free(text_out);
> >
> >
> >
> >/**
> > * Returns the filename without path
> > * 
> > * Examples:
> > *      justfname("c:\aaa\bbb\ccc\ddd.txt")             =>  "ddd.txt"
> > *      justfname("http://www.myserver.com/file.html")  =>  "file.html"
> > */
> >char *justfname(char *text_in)
> >{
> >    int len = strlen(text_in);
> >    char *fname = NULL;
> >    char *text_out = malloc(sizeof(text_in));
> 
> Why bother to copy the file name to a new area.  You could return a
> pointer to the spot in text_in where the file name starts.

It's a good point.


> 
> >    fname = strrchr(text_in, '/');
> >    if (fname == NULL)
> >    {
> >        fname = strrchr(text_in, '\\');
> >        if (fname == NULL)
> >        {
> >            fname = text_in;
> >        }
> >        else
> >        {
> >            fname++; // Advance address +1 (skip "\" char)
> >        }
> >    }
> >    else
> >    {
> >        fname++; // Advance address +1 (skip "/" char)
> >    }
> >
> >    // Copy obtained data
> >    strncpy(text_out, fname, len);
> >
> >    return text_out;
> 
> Delete the call to strncpy and return fname.
> 
> >}
> >
> >
> >
> >So my questions are:
> >1) Is this implementation ok/correct, or is there a better way of doing it?
> 
> Others have pointed out that len contains the wrong value, your
> allocated area is too small if the entire input string is the file
> name, and the returned pointer value does not point to a string.
> 
> >2) Is usually the caller who is responsible for freeing the used pointers on the called functions?
> 
> If your function returns the address of allocated memory, then the
> caller is responsible for freeing the allocation.
> 
> >3) When using pointers, are they normally created with malloc (heap) in habitual programming, or automatic var pointers (stack) are habitual too?
> 
> malloc does not create a pointer.  
> 
> Avoiding the issue of whether there is an actual heap or stack,
> dynamic allocations are often referred as allocations from the heap
> and defined objects are often said to exist on the stack.  If you take
> the address of a defined object, the address will point to the stack.
> If you allocate memory, the address will point to the heap.  For
> defined objects, there is no difference between an auto var or a
> static var (or any other type of object).  The address always points
> to the object in question.  
> 
> Which object you choose to point to depends on what you are trying to
> accomplish.  In many cases, it is unnecessary for the function to know
> if the pointed to object is on the heap or the stack.  Consider your
> function.  You could have copied the string pointed to by argv[1] to a
> static array, an automatic array, or an allocated block of memory.
> Given the four possible "types" the function could be called with, not
> one line of code has to change.
> 
> -- 

Thanks for clarifying this.

[toc] | [prev] | [next] | [standalone]


#101442

FromGareth Owen <gwowen@gmail.com>
Date2017-01-11 17:20 +0000
Message-ID<871sw9343p.fsf@gmail.com>
In reply to#101407
"Fernando D. Bozzo" <fdbozzo@gmail.com> writes:

> Hi all,
>
> I'm starting at C but have a background on programmming in OOP.
>
> My question is about string manipulation functions and the
> correct/best/good way of doing this in C.

Seeing as the technical shortcomings have been addressed I'd just say
one extra thing - don't do this in C.  String handling is possibly the
most error prone part of the language.  Even experts have fierce
disagreements about the merits of strcpy(), strncpy(), strncpy_s() and
the various other ones. 

The reason for this is that they are all varying degrees of terrible to
work with. Manual memory management and null-termination are finicky,
and even experienced C-programmer screw up this from time to time.
And that's before you even consider the possibility of how Unicode
code-points in filenames show up.

If these routines are not 100% speed critical (and even if they are), if
you have any possibility of writing these particular routines in a
language where strings are first class citizens and then copying the
bytes into a buffer of char[] for use in C, then I strongly recommend
you do so.

[toc] | [prev] | [next] | [standalone]


#101443

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-11 12:38 -0500
Message-ID<b74d3964-5d31-15c4-847f-507a83d9334e@verizon.net>
In reply to#101442
On 01/11/2017 12:20 PM, Gareth Owen wrote:
...
> If these routines are not 100% speed critical (and even if they are), if
> you have any possibility of writing these particular routines in a
> language where strings are first class citizens and then copying the
> bytes into a buffer of char[] for use in C, then I strongly recommend
> you do so.

If string-handling speed is important, and C code isn't fast enough, 
pretty much your only alternative is assembler. Languages where strings 
are first class citizens make it much easier to work with strings, but 
they aren't generally faster than C. In many cases, treating strings as 
first class citizens imposes overhead that makes them slower than C.

[toc] | [prev] | [next] | [standalone]


#101444 — Strings as first class citizens (Was: Correct way of doing string manipulation functions)

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2017-01-11 17:53 +0000
SubjectStrings as first class citizens (Was: Correct way of doing string manipulation functions)
Message-ID<o55re4$gpt$1@news.xmission.com>
In reply to#101443
In article <b74d3964-5d31-15c4-847f-507a83d9334e@verizon.net>,
James R. Kuyper <jameskuyper@verizon.net> wrote:
>On 01/11/2017 12:20 PM, Gareth Owen wrote:
>...
>> If these routines are not 100% speed critical (and even if they are), if
>> you have any possibility of writing these particular routines in a
>> language where strings are first class citizens and then copying the
>> bytes into a buffer of char[] for use in C, then I strongly recommend
>> you do so.
>
>If string-handling speed is important, and C code isn't fast enough, 
>pretty much your only alternative is assembler. Languages where strings 
>are first class citizens make it much easier to work with strings, but 
>they aren't generally faster than C. In many cases, treating strings as 
>first class citizens imposes overhead that makes them slower than C.

Your point being?

-- 
The randomly chosen signature file that would have appeared here is more than 4
lines long.  As such, it violates one or more Usenet RFCs.  In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
	http://user.xmission.com/~gazelle/Sigs/FreeCollege

[toc] | [prev] | [next] | [standalone]


#101459 — Re: Strings as first class citizens (Was: Correct way of doing string manipulation functions)

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2017-01-11 12:46 -0800
SubjectRe: Strings as first class citizens (Was: Correct way of doing string manipulation functions)
Message-ID<f3c18a4f-9192-4d68-974f-d252207a6f2f@googlegroups.com>
In reply to#101444
On Wednesday, January 11, 2017 at 5:53:16 PM UTC, Kenny McCormack wrote:
> In article <b74d3964-5d31-15c4-847f-507a83d9334e@verizon.net>,
>
> >If string-handling speed is important, and C code isn't fast enough, 
> >pretty much your only alternative is assembler. Languages where strings 
> >are first class citizens make it much easier to work with strings, but 
> >they aren't generally faster than C. In many cases, treating strings as 
> >first class citizens imposes overhead that makes them slower than C.
> 
> Your point being?
> 
MiniBasic has two sorts of variables, numbers and strings. String variables
take the character $ as a suffix. The interpreter is written in and
built on top of the C string library. The  result is that operations 
are very slow. For example, to build a string dynamically, you need to
create a string of one character (entailing a call to malloc) then
add it to your growing buffer, entailing a call to realloc().

However MiniBasic has been praised for its string handling functions.
For many uses, like embedded hobby programming, runtime efficiency
just isn't much of a  consideration.

[toc] | [prev] | [next] | [standalone]


#101479 — Re: Strings as first class citizens (Was: Correct way of doing string manipulation functions)

Fromfir <profesor.fir@gmail.com>
Date2017-01-11 14:40 -0800
SubjectRe: Strings as first class citizens (Was: Correct way of doing string manipulation functions)
Message-ID<200dc062-1d4d-4920-bdb2-1104e0d7db6e@googlegroups.com>
In reply to#101459
W dniu środa, 11 stycznia 2017 21:46:14 UTC+1 użytkownik Malcolm McLean napisał:
> On Wednesday, January 11, 2017 at 5:53:16 PM UTC, Kenny McCormack wrote:
> > In article <b74d3964-5d31-15c4-847f-507a83d9334e@verizon.net>,
> >
> > >If string-handling speed is important, and C code isn't fast enough, 
> > >pretty much your only alternative is assembler. Languages where strings 
> > >are first class citizens make it much easier to work with strings, but 
> > >they aren't generally faster than C. In many cases, treating strings as 
> > >first class citizens imposes overhead that makes them slower than C.
> > 
> > Your point being?
> > 
> MiniBasic has two sorts of variables, numbers and strings. String variables
> take the character $ as a suffix. The interpreter is written in and
> built on top of the C string library. The  result is that operations 
> are very slow. For example, to build a string dynamically, you need to
> create a string of one character (entailing a call to malloc) then
> add it to your growing buffer, entailing a call to realloc().
> 
> However MiniBasic has been praised for its string handling functions.
> For many uses, like embedded hobby programming, runtime efficiency
> just isn't much of a  consideration.

even if purring efficiency matters on side and 
invent any synta one would wish for text processing
it still seems to be a bit boring and ugly 

im searchin for coolness in coding, text processing 
doesnt seem cool (maybe that means that text processing is not true? as true matters usually seem to be cool, maybe)

fr example pixel processing seem far more cool, artificial worlds also more cool, some parts of c also cool, optimistation matters also cool 

as to coolnes btw it is sad to not that some part of 
coding is real present coolnes, but some is imaginary
coolnes which may be not present in real..

coolnes also mixes with anticoolnes

[toc] | [prev] | [next] | [standalone]


#101491 — Re: Strings as first class citizens (Was: Correct way of doing string manipulation functions)

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-01-11 18:12 -0600
SubjectRe: Strings as first class citizens (Was: Correct way of doing string manipulation functions)
Message-ID<dcid7chnsj368ukm5r5lfn0pm0gf5qmh0s@4ax.com>
In reply to#101459
On Wed, 11 Jan 2017 12:46:08 -0800 (PST), Malcolm McLean
<malcolm.mclean5@btinternet.com> wrote:

>On Wednesday, January 11, 2017 at 5:53:16 PM UTC, Kenny McCormack wrote:
>> In article <b74d3964-5d31-15c4-847f-507a83d9334e@verizon.net>,
>>
>> >If string-handling speed is important, and C code isn't fast enough, 
>> >pretty much your only alternative is assembler. Languages where strings 
>> >are first class citizens make it much easier to work with strings, but 
>> >they aren't generally faster than C. In many cases, treating strings as 
>> >first class citizens imposes overhead that makes them slower than C.
>> 
>> Your point being?
>> 
>MiniBasic has two sorts of variables, numbers and strings. String variables
>take the character $ as a suffix. The interpreter is written in and
>built on top of the C string library. The  result is that operations 
>are very slow. For example, to build a string dynamically, you need to
>create a string of one character (entailing a call to malloc) then
>add it to your growing buffer, entailing a call to realloc().
>
>However MiniBasic has been praised for its string handling functions.
>For many uses, like embedded hobby programming, runtime efficiency
>just isn't much of a  consideration.


Surely poor memory management is an implementation issue, is it not?

[toc] | [prev] | [next] | [standalone]


#101445

Fromsupercat@casperkitty.com
Date2017-01-11 09:56 -0800
Message-ID<31b0c957-5206-483e-901a-ffef229f4e0c@googlegroups.com>
In reply to#101443
On Wednesday, January 11, 2017 at 11:38:36 AM UTC-6, James R. Kuyper wrote:
> If string-handling speed is important, and C code isn't fast enough, 
> pretty much your only alternative is assembler. Languages where strings 
> are first class citizens make it much easier to work with strings, but 
> they aren't generally faster than C. In many cases, treating strings as 
> first class citizens imposes overhead that makes them slower than C.

C can be faster if code abides by certain usage patterns, but making strings
be first-class citizens makes it possible for languages to optimize things
in ways which would not be possible in C.

Suppose, for example, that one wants to have an array of strings, many of
which will have come from the same source and will be identical.  In a
garbage-collected framework like Java or .NET, array slots which hold the
same string would simply hold references to the same object.  Nothing needs
to keep track of how many references exist to a string, or when the last
existing reference to a string gets destroyed.

While it would be possible to implement a sort of GC framework in C, it
would need to use its own heap which was essentially separate from the one
used by malloc/calloc and code to work with it would be a lot clunkier than
code to work with strings in GC languages.  Further, some of that clunkiness
would extend to the machine-code level.  For example, if a string is copied
to a global variable, a program using a C-based GC system would need to
execute some code to tell the GC about it.  By contrast, a GC-based framework
would receive from the compiler a list of all global variables that may hold
object references, so nothing special would need to be done at runtime.

[toc] | [prev] | [next] | [standalone]


#101484

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-11 14:48 -0800
Message-ID<62483699-0281-4d6e-b0a9-d6eaea0dae8e@googlegroups.com>
In reply to#101442
Hi Gareth:


El miércoles, 11 de enero de 2017, 18:21:12 (UTC+1), gwowen  escribió:
> "Fernando D. Bozzo" writes:
> 
> > Hi all,
> >
> > I'm starting at C but have a background on programmming in OOP.
> >
> > My question is about string manipulation functions and the
> > correct/best/good way of doing this in C.
> 
> Seeing as the technical shortcomings have been addressed I'd just say
> one extra thing - don't do this in C.  String handling is possibly the
> most error prone part of the language.  Even experts have fierce
> disagreements about the merits of strcpy(), strncpy(), strncpy_s() and
> the various other ones. 
> 
> The reason for this is that they are all varying degrees of terrible to
> work with. Manual memory management and null-termination are finicky,
> and even experienced C-programmer screw up this from time to time.
> And that's before you even consider the possibility of how Unicode
> code-points in filenames show up.

I did see the discrepancies you mention looking at various code examples on the net.


> 
> If these routines are not 100% speed critical (and even if they are), if
> you have any possibility of writing these particular routines in a
> language where strings are first class citizens and then copying the
> bytes into a buffer of char[] for use in C, then I strongly recommend
> you do so.

The reason for which I need to do this in C is because I'm doing a Mooc excercise, and they did give us a copy of the apache 2.2 core (apache.c file) with 4 methods without code that wehave to implement.

One of them is a method that receives a line (the GET petition with the URL and some more details) and need to parse it, so I first tought of making some methods for manipulating parts of the string.

Some methods I see that expect a malloc'ed pointer, but others are predefined arrays, so even in this program I don't see a unique way of dealing with strings.

Thanks!

[toc] | [prev] | [next] | [standalone]


#101450

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-11 12:09 -0800
Message-ID<1c29eee4-d302-41b3-9703-0f9a546ed193@googlegroups.com>
In reply to#101407
On Tuesday, January 10, 2017 at 9:43:53 PM UTC-2, Fernando D. Bozzo wrote:
> Hi all,
> 
> I'm starting at C but have a background on programmming in OOP.
> 
> My question is about string manipulation functions and the correct/best/good way of doing this in C.


I have a string class that I use for holding a C string.
This is a high level object in C. I have another one for
building strings.

Sample:

void Get(String* s)
{
   String_Set(s, "out");
}

int main()
{
 String s = STRING_INIT;

 Get(&s);
 printf("%s", s);
 
 String_Destroy(&s);
 
 return 0;
}

When used in structs

typedef struct
{
  String Name; //String == "I am the owner"
} Person;
#define PERSON_INIT {STRING_INIT}

void Person_Destroy(Person* p) 
{
  String_Destroy(&p->Name);
}

int main()
{
  Person person = PERSON_INIT;
  String_Set(&person.Name, "name");
  Person_Destroy(&person);
  return 0;
}

I don't use String for 'in' arguments.

//bad because in this case s is not the owner
void F1(String s) { } 

void F2(const char* s) { } //I use this

String_Set make a copy from source.
If you want to move a string you can use.

int main()
{
  String s = STRING_INIT;
  Get(&s);	
  Person person = PERSON_INIT;
  String_Swap(&person.Name, &s);	
  Person_Destroy(&person);
  String_Destroy(&s);
  return 0;
}

I use the semantics of these samples in other types.
_Swap and _Set are replacements for the usage of operator =.
_Init is a initialization function. 
_Destroy is the endpoint for the lifetime of the object.

The types I create are composable  as showed in the 
Person struct.

I have two more function that are
_Create used to create the object on the heap
and _Delete for the end-point lifetime for owner-pointers
of this object.

In my original design the String was NULL on init and NULL
was a valid state for 'empty'.
But because it's not safe to use NULL in many functions like 
strlen I am testing this new design where it cannot point 
to NULL.
I would appreciate comments about this design.
I also think if we had some function in the compiler to tell if the string
is literal this could be used for optimizations.

The result for String_Init and String_Set also are a new 
design not using error codes.

==header==

#pragma once

typedef char * String;
extern const char * const String_Empty_Constant;
#define STRING_INIT ((char*)String_Empty_Constant)

int    String_Init(String* pString, const char* source);
void   String_Destroy(String* pString);
void   String_Swap(String* pA, String* pB);
int    String_Set(String *pS1, const char* psz1);

==source==


const char * const String_Empty_Constant = "";

int String_Init(String* pString, const char* sourceOpt)
{
	int length = -1;
	if (sourceOpt == NULL ||
		sourceOpt[0] == '\0')
	{
		*pString = (char*)String_Empty_Constant;
		length = 0;
	}
	else
	{
		size_t sourceLen = strlen(sourceOpt);
		void * pNew = malloc(sizeof(char) * sourceLen + 1);
		if (pNew != 0)
		{
			memcpy(pNew, sourceOpt, sourceLen + 1);
			*pString = (char*)pNew;
			length = (int)sourceLen;
		}		
	}

	return length;
}

void String_Destroy(String* pString)
{
	if (pString != NULL)
	{
		if (*pString != String_Empty_Constant)
		{
			free(*pString);
		}
		//*pString = NULL; //some invalid value in debug
	}
}

void String_Swap(String* pA, String* pB)
{
	String tmp = *pA;
	*pA = *pB;
	*pB = tmp;
}

int String_Set(String *pS1, const char* psz1)
{	
	String local;
	int i = String_Init(&local, psz1);
	if (i >= 0)
	{
		String_Swap(&local, pS1);
		String_Destroy(&local);
	}	
	return i;
}

[toc] | [prev] | [next] | [standalone]


#101485

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-11 15:00 -0800
Message-ID<ad94ab17-d432-4d7f-84f8-65ef5a03724e@googlegroups.com>
In reply to#101450
Hi Thiago:

Thanks for this implementation example. I need to read it more carefuly because it is not immediately clear for me how it works, but I see that for the most part you encapsulate some common functionallity to simplify some coding.




El miércoles, 11 de enero de 2017, 21:09:51 (UTC+1), Thiago Adams  escribió:
> On Tuesday, January 10, 2017 at 9:43:53 PM UTC-2, Fernando D. Bozzo wrote:
> > Hi all,
> > 
> > I'm starting at C but have a background on programmming in OOP.
> > 
> > My question is about string manipulation functions and the correct/best/good way of doing this in C.
> 
> 
> I have a string class that I use for holding a C string.
> This is a high level object in C. I have another one for
> building strings.
> 
> Sample:
> 
> void Get(String* s)
> {
>    String_Set(s, "out");
> }
> 
> int main()
> {
>  String s = STRING_INIT;
> 
>  Get(&s);
>  printf("%s", s);
>  
>  String_Destroy(&s);
>  
>  return 0;
> }
> 
> When used in structs
> 
> typedef struct
> {
>   String Name; //String == "I am the owner"
> } Person;
> #define PERSON_INIT {STRING_INIT}
> 
> void Person_Destroy(Person* p) 
> {
>   String_Destroy(&p->Name);
> }
> 
> int main()
> {
>   Person person = PERSON_INIT;
>   String_Set(&person.Name, "name");
>   Person_Destroy(&person);
>   return 0;
> }
> 
> I don't use String for 'in' arguments.
> 
> //bad because in this case s is not the owner
> void F1(String s) { } 
> 
> void F2(const char* s) { } //I use this
> 
> String_Set make a copy from source.
> If you want to move a string you can use.
> 
> int main()
> {
>   String s = STRING_INIT;
>   Get(&s);	
>   Person person = PERSON_INIT;
>   String_Swap(&person.Name, &s);	
>   Person_Destroy(&person);
>   String_Destroy(&s);
>   return 0;
> }
> 
> I use the semantics of these samples in other types.
> _Swap and _Set are replacements for the usage of operator =.
> _Init is a initialization function. 
> _Destroy is the endpoint for the lifetime of the object.
> 
> The types I create are composable  as showed in the 
> Person struct.
> 
> I have two more function that are
> _Create used to create the object on the heap
> and _Delete for the end-point lifetime for owner-pointers
> of this object.
> 
> In my original design the String was NULL on init and NULL
> was a valid state for 'empty'.
> But because it's not safe to use NULL in many functions like 
> strlen I am testing this new design where it cannot point 
> to NULL.
> I would appreciate comments about this design.
> I also think if we had some function in the compiler to tell if the string
> is literal this could be used for optimizations.
> 
> The result for String_Init and String_Set also are a new 
> design not using error codes.
> 
> ==header==
> 
> #pragma once
> 
> typedef char * String;
> extern const char * const String_Empty_Constant;
> #define STRING_INIT ((char*)String_Empty_Constant)
> 
> int    String_Init(String* pString, const char* source);
> void   String_Destroy(String* pString);
> void   String_Swap(String* pA, String* pB);
> int    String_Set(String *pS1, const char* psz1);
> 
> ==source==
> 
> 
> const char * const String_Empty_Constant = "";
> 
> int String_Init(String* pString, const char* sourceOpt)
> {
> 	int length = -1;
> 	if (sourceOpt == NULL ||
> 		sourceOpt[0] == '\0')
> 	{
> 		*pString = (char*)String_Empty_Constant;
> 		length = 0;
> 	}
> 	else
> 	{
> 		size_t sourceLen = strlen(sourceOpt);
> 		void * pNew = malloc(sizeof(char) * sourceLen + 1);
> 		if (pNew != 0)
> 		{
> 			memcpy(pNew, sourceOpt, sourceLen + 1);
> 			*pString = (char*)pNew;
> 			length = (int)sourceLen;
> 		}		
> 	}
> 
> 	return length;
> }
> 
> void String_Destroy(String* pString)
> {
> 	if (pString != NULL)
> 	{
> 		if (*pString != String_Empty_Constant)
> 		{
> 			free(*pString);
> 		}
> 		//*pString = NULL; //some invalid value in debug
> 	}
> }
> 
> void String_Swap(String* pA, String* pB)
> {
> 	String tmp = *pA;
> 	*pA = *pB;
> 	*pB = tmp;
> }
> 
> int String_Set(String *pS1, const char* psz1)
> {	
> 	String local;
> 	int i = String_Init(&local, psz1);
> 	if (i >= 0)
> 	{
> 		String_Swap(&local, pS1);
> 		String_Destroy(&local);
> 	}	
> 	return i;
> }

[toc] | [prev] | [next] | [standalone]


#101486

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-11 15:11 -0800
Message-ID<1414fce8-8d42-4ced-8289-2eaca032baef@googlegroups.com>
In reply to#101407
I've read all of the recommendations and suggestions and ended with two possible working (and a little tested) solutions for this method:


SOLUTION 1: Returning malloc'ed string
- In this case the caller is responsible for free()ing the pointer.
----------------------------------------------------------------------------
char *justfname(const char *text_in)
{
    if (text_in == NULL)
    {
        return NULL; // Would like to throw an error or exception, but don't know how to yet.
    }
    int len = strlen(text_in);

    int pos = len - 1;
    for (pos = (len - 1); (pos >= 0 && text_in[pos] != '\\' 
        && text_in[pos] != '/' && text_in[pos] != ':'); pos--)
        ;
    char *text_out = malloc(sizeof(char) * (len - pos));
    
    if (text_out == NULL)
    {
        return NULL; // Would like to throw an error or exception, but don't know how to yet.
    }
    
    for (int i = (pos + 1); i <= len; i++)
    {
        text_out[i - (pos + 1)] = text_in[i];
    }

    return text_out;
}




SOLUTION 2: Returning a pointer to the appropiate position of the string
- In this case the caller must know that the returned value is a pointer to some part of the original string
----------------------------------------------------------------------------
char *justfname(char *text_in)
{
    if (text_in == NULL)
    {
        return NULL; // Would like to throw an error or exception, but don't know how to yet.
    }
    int len = strlen(text_in);
    int pos = len - 1;
    for (pos = (len - 1); (pos >= 0 && text_in[pos] != '\\' 
        && text_in[pos] != '/' && text_in[pos] != ':'); pos--)
        ;
    return text_in + pos + 1;
}



But in this case I've a second method I can use just in case that I need a malloc'ed value that not depends on the original (and that can't change it either):

char* getRealValue(char* value)
{
    if (value == NULL)
    {
        return NULL;
    }
    int len = strlen(value);
    char *realValue = malloc(sizeof(char) * (len + 1));
    strncpy(realValue, value, len + 1);
    return realValue;
}



Looking at the source code they gave me for this practice (apache core 2.2, a file called server.c), I see that in one of the methods I need to return a pointer to a malloc'ed variable, so I can use either of the solutions (1 or 2 + getRealValue), because the caller is free()ing that pointer later.

But in another of the methods it's expected a pointer to a array (in stack), so in this case the second solution can fit.


Very thanks to all for your great comments and tips, I surelly will continue to ask some questions :)

[toc] | [prev] | [next] | [standalone]


#101490

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-11 19:03 -0500
Message-ID<e1031b13-86f7-0357-a8d2-503881cb8a73@verizon.net>
In reply to#101486
On 01/11/2017 06:11 PM, Fernando D. Bozzo wrote:
> I've read all of the recommendations and suggestions and ended with two possible working (and a little tested) solutions for this method:
>
>
> SOLUTION 1: Returning malloc'ed string
> - In this case the caller is responsible for free()ing the pointer.
> ----------------------------------------------------------------------------
> char *justfname(const char *text_in)
> {
>     if (text_in == NULL)
>     {
>         return NULL; // Would like to throw an error or exception, but don't know how to yet.

C doesn't have such a feature, though it can be emulated using setjmp() 
and longjmp() - a complication you shouldn't worry about anytime soon.

>     }
>     int len = strlen(text_in);
>
>     int pos = len - 1;
>     for (pos = (len - 1); (pos >= 0 && text_in[pos] != '\\'
>         && text_in[pos] != '/' && text_in[pos] != ':'); pos--)
>         ;
>     char *text_out = malloc(sizeof(char) * (len - pos));

sizeof(char) is guaranteed to be exactly 1, so that's unnecessary. The 
recommended way to do this is:

       char *text_out = malloc((len-pos)*sizeof *text_out);

In this particular context, it doesn't make much difference. However, if 
the declaration of text_out was separated from the assignment, it's 
convenient that using sizeof *text_out guarantees that you're allocating 
the correct number of bytes, regardless of what type text_out points at. 
If you ever end up changing the type it points at (which is rather 
unlikely in this case), you don't have to change this line, because it 
will automatically adjust the number of bytes allocated.

>     if (text_out == NULL)
>     {
>         return NULL; // Would like to throw an error or exception, but don't know how to yet.
>     }
>
>     for (int i = (pos + 1); i <= len; i++)
>     {
>         text_out[i - (pos + 1)] = text_in[i];
>     }

A call to memcpy() with the right arguments would be both simpler and 
probably marginally faster.

>     return text_out;
> }

[toc] | [prev] | [next] | [standalone]


#101506

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-12 02:46 -0800
Message-ID<b8b58c4c-1dc6-4ab5-8b21-a0a32528d476@googlegroups.com>
In reply to#101490
El jueves, 12 de enero de 2017, 1:03:50 (UTC+1), James R. Kuyper  escribió:
> On 01/11/2017 06:11 PM, Fernando D. Bozzo wrote:
[...]
> >     char *text_out = malloc(sizeof(char) * (len - pos));
> 
> sizeof(char) is guaranteed to be exactly 1, so that's unnecessary. The 
> recommended way to do this is:
> 
>        char *text_out = malloc((len-pos)*sizeof *text_out);
> 
> In this particular context, it doesn't make much difference. However, if 
> the declaration of text_out was separated from the assignment, it's 
> convenient that using sizeof *text_out guarantees that you're allocating 
> the correct number of bytes, regardless of what type text_out points at. 
> If you ever end up changing the type it points at (which is rather 
> unlikely in this case), you don't have to change this line, because it 
> will automatically adjust the number of bytes allocated.
> 
> >     if (text_out == NULL)
> >     {
> >         return NULL; // Would like to throw an error or exception, but don't know how to yet.
> >     }
> >
> >     for (int i = (pos + 1); i <= len; i++)
> >     {
> >         text_out[i - (pos + 1)] = text_in[i];
> >     }
> 
> A call to memcpy() with the right arguments would be both simpler and 
> probably marginally faster.
> 
> >     return text_out;
> > }

I need to take a deep look at all the common standard functions in C so I better know what to use, like memcpy you suggested.

Thanks for the tips!

[toc] | [prev] | [next] | [standalone]


#101498

FromBarry Schwarz <schwarzb@dqel.com>
Date2017-01-12 00:08 -0800
Message-ID<dnde7ct48a26n0520l31tbu0qtdk1nu4nh@4ax.com>
In reply to#101486
On Wed, 11 Jan 2017 15:11:43 -0800 (PST), "Fernando D. Bozzo"
<fdbozzo@gmail.com> wrote:

>I've read all of the recommendations and suggestions and ended with two possible working (and a little tested) solutions for this method:
>
>
>SOLUTION 1: Returning malloc'ed string
>- In this case the caller is responsible for free()ing the pointer.
>----------------------------------------------------------------------------
>char *justfname(const char *text_in)
>{
>    if (text_in == NULL)
>    {
>        return NULL; // Would like to throw an error or exception, but don't know how to yet.

Why would you do that?  This is a service function.  If it fails, let
the calling function decide what is appropriate.  Consider malloc.
When it fails, it returns NULL.  This lets the calling function decide
if there still some useful work that can be accomplished.

>    }
>    int len = strlen(text_in);
>
>    int pos = len - 1;
>    for (pos = (len - 1); (pos >= 0 && text_in[pos] != '\\' 
>        && text_in[pos] != '/' && text_in[pos] != ':'); pos--)

If you need to compare one character against a list of (un)desirable
ones, you might find strchr useful.  In this case, the second for
clause could be simplified to 
     pos >= 0 && strchr("\\/:", test_in[pos] == NULL

>        ;
>    char *text_out = malloc(sizeof(char) * (len - pos));
>    
>    if (text_out == NULL)
>    {
>        return NULL; // Would like to throw an error or exception, but don't know how to yet.
>    }
>    
>    for (int i = (pos + 1); i <= len; i++)
>    {
>        text_out[i - (pos + 1)] = text_in[i];

You have an aversion to strcpy??

>    }
>
>    return text_out;
>}
>
>
>
>
>SOLUTION 2: Returning a pointer to the appropiate position of the string
>- In this case the caller must know that the returned value is a pointer to some part of the original string
>----------------------------------------------------------------------------
>char *justfname(char *text_in)
>{
>    if (text_in == NULL)
>    {
>        return NULL; // Would like to throw an error or exception, but don't know how to yet.
>    }
>    int len = strlen(text_in);
>    int pos = len - 1;
>    for (pos = (len - 1); (pos >= 0 && text_in[pos] != '\\' 
>        && text_in[pos] != '/' && text_in[pos] != ':'); pos--)
>        ;
>    return text_in + pos + 1;
>}
>
>
>
>But in this case I've a second method I can use just in case that I need a malloc'ed value that not depends on the original (and that can't change it either):
>
>char* getRealValue(char* value)
>{
>    if (value == NULL)
>    {
>        return NULL;
>    }
>    int len = strlen(value);
>    char *realValue = malloc(sizeof(char) * (len + 1));
>    strncpy(realValue, value, len + 1);
>    return realValue;
>}
>
>
>
>Looking at the source code they gave me for this practice (apache core 2.2, a file called server.c), I see that in one of the methods I need to return a pointer to a malloc'ed variable, so I can use either of the solutions (1 or 2 + getRealValue), because the caller is free()ing that pointer later.
>
>But in another of the methods it's expected a pointer to a array (in stack), so in this case the second solution can fit.
>
>
>Very thanks to all for your great comments and tips, I surelly will continue to ask some questions :)
>

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#101507

From"Fernando D. Bozzo" <fdbozzo@gmail.com>
Date2017-01-12 03:02 -0800
Message-ID<fa5bae86-24a8-43fa-b6b0-fb4ce7a826b1@googlegroups.com>
In reply to#101498
El jueves, 12 de enero de 2017, 9:08:46 (UTC+1), Barry Schwarz  escribió:
> On Wed, 11 Jan 2017 15:11:43 -0800 (PST), "Fernando D. Bozzo"
[...]
> >        return NULL; // Would like to throw an error or exception, but don't know how to yet.
> 
> Why would you do that?  This is a service function.  If it fails, let
> the calling function decide what is appropriate.  Consider malloc.
> When it fails, it returns NULL.  This lets the calling function decide
> if there still some useful work that can be accomplished.

In this case you are right, because it's just a function that can be reused in other programs, but I like the OOP style of try/catch/finally for garbage collecting in modules, which I will look how to emulate at some point, because it's a pain doing proper garbage collection in procedural programming.


[...]
> >    for (int i = (pos + 1); i <= len; i++)
> >    {
> >        text_out[i - (pos + 1)] = text_in[i];
> 
> You have an aversion to strcpy??
> 

Ha ha ha! :) No, I have no aversion to any function at all, but strcpy copies the entire string, and I just need to copy the filename part of the input string.
Is there a way to to this with strcpy? I did not try to specify text_in[pos+1] as source string... may be you refer to this.
I will do a test later to see if works, and yes, should be better to use a standard function that a new one


[...]

[toc] | [prev] | [next] | [standalone]


#101513

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-01-12 11:38 +0000
Message-ID<o57pnv$5qg$1@dont-email.me>
In reply to#101507
On 12/01/17 11:02, Fernando D. Bozzo wrote:
> El jueves, 12 de enero de 2017, 9:08:46 (UTC+1), Barry Schwarz
> escribió:
>> On Wed, 11 Jan 2017 15:11:43 -0800 (PST), "Fernando D. Bozzo"
<snip>
>>> for (int i = (pos + 1); i <= len; i++)
>>> {
>>>     text_out[i - (pos + 1)] = text_in[i];
>>
>> You have an aversion to strcpy??
>>
>
> Ha ha ha! :) No, I have no aversion to any function at all, but
> strcpy copies the entire string, and I just need to copy the filename
> part of the input string. Is there a way to to this with strcpy? I
> did not try to specify text_in[pos+1] as source string... may be you
> refer to this. I will do a test later to see if works, and yes,
> should be better to use a standard function that a new one

No, you can't do this with strcpy, but you can certainly do it with memcpy.

memcpy(dest, src, bytes);
dest[bytes] = '\0'; /* to null-terminate the target */

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →

Back to top | Article view | comp.lang.c


csiph-web