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


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

on how to use the third argument of strncmp()

Started byMeredith Montgomery <mmontgomery@levado.to>
First post2022-01-28 16:52 -0300
Last post2022-02-03 18:48 -0800
Articles 20 on this page of 25 — 14 participants

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


Contents

  on how to use the third argument of strncmp() Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 16:52 -0300
    Re: on how to use the third argument of strncmp() Mateusz Viste <mateusz@xyz.invalid> - 2022-01-28 21:07 +0100
      Re: on how to use the third argument of strncmp() Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 18:17 -0300
        Re: on how to use the third argument of strncmp() Mateusz Viste <mateusz@xyz.invalid> - 2022-01-28 22:35 +0100
        Re: on how to use the third argument of strncmp() Vir Campestris <vir.campestris@invalid.invalid> - 2022-02-02 22:01 +0000
      Re: on how to use the third argument of strncmp() Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-28 18:37 -0800
        Re: on how to use the third argument of strncmp() scott@slp53.sl.home (Scott Lurndal) - 2022-01-29 15:32 +0000
        Re: on how to use the third argument of strncmp() Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-29 19:02 +0100
    Re: on how to use the third argument of strncmp() scott@slp53.sl.home (Scott Lurndal) - 2022-01-28 21:26 +0000
      Re: on how to use the third argument of strncmp() Mike Terry <news.dead.person.stones@darjeeling.plus.com> - 2022-01-28 22:03 +0000
        Re: on how to use the third argument of strncmp() scott@slp53.sl.home (Scott Lurndal) - 2022-01-29 15:31 +0000
    Re: on how to use the third argument of strncmp() Siri Cruise <chine.bleu@yahoo.com> - 2022-01-28 13:43 -0800
      Re: on how to use the third argument of strncmp() Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-29 13:43 +0100
        Re: on how to use the third argument of strncmp() Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-29 16:06 +0100
          Re: on how to use the third argument of strncmp() Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-29 16:09 +0100
    Re: on how to use the third argument of strncmp() Kaz Kylheku <480-992-1380@kylheku.com> - 2022-01-28 21:54 +0000
      Re: on how to use the third argument of strncmp() Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 21:47 -0300
    Re: on how to use the third argument of strncmp() James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-28 19:40 -0500
      Re: on how to use the third argument of strncmp() Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-01-29 03:53 -0800
        Re: on how to use the third argument of strncmp() Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-29 19:01 +0100
      Re: on how to use the third argument of strncmp() Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2022-01-29 10:54 -0700
        Re: on how to use the third argument of strncmp() James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-29 14:55 -0500
    Re: on how to use the third argument of strncmp() Manfred <noname@add.invalid> - 2022-01-30 04:03 +0100
      Re: on how to use the third argument of strncmp() Meredith Montgomery <mmontgomery@levado.to> - 2022-01-30 10:02 -0300
        Re: on how to use the third argument of strncmp() Dolores Filandro <dolfiland8@gmail.com> - 2022-02-03 18:48 -0800

Page 1 of 2  [1] 2  Next page →


#164677 — on how to use the third argument of strncmp()

FromMeredith Montgomery <mmontgomery@levado.to>
Date2022-01-28 16:52 -0300
Subjecton how to use the third argument of strncmp()
Message-ID<86czkbd4ey.fsf@levado.to>
I don't really get

--8<---------------cut here---------------start------------->8---
  int strncmp(const char *s1, const char *s2, size_t n);

  The strncmp() function shall compare not more than n bytes (bytes that
  follow a NUL character are not compared) from the array pointed to by
  s1 to the array pointed to by s2.
--8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
Definition.  A c-string is a 0-terminated array of characters.
--8<---------------cut here---------------end--------------->8---

What should choose for the n argument?  If I'm sure s1 and s2 are
c-strings, then I have nothing to worry about, but if I have to specify
the n argument, then I must choose a number.  To me the sensible thing
is

  min(strlen(s1), strlen(s2))

So far so good.  What if I don't want to trust that s1 and s2 are
c-strings?  In that case I can't use strlen() at all.  So I guess this
procedure assumes c-strings.

Is that the end of the story?  I feel there could be more to this.  Can
you share your experience?  Thank you.

[toc] | [next] | [standalone]


#164679

FromMateusz Viste <mateusz@xyz.invalid>
Date2022-01-28 21:07 +0100
Message-ID<st1idr$jc8$1@gioia.aioe.org>
In reply to#164677
2022-01-28 at 16:52 -0300, Meredith Montgomery wrote:
> What should choose for the n argument?  If I'm sure s1 and s2 are
> c-strings, then I have nothing to worry about, but if I have to
> specify the n argument, then I must choose a number.  To me the
> sensible thing is
> 
>   min(strlen(s1), strlen(s2))
> 
> So far so good.  What if I don't want to trust that s1 and s2 are
> c-strings?  In that case I can't use strlen() at all.  So I guess this
> procedure assumes c-strings.

This function is intended to work with fixed-width (padded, not
necessarily terminated) string fields, like strncpy(). I don't think
this kind of fields is much in use nowadays.

strncmp() also allows to compare prefix of strings (ie. "do s1 and s2
start with the exact same 7 characters?" situation).

Since you wish to compare NULL-terminated strings in their entirety,
the usual strcmp() is the right tool for the job.


Mateusz

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


#164681

FromMeredith Montgomery <mmontgomery@levado.to>
Date2022-01-28 18:17 -0300
Message-ID<86ee4rblvt.fsf@levado.to>
In reply to#164679
Mateusz Viste <mateusz@xyz.invalid> writes:

> 2022-01-28 at 16:52 -0300, Meredith Montgomery wrote:
>> What should choose for the n argument?  If I'm sure s1 and s2 are
>> c-strings, then I have nothing to worry about, but if I have to
>> specify the n argument, then I must choose a number.  To me the
>> sensible thing is
>> 
>>   min(strlen(s1), strlen(s2))
>> 
>> So far so good.  What if I don't want to trust that s1 and s2 are
>> c-strings?  In that case I can't use strlen() at all.  So I guess this
>> procedure assumes c-strings.
>
> This function is intended to work with fixed-width (padded, not
> necessarily terminated) string fields, like strncpy(). I don't think
> this kind of fields is much in use nowadays.
>
> strncmp() also allows to compare prefix of strings (ie. "do s1 and s2
> start with the exact same 7 characters?" situation).
>
> Since you wish to compare NULL-terminated strings in their entirety,
> the usual strcmp() is the right tool for the job.

But what do I do when these strings come from a user?  I can't trust the
user will close them properly.  

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


#164685

FromMateusz Viste <mateusz@xyz.invalid>
Date2022-01-28 22:35 +0100
Message-ID<st1ni9$rgn$1@gioia.aioe.org>
In reply to#164681
2022-01-28 at 18:17 -0300, Meredith Montgomery wrote:
> > Since you wish to compare NULL-terminated strings in their entirety,
> > the usual strcmp() is the right tool for the job.  
> 
> But what do I do when these strings come from a user?  I can't trust
> the user will close them properly.

I take it that "a user" is a metaphor for something here, since
real users are rarely tasked with inserting NULL terminators after their
output...

So you obtain data from an unreliable source, and you aren't sure this
data is properly terminated? Then terminate it yourself. You surely
know how much data you acquired.


len = fetch_data_from_user(buff);

if (len < 0) {
  puts("failed to fetch data");
} else {
  buff[len] = 0; /* data might not be NULL-terminated */
  if (strcmp(buff, "hello") == 0) puts("user says hello");
}


Mateusz

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


#164754

FromVir Campestris <vir.campestris@invalid.invalid>
Date2022-02-02 22:01 +0000
Message-ID<steuvk$8bu$2@dont-email.me>
In reply to#164681
On 28/01/2022 21:17, Meredith Montgomery wrote:
> Mateusz Viste <mateusz@xyz.invalid> writes:
> 
>> 2022-01-28 at 16:52 -0300, Meredith Montgomery wrote:
>>> What should choose for the n argument?  If I'm sure s1 and s2 are
>>> c-strings, then I have nothing to worry about, but if I have to
>>> specify the n argument, then I must choose a number.  To me the
>>> sensible thing is
>>>
>>>    min(strlen(s1), strlen(s2))
>>>
>>> So far so good.  What if I don't want to trust that s1 and s2 are
>>> c-strings?  In that case I can't use strlen() at all.  So I guess this
>>> procedure assumes c-strings.
>>
>> This function is intended to work with fixed-width (padded, not
>> necessarily terminated) string fields, like strncpy(). I don't think
>> this kind of fields is much in use nowadays.
>>
>> strncmp() also allows to compare prefix of strings (ie. "do s1 and s2
>> start with the exact same 7 characters?" situation).
>>
>> Since you wish to compare NULL-terminated strings in their entirety,
>> the usual strcmp() is the right tool for the job.
> 
> But what do I do when these strings come from a user?  I can't trust the
> user will close them properly.

If you can't trust the user to have put a null on for strcmp, then you 
can't trust it for strlen either.

Andy

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


#164708

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2022-01-28 18:37 -0800
Message-ID<87k0ejl11j.fsf@nosuchdomain.example.com>
In reply to#164679
Mateusz Viste <mateusz@xyz.invalid> writes:
[...]
> Since you wish to compare NULL-terminated strings in their entirety,
> the usual strcmp() is the right tool for the job.

A small but important correction: strings are null-terminated, not
NULL-terminated.  NULL is (a macro that expands to) a null pointer
constant.  The terminator for a string is a null character '\0',
sometimes called NUL, not a null pointer.

(The null character is referred to as NULL in some contexts, but
avoiding that term for it is a good way to avoid confusion.)

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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


#164717

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-01-29 15:32 +0000
Message-ID<h6dJJ.5507$u%.3019@fx01.iad>
In reply to#164708
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>Mateusz Viste <mateusz@xyz.invalid> writes:
>[...]
>> Since you wish to compare NULL-terminated strings in their entirety,
>> the usual strcmp() is the right tool for the job.
>
>A small but important correction: strings are null-terminated, not
>NULL-terminated.  NULL is (a macro that expands to) a null pointer
>constant.  The terminator for a string is a null character '\0',
>sometimes called NUL, not a null pointer.

In the original ASCII tables it was the 'nul' character.

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


#164723

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-01-29 19:02 +0100
Message-ID<st3vfk$eet$2@dont-email.me>
In reply to#164708
Am 29.01.2022 um 03:37 schrieb Keith Thompson:
> Mateusz Viste <mateusz@xyz.invalid> writes:
> [...]
>> Since you wish to compare NULL-terminated strings in their entirety,
>> the usual strcmp() is the right tool for the job.
> 
> A small but important correction: strings are null-terminated, not
> NULL-terminated.  NULL is (a macro that expands to) a null pointer
> constant.  The terminator for a string is a null character '\0',
> sometimes called NUL, not a null pointer.

*facpalm*

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


#164682

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-01-28 21:26 +0000
Message-ID<ObZIJ.21451$V31.13472@fx47.iad>
In reply to#164677
Meredith Montgomery <mmontgomery@levado.to> writes:
>I don't really get
>
>--8<---------------cut here---------------start------------->8---
>  int strncmp(const char *s1, const char *s2, size_t n);
>
>  The strncmp() function shall compare not more than n bytes (bytes that
>  follow a NUL character are not compared) from the array pointed to by
>  s1 to the array pointed to by s2.
>--8<---------------cut here---------------end--------------->8---
>
>--8<---------------cut here---------------start------------->8---
>Definition.  A c-string is a 0-terminated array of characters.
>--8<---------------cut here---------------end--------------->8---
>
>What should choose for the n argument?  If I'm sure s1 and s2 are
>c-strings, then I have nothing to worry about, but if I have to specify
>the n argument, then I must choose a number.  To me the sensible thing
>is
>
>  min(strlen(s1), strlen(s2))
>
>So far so good.  What if I don't want to trust that s1 and s2 are
>c-strings?  In that case I can't use strlen() at all.  So I guess this
>procedure assumes c-strings.

 The 'str' prefix on the library function names pretty much tells you
they were designed to work with nul-terminated strings.   For non-strings one uses
memcpy, memmove and memset.

Say you have input text of "cpu0", you can use
strncmp(text, "cpu", sizeof("cpu")) to match on
the prefix then parse the numeric suffix.

Or, say you have a command table, and you want to
match the unique leading prefix of a command rather
than the entire command.

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


#164689

FromMike Terry <news.dead.person.stones@darjeeling.plus.com>
Date2022-01-28 22:03 +0000
Message-ID<st1p6r$1p07$1@gioia.aioe.org>
In reply to#164682
On 28/01/2022 21:26, Scott Lurndal wrote:
> Meredith Montgomery <mmontgomery@levado.to> writes:
>> I don't really get
>>
>> --8<---------------cut here---------------start------------->8---
>>   int strncmp(const char *s1, const char *s2, size_t n);
>>
>>   The strncmp() function shall compare not more than n bytes (bytes that
>>   follow a NUL character are not compared) from the array pointed to by
>>   s1 to the array pointed to by s2.
>> --8<---------------cut here---------------end--------------->8---
>>
>> --8<---------------cut here---------------start------------->8---
>> Definition.  A c-string is a 0-terminated array of characters.
>> --8<---------------cut here---------------end--------------->8---
>>
>> What should choose for the n argument?  If I'm sure s1 and s2 are
>> c-strings, then I have nothing to worry about, but if I have to specify
>> the n argument, then I must choose a number.  To me the sensible thing
>> is
>>
>>   min(strlen(s1), strlen(s2))
>>
>> So far so good.  What if I don't want to trust that s1 and s2 are
>> c-strings?  In that case I can't use strlen() at all.  So I guess this
>> procedure assumes c-strings.
> 
>   The 'str' prefix on the library function names pretty much tells you
> they were designed to work with nul-terminated strings.   For non-strings one uses
> memcpy, memmove and memset.
> 
> Say you have input text of "cpu0", you can use
> strncmp(text, "cpu", sizeof("cpu")) to match on
> the prefix then parse the numeric suffix.

You mean strncmp(text, "cpu", sizeof("cpu") - 1).
Or strncmp(text, "cpu", strlen("cpu")).

Mike.

> 
> Or, say you have a command table, and you want to
> match the unique leading prefix of a command rather
> than the entire command.
> 

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


#164716

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-01-29 15:31 +0000
Message-ID<e5dJJ.5506$u%.882@fx01.iad>
In reply to#164689
Mike Terry <news.dead.person.stones@darjeeling.plus.com> writes:
>On 28/01/2022 21:26, Scott Lurndal wrote:
>> Meredith Montgomery <mmontgomery@levado.to> writes:
>>> I don't really get
>>>
>>> --8<---------------cut here---------------start------------->8---
>>>   int strncmp(const char *s1, const char *s2, size_t n);
>>>
>>>   The strncmp() function shall compare not more than n bytes (bytes that
>>>   follow a NUL character are not compared) from the array pointed to by
>>>   s1 to the array pointed to by s2.
>>> --8<---------------cut here---------------end--------------->8---
>>>
>>> --8<---------------cut here---------------start------------->8---
>>> Definition.  A c-string is a 0-terminated array of characters.
>>> --8<---------------cut here---------------end--------------->8---
>>>
>>> What should choose for the n argument?  If I'm sure s1 and s2 are
>>> c-strings, then I have nothing to worry about, but if I have to specify
>>> the n argument, then I must choose a number.  To me the sensible thing
>>> is
>>>
>>>   min(strlen(s1), strlen(s2))
>>>
>>> So far so good.  What if I don't want to trust that s1 and s2 are
>>> c-strings?  In that case I can't use strlen() at all.  So I guess this
>>> procedure assumes c-strings.
>> 
>>   The 'str' prefix on the library function names pretty much tells you
>> they were designed to work with nul-terminated strings.   For non-strings one uses
>> memcpy, memmove and memset.
>> 
>> Say you have input text of "cpu0", you can use
>> strncmp(text, "cpu", sizeof("cpu")) to match on
>> the prefix then parse the numeric suffix.
>
>You mean strncmp(text, "cpu", sizeof("cpu") - 1).
>Or strncmp(text, "cpu", strlen("cpu")).

Yes, indeed, that was a typo.  I prefer the compile time version.

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


#164686

FromSiri Cruise <chine.bleu@yahoo.com>
Date2022-01-28 13:43 -0800
Message-ID<chine.bleu-2381BF.13431128012022@reader.eternal-september.org>
In reply to#164677
In article <86czkbd4ey.fsf@levado.to>,
 Meredith Montgomery <mmontgomery@levado.to> wrote:

> What should choose for the n argument?  If I'm sure s1 and s2 are
> c-strings, then I have nothing to worry about, but if I have to specify
> the n argument, then I must choose a number.  To me the sensible thing
> is

//  begins(stringvalue, constantstring)

#define begins(s, c) (strncmp(s,c,(sizeof c))==0)

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.    @
'I desire mercy, not sacrifice.'                                    /|\
Discordia: not just a religion but also a parody. This post         / \
I am an Andrea Doria sockpuppet.                  insults Islam.  Mohammed

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


#164712

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-01-29 13:43 +0100
Message-ID<st3cpn$fe$1@dont-email.me>
In reply to#164686
Am 28.01.2022 um 22:43 schrieb Siri Cruise:
> In article <86czkbd4ey.fsf@levado.to>,
>   Meredith Montgomery <mmontgomery@levado.to> wrote:
> 
>> What should choose for the n argument?  If I'm sure s1 and s2 are
>> c-strings, then I have nothing to worry about, but if I have to specify
>> the n argument, then I must choose a number.  To me the sensible thing
>> is
> 
> //  begins(stringvalue, constantstring)
> 
> #define begins(s, c) (strncmp(s,c,(sizeof c))==0)

Doesn't this look better ?

#include <cstddef>
#include <concepts>
#include <string_view>

template<typename char_t = char>
inline
bool begins_with( std::basic_string_view<char_t> const &str, 
std::basic_string_view<char_t> const &cmp )
{
	return str.starts_with( cmp );
}

#include <iostream>

using namespace std;

int main()
{
	begins_with( "hello world"sv, "hello"sv );
}

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


#164714

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-01-29 16:06 +0100
Message-ID<st3l4t$u7d$1@dont-email.me>
In reply to#164712
Am 29.01.2022 um 13:43 schrieb Bonita Montero:

> Doesn't this look better ?
> 
> #include <cstddef>
> #include <concepts>
> #include <string_view>
> 
> template<typename char_t = char>
> 	requires std::is_same_v<char_t, char> || std::is_same_v<char_t, wchar_t>
> inline
> bool begins_with( std::basic_string_view<char_t> const &str, std::basic_string_view<char_t> const &cmp )
> {
> 	return str.starts_with( cmp );
> }
> 
> #include <iostream>
> 
> using namespace std;
> 
> int main()
> {
> 	cout << begins_with( "hello world"sv, "hello"sv ) << endl;
> }
And for the above code everything inside the begins_with-call is
compile-time evaluated. And even if wouldn't be: the starts_with
call could check if cmp's length is shorter than str and and skip
the comparison, thereby being faster than the strncmp-solution in
plain C.

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


#164715

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-01-29 16:09 +0100
Message-ID<st3lc2$vk1$1@dont-email.me>
In reply to#164714
This is even simpler and also compile-time evaluated:

	bool f = "hello world"sv.starts_with( "hello" );

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


#164688

FromKaz Kylheku <480-992-1380@kylheku.com>
Date2022-01-28 21:54 +0000
Message-ID<20220128134351.435@kylheku.com>
In reply to#164677
On 2022-01-28, Meredith Montgomery <mmontgomery@levado.to> wrote:
> What should choose for the n argument?  If I'm sure s1 and s2 are
> c-strings, then I have nothing to worry about, but if I have to specify
> the n argument, then I must choose a number.  To me the sensible thing
> is
>
>   min(strlen(s1), strlen(s2))

So you don't actually have a real requirement that you're
trying to implement; someone handed you a spcification which says "make
me some kind of program that uses strncmp in some good way".

> Is that the end of the story?  I feel there could be more to this.  Can
> you share your experience?  Thank you.

One use case is testing whether a given string s1 is the prefix of a
string s2. Then we choose strlen(s1).

For instance, suppose you have some simple command language, in which
you'd like users to be able to use abbreviated commands. Say that if the
user types at least two charcters, you'd like to do a prefix match.
If the user types "li", you'd like to dispatch the "list" command.
So then you're comparing the list of commands in your cmomand table like
this:

   size_t len  = strlen(user_input);

   for (i = 0; len >= 2 && i < NCOMMANDS; i++)
   {
     if (0 == strncmp(user_input, command_table[i].command, len))
     {
        /* prefix match: e.g "lis" input matched "list".
        break;
     }
   }

   if (len < 2 || i == NCOMMANDS)
   {
      /* command not found */
   }

Under this scheme, if the user types "listing", then it will not match
the "list" command, but "li" will.

Alternatively, the command table could have short command in it like
"li", whereby the user can use the longer "list", and it makes no
diference.

   const char *command_table[i].command;

   if (0 == strncmp(user_input, command, strlen(command)))
   {
      /* the command, e.g. "li", is a prefix of the user's requested
         command such as "listing", hence match */
      break;
   }

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


#164698

FromMeredith Montgomery <mmontgomery@levado.to>
Date2022-01-28 21:47 -0300
Message-ID<86zgnf9xln.fsf@levado.to>
In reply to#164688
Kaz Kylheku <480-992-1380@kylheku.com> writes:

> On 2022-01-28, Meredith Montgomery <mmontgomery@levado.to> wrote:
>> What should choose for the n argument?  If I'm sure s1 and s2 are
>> c-strings, then I have nothing to worry about, but if I have to specify
>> the n argument, then I must choose a number.  To me the sensible thing
>> is
>>
>>   min(strlen(s1), strlen(s2))
>
> So you don't actually have a real requirement that you're
> trying to implement; someone handed you a spcification which says "make
> me some kind of program that uses strncmp in some good way".
>
>> Is that the end of the story?  I feel there could be more to this.  Can
>> you share your experience?  Thank you.
>
> One use case is testing whether a given string s1 is the prefix of a
> string s2. Then we choose strlen(s1).
>
> For instance, suppose you have some simple command language, in which
> you'd like users to be able to use abbreviated commands. Say that if the
> user types at least two charcters, you'd like to do a prefix match.
> If the user types "li", you'd like to dispatch the "list" command.
> So then you're comparing the list of commands in your cmomand table like
> this:
>
>    size_t len  = strlen(user_input);
>
>    for (i = 0; len >= 2 && i < NCOMMANDS; i++)
>    {
>      if (0 == strncmp(user_input, command_table[i].command, len))
>      {
>         /* prefix match: e.g "lis" input matched "list".
>         break;
>      }
>    }
>
>    if (len < 2 || i == NCOMMANDS)
>    {
>       /* command not found */
>    }
>
> Under this scheme, if the user types "listing", then it will not match
> the "list" command, but "li" will.
>
> Alternatively, the command table could have short command in it like
> "li", whereby the user can use the longer "list", and it makes no
> diference.
>
>    const char *command_table[i].command;
>
>    if (0 == strncmp(user_input, command, strlen(command)))
>    {
>       /* the command, e.g. "li", is a prefix of the user's requested
>          command such as "listing", hence match */
>       break;
>    }

Pretty interesting illustration!

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


#164697

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-01-28 19:40 -0500
Message-ID<st22e8$m8m$1@dont-email.me>
In reply to#164677
On 1/28/22 14:52, Meredith Montgomery wrote:
> I don't really get
>
> --8<---------------cut here---------------start------------->8---
> int strncmp(const char *s1, const char *s2, size_t n);
>
> The strncmp() function shall compare not more than n bytes (bytes that
> follow a NUL character are not compared) from the array pointed to by
> s1 to the array pointed to by s2.
> --8<---------------cut here---------------end--------------->8---
>
> --8<---------------cut here---------------start------------->8---
> Definition. A c-string is a 0-terminated array of characters.
> --8<---------------cut here---------------end--------------->8---
>
> What should choose for the n argument? If I'm sure s1 and s2 are
> c-strings, then I have nothing to worry about, but if I have to specify
> the n argument, then I must choose a number. To me the sensible thing
> is
>
> min(strlen(s1), strlen(s2))
>
> So far so good. What if I don't want to trust that s1 and s2 are
> c-strings? In that case I can't use strlen() at all. So I guess this
> procedure assumes c-strings.
>
> Is that the end of the story? I feel there could be more to this. Can
> you share your experience? Thank you.

I've been told by experts that the reasons why I needed to use strncpy()
were very peculiar, but given those peculiar reasons, it's use was
legitimate. The situation described below came up fairly frequently
while I was working for NASA on data coming down from earth-observing
satellites:

My programs had to deal with file formats that set aside a fixed amount
of space to store a string that was not guaranteed to be able to fit in
that space - if it didn't, it was acceptable to truncate it to fit.
There would be a terminating null character only if the field stored a
string shorter than the size of the field.
I used strncpy() both to fill in such fields, and to copy from such
fields. In both cases, the third argument of strncpy() was the size
allocated for that field, which I knew at the time I was writing the
program because I could read the file's format specification.

strlen() would have been useless for determining that value - since the
data was not guaranteed to be null terminated, strlen() might easily
have ended up searching outside the memory allocated for the string for
a terminating null character. There was no guarantee that it would find
one before reaching memory that my process did not have permission to
read. Any null character found outside of the memory allocated for the
string would have had nothing to do with describing the length of the
string.

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


#164711

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-01-29 03:53 -0800
Message-ID<5f4e00a3-bd56-4259-90a3-7773120c88d7n@googlegroups.com>
In reply to#164697
On Saturday, 29 January 2022 at 00:40:53 UTC, james...@alumni.caltech.edu wrote:
> 
> I've been told by experts that the reasons why I needed to use strncpy() 
> were very peculiar, but given those peculiar reasons, it's use was 
> legitimate. The situation described below came up fairly frequently 
> while I was working for NASA on data coming down from earth-observing 
> satellites: 
> 
> My programs had to deal with file formats that set aside a fixed amount 
> of space to store a string that was not guaranteed to be able to fit in 
> that space - if it didn't, it was acceptable to truncate it to fit. 
> There would be a terminating null character only if the field stored a 
> string shorter than the size of the field. 
> I used strncpy() both to fill in such fields, and to copy from such 
> fields. In both cases, the third argument of strncpy() was the size 
> allocated for that field, which I knew at the time I was writing the 
> program because I could read the file's format specification. 
> 
> strlen() would have been useless for determining that value - since the 
> data was not guaranteed to be null terminated, strlen() might easily 
> have ended up searching outside the memory allocated for the string for 
> a terminating null character. There was no guarantee that it would find 
> one before reaching memory that my process did not have permission to 
> read. Any null character found outside of the memory allocated for the 
> string would have had nothing to do with describing the length of the 
> string.
>
That's what strncpy() is designed for. Databases with fixed field string
records, and a convention that the last character need not be nul.
You rarely write raw database records these days, unless you are
writing the database query engine itself. I've certainly never used strncpy()
in a "real" program. But I believe that in the olden days, it was
more common.

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


#164722

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-01-29 19:01 +0100
Message-ID<st3vea$eet$1@dont-email.me>
In reply to#164711
> That's what strncpy() is designed for. Databases with fixed field string
> records, and a convention that the last character need not be nul.

I don't know if this is common for all database-servers,
but Oracle and SQL Server tail-pad CHAR(n)-columns with spaces.

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


Page 1 of 2  [1] 2  Next page →

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


csiph-web