Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #101407 > unrolled thread
| Started by | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| First post | 2017-01-10 15:43 -0800 |
| Last post | 2017-01-13 18:02 -0800 |
| Articles | 20 on this page of 101 — 19 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Gareth Owen <gwowen@gmail.com> |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2017-01-11 17:53 +0000 |
| Subject | Strings 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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2017-01-11 12:46 -0800 |
| Subject | Re: 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]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2017-01-11 14:40 -0800 |
| Subject | Re: 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]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2017-01-11 18:12 -0600 |
| Subject | Re: 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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-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]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-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