Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #164677 > unrolled thread
| Started by | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| First post | 2022-01-28 16:52 -0300 |
| Last post | 2022-02-03 18:48 -0800 |
| Articles | 20 on this page of 25 — 14 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| Date | 2022-01-28 16:52 -0300 |
| Subject | on 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]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2022-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]
| From | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| Date | 2022-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]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2022-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]
| From | Vir Campestris <vir.campestris@invalid.invalid> |
|---|---|
| Date | 2022-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-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]
| From | Mike Terry <news.dead.person.stones@darjeeling.plus.com> |
|---|---|
| Date | 2022-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-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]
| From | Siri Cruise <chine.bleu@yahoo.com> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| Date | 2022-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]
| From | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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