Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #111820 > unrolled thread
| Started by | DFS <nospam@dfs.com> |
|---|---|
| First post | 2017-06-08 11:13 -0400 |
| Last post | 2017-06-08 11:51 -0700 |
| Articles | 20 on this page of 41 — 15 participants |
Back to article view | Back to comp.lang.c
sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-08 11:13 -0400
Re: sizeof environment variables array = 1? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2017-06-08 11:25 -0400
Re: sizeof environment variables array = 1? Keith Thompson <kst-u@mib.org> - 2017-06-08 09:34 -0700
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-08 13:14 -0400
Re: sizeof environment variables array = 1? jameskuyper@verizon.net - 2017-06-08 10:51 -0700
Re: sizeof environment variables array = 1? Gareth Owen <gwowen@gmail.com> - 2017-06-08 16:56 +0100
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-08 12:18 -0400
Re: sizeof environment variables array = 1? scott@slp53.sl.home (Scott Lurndal) - 2017-06-08 16:35 +0000
Re: sizeof environment variables array = 1? Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2017-06-08 12:43 -0400
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-08 13:49 -0400
Re: sizeof environment variables array = 1? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-08 13:58 -0400
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-08 14:45 -0400
Re: sizeof environment variables array = 1? Keith Thompson <kst-u@mib.org> - 2017-06-08 12:10 -0700
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-09 11:21 -0400
Re: sizeof environment variables array = 1? Richard Heathfield <rjh@cpax.org.uk> - 2017-06-09 16:23 +0100
Re: sizeof environment variables array = 1? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-09 11:48 -0400
Re: sizeof environment variables array = 1? Richard Heathfield <rjh@cpax.org.uk> - 2017-06-09 16:53 +0100
Re: sizeof environment variables array = 1? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-09 12:18 -0400
Re: sizeof environment variables array = 1? Richard Heathfield <rjh@cpax.org.uk> - 2017-06-09 17:28 +0100
Re: sizeof environment variables array = 1? Keith Thompson <kst-u@mib.org> - 2017-06-09 09:12 -0700
Re: sizeof environment variables array = 1? "Patrick.Schluter" <Patrick.Schluter@free.fr> - 2017-06-10 09:28 +0200
Re: sizeof environment variables array = 1? jak <please@nospam.tnx> - 2017-06-08 22:18 +0200
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-08 17:31 -0400
Re: sizeof environment variables array = 1? Keith Thompson <kst-u@mib.org> - 2017-06-08 15:12 -0700
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-09 11:21 -0400
Re: sizeof environment variables array = 1? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-09 16:39 +0100
Re: sizeof environment variables array = 1? Gareth Owen <gwowen@gmail.com> - 2017-06-10 07:26 +0100
Re: sizeof environment variables array = 1? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-10 13:21 +0100
Re: sizeof environment variables array = 1? gordonb.q80bx@burditt.org (Gordon Burditt) - 2017-06-10 17:32 -0500
Re: sizeof environment variables array = 1? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-11 01:01 +0100
Re: sizeof environment variables array = 1? luser droog <luser.droog@gmail.com> - 2017-06-11 01:28 -0700
Re: sizeof environment variables array = 1? raltbos@xs4all.nl (Richard Bos) - 2017-06-17 18:38 +0000
Re: sizeof environment variables array = 1? Keith Thompson <kst-u@mib.org> - 2017-06-09 08:41 -0700
Re: sizeof environment variables array = 1? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-09 11:50 -0400
Re: sizeof environment variables array = 1? raltbos@xs4all.nl (Richard Bos) - 2017-06-17 18:37 +0000
Re: sizeof environment variables array = 1? DFS <nospam@dfs.com> - 2017-06-18 09:11 -0400
Re: sizeof environment variables array = 1? "Patrick.Schluter" <Patrick.Schluter@free.fr> - 2017-06-10 09:19 +0200
Re: sizeof environment variables array = 1? Robert Wessel <robertwessel2@yahoo.com> - 2017-06-08 12:44 -0500
Re: sizeof environment variables array = 1? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-08 18:01 +0100
Re: sizeof environment variables array = 1? Gareth Owen <gwowen@gmail.com> - 2017-06-08 18:45 +0100
Re: sizeof environment variables array = 1? Keith Thompson <kst-u@mib.org> - 2017-06-08 11:51 -0700
Page 1 of 3 [1] 2 3 Next page →
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-08 11:13 -0400 |
| Subject | sizeof environment variables array = 1? |
| Message-ID | <ohbpd7$5r3$2@dont-email.me> |
int main(int argc, char *argv[], char *env[])
{
printf("%d\n",sizeof(env)/sizeof(env[0]));
return(0);
)
Output is 1.
Why?
If I add:
while (*env) {printf("%s\n", *env++);}
it prints out all 65 of them.
[toc] | [next] | [standalone]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2017-06-08 11:25 -0400 |
| Message-ID | <ohbq3c$6oj$1@dont-email.me> |
| In reply to | #111820 |
DFS wrote:
> int main(int argc, char *argv[], char *env[])
> {
> printf("%d\n",sizeof(env)/sizeof(env[0]));
> return(0);
> )
>
> Output is 1.
>
> Why?
Given
char *env[];
then
env is a pointer (to a pointer to char)
and
env[0] is also a pointer (to a char)
Apparently, in your execution environment,
a >>pointer to a pointer to char<< is the same size as a >>pointer to char<<
and, thus, division of the size of one by the size of the other gives a
value of 1
>
> If I add:
>
> while (*env) {printf("%s\n", *env++);}
>
> it prints out all 65 of them.
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-08 09:34 -0700 |
| Message-ID | <lnvao6igkb.fsf@kst-u.example.com> |
| In reply to | #111822 |
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
> DFS wrote:
>> int main(int argc, char *argv[], char *env[])
>> {
>> printf("%d\n",sizeof(env)/sizeof(env[0]));
Should be "%zu\n", not "%d\n" -- or you could use "%d\n" and cast the
argument to int.
>> return(0);
>> )
>>
>> Output is 1.
>>
>> Why?
>
> Given
> char *env[];
> then
> env is a pointer (to a pointer to char)
> and
> env[0] is also a pointer (to a char)
`char *env[]` normally makes env an array of char* pointers, but because
it's a parameter declaration it's "adjusted" to become a pointer.
This:
int main(int argc, char *argv[], char *env[])
is exactly equivalent to this:
int main(int argc, char **argv, char **env)
Given a pointer to the initial element of an array, you can't
use sizeof to determine the number of elements in that array.
You can traverse the array elements to find the length *if* there's
a consistent convention marking the end of the array (typically a
null pointer for an array of pointers, or a null character for an
array of characters).
Incidentally, this declaration of main is not portable, but an
optional third "env" parameter is a common extension.
> Apparently, in your execution environment,
> a >>pointer to a pointer to char<< is the same size as a >>pointer to char<<
> and, thus, division of the size of one by the size of the other gives a
> value of 1
In principle, it could still yield 1 if, for example, sizeof (char**)
== 6 and sizeof (char*) == 4. But that detail in understanding
the semantics of this semantically incorrect code is less important
than fixing the code.
>> If I add:
>>
>> while (*env) {printf("%s\n", *env++);}
>>
>> it prints out all 65 of them.
Because it scans for the null pointer that conventionally marks the end
of the array. If the program were invoked with an `env` data structure
that isn't properly terminated, you'd have undefined behavior.
--
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 | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-08 13:14 -0400 |
| Message-ID | <ohc0fl$vcl$3@dont-email.me> |
| In reply to | #111832 |
On 6/8/2017 12:34 PM, Keith Thompson wrote:
> Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
>> DFS wrote:
>>> int main(int argc, char *argv[], char *env[])
>>> {
>>> printf("%d\n",sizeof(env)/sizeof(env[0]));
>
> Should be "%zu\n", not "%d\n"
printf("%zu\n",sizeof(env)/sizeof(env[0]));
zu
issue with Tiny C compiler I guess (which claims to almost-fully support
C99).
> -- or you could use "%d\n" and cast the argument to int.
printf("%d\n",(int)(sizeof(env)/sizeof(env[0])));
1
> Incidentally, this declaration of main is not portable, but an
> optional third "env" parameter is a common extension.
Haven't tested it yet, but I assume it will run unchanged on Linux.
>> Apparently, in your execution environment,
>> a >>pointer to a pointer to char<< is the same size as a >>pointer to char<<
>> and, thus, division of the size of one by the size of the other gives a
>> value of 1
>
> In principle, it could still yield 1 if, for example, sizeof (char**)
> == 6 and sizeof (char*) == 4. But that detail in understanding
> the semantics of this semantically incorrect code is less important
> than fixing the code.
What here needs to be fixed?
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-06-08 10:51 -0700 |
| Message-ID | <497ef66f-7fc4-43d8-a897-8d5599042e6e@googlegroups.com> |
| In reply to | #111842 |
On Thursday, June 8, 2017 at 1:15:00 PM UTC-4, DFS wrote:
> On 6/8/2017 12:34 PM, Keith Thompson wrote:
> > Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
> >> DFS wrote:
> >>> int main(int argc, char *argv[], char *env[])
> >>> {
> >>> printf("%d\n",sizeof(env)/sizeof(env[0]));
> >
> > Should be "%zu\n", not "%d\n"
>
> printf("%zu\n",sizeof(env)/sizeof(env[0]));
> zu
>
> issue with Tiny C compiler I guess (which claims to almost-fully support
> C99).
>
>
> > -- or you could use "%d\n" and cast the argument to int.
>
> printf("%d\n",(int)(sizeof(env)/sizeof(env[0])));
> 1
>
>
> > Incidentally, this declaration of main is not portable, but an
> > optional third "env" parameter is a common extension.
>
> Haven't tested it yet, but I assume it will run unchanged on Linux.
>
>
>
> >> Apparently, in your execution environment,
> >> a >>pointer to a pointer to char<< is the same size as a >>pointer to char<<
> >> and, thus, division of the size of one by the size of the other gives a
> >> value of 1
> >
> > In principle, it could still yield 1 if, for example, sizeof (char**)
> > == 6 and sizeof (char*) == 4. But that detail in understanding
> > the semantics of this semantically incorrect code is less important
> > than fixing the code.
>
> What here needs to be fixed?
The env parameter, while declared as an array, is actually a pointer. It points to the first element of an array of pointers. Your method of determining how many elements there are in that array doesn't work. The way you're supposed to figure it out is by going through that array, one element at a time, until you find a null pointer. That's what needs to be fixed.
[toc] | [prev] | [next] | [standalone]
| From | Gareth Owen <gwowen@gmail.com> |
|---|---|
| Date | 2017-06-08 16:56 +0100 |
| Message-ID | <878tl2v5ge.fsf@gmail.com> |
| In reply to | #111820 |
DFS <nospam@dfs.com> writes:
> int main(int argc, char *argv[], char *env[])
> {
> printf("%d\n",sizeof(env)/sizeof(env[0]));
> return(0);
> )
>
> Output is 1.
>
> Why?
Anything that looks like an array object - when used in the argument
list of a function, is not an array object, but "decays" into a pointer.
so in
int foo(char *arr1[12])
{
char *arr2[12];
char **arr3;
}
arr1 and arr3 have the same type, even though
arr1 and arr2 have the same declaration.
A misfeature, but an explicable one.
There is no way to obtain the size of arr1 in foo() without passing it
in explicitly (or counting them using a sentinel such as NULL to mark
the end, as is done with environment variables)
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-08 12:18 -0400 |
| Message-ID | <ohbt7i$jm2$2@dont-email.me> |
| In reply to | #111826 |
On 6/8/2017 11:56 AM, Gareth Owen wrote:
> DFS <nospam@dfs.com> writes:
>
>> int main(int argc, char *argv[], char *env[])
>> {
>> printf("%d\n",sizeof(env)/sizeof(env[0]));
>> return(0);
>> )
>>
>> Output is 1.
>>
>> Why?
>
> Anything that looks like an array object - when used in the argument
> list of a function, is not an array object, but "decays" into a pointer.
>
> so in
>
> int foo(char *arr1[12])
> {
> char *arr2[12];
> char **arr3;
> }
>
> arr1 and arr3 have the same type, even though
> arr1 and arr2 have the same declaration.
>
> A misfeature, but an explicable one.
Gotcha
> There is no way to obtain the size of arr1 in foo() without passing it
> in explicitly (or counting them using a sentinel such as NULL to mark
> the end, as is done with environment variables)
I want to check the Path env variable for the existence of a string:
\GNU\Win32\bin
I counted the env variables:
int envars=0;
while (*env!=NULL) {*env++;envars++;}
printf("%d\n",envars);
65
But then I can't go back and reference the values in env[] again because
the pointer has moved to the end of the array (or past it?).
What would you suggest?
1) can I reset the pointer back to the beginning of env[]? How?
2) make a copy of the env[] array and use it? How do I make a copy?
3) can I create a new pointer pointing back to the beginning of env[]? How?
Thanks
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-06-08 16:35 +0000 |
| Message-ID | <m1f_A.19254$5S7.2068@fx28.iad> |
| In reply to | #111831 |
DFS <nospam@dfs.com> writes:
>On 6/8/2017 11:56 AM, Gareth Owen wrote:
>> DFS <nospam@dfs.com> writes:
>
>I want to check the Path env variable for the existence of a string:
>
>\GNU\Win32\bin
>
>
>I counted the env variables:
>
>int envars=0;
>while (*env!=NULL) {*env++;envars++;}
>printf("%d\n",envars);
>65
>
>But then I can't go back and reference the values in env[] again because
>the pointer has moved to the end of the array (or past it?).
>
>What would you suggest?
>
>1) can I reset the pointer back to the beginning of env[]? How?
>2) make a copy of the env[] array and use it? How do I make a copy?
>3) can I create a new pointer pointing back to the beginning of env[]? How?
#include <stdio.h>
int main(int argc, const char *argv[], const char *env[])
{
const char **ep = env;
unsigned count;
for (count=0; *ep != NULL; ep++, count++) ;
printf("%u\n",count);
return(0);
}
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2017-06-08 12:43 -0400 |
| Message-ID | <ohbuk2$p49$1@dont-email.me> |
| In reply to | #111831 |
DFS wrote:
> On 6/8/2017 11:56 AM, Gareth Owen wrote:
>> DFS <nospam@dfs.com> writes:
>>
>>> int main(int argc, char *argv[], char *env[])
>>> {
>>> printf("%d\n",sizeof(env)/sizeof(env[0]));
>>> return(0);
>>> )
>>>
>>> Output is 1.
>>>
>>> Why?
>>
>> Anything that looks like an array object - when used in the argument
>> list of a function, is not an array object, but "decays" into a pointer.
>>
>> so in
>>
>> int foo(char *arr1[12])
>> {
>> char *arr2[12];
>> char **arr3;
>> }
>>
>> arr1 and arr3 have the same type, even though
>> arr1 and arr2 have the same declaration.
>>
>> A misfeature, but an explicable one.
>
> Gotcha
>
>
>> There is no way to obtain the size of arr1 in foo() without passing it
>> in explicitly (or counting them using a sentinel such as NULL to mark
>> the end, as is done with environment variables)
>
> I want to check the Path env variable for the existence of a string:
>
> \GNU\Win32\bin
>
>
> I counted the env variables:
>
> int envars=0;
> while (*env!=NULL) {*env++;envars++;}
> printf("%d\n",envars);
> 65
>
> But then I can't go back and reference the values in env[] again because
> the pointer has moved to the end of the array (or past it?).
>
> What would you suggest?
>
> 1) can I reset the pointer back to the beginning of env[]? How?
By taking another approach.
You can either make a copy of env (the pointer), and walk through the array
using /that/, or
You can walk through the array using an index. Using your code (above) as an
example, this might look like...
int envars=0;
while (env[envars]!=NULL) {envars++;}
printf("%d\n",envars)
but, I'd probably write it something like...
int envars;
/* advance through env[] array, looking for NULL pointer */
for (envars = 0; env[envars] != NULL; ++envars) {/*NOP*/}
printf("%d\n",envars);
> 2) make a copy of the env[] array and use it? How do I make a copy?
That's doable, but not the brightest move. You don't need a copy.
The code to do this would be more complex than you have now.
> 3) can I create a new pointer pointing back to the beginning of env[]?
Using your code, above, you would do something like...
char **beginning;
int envars=0;
beginning = env; /* beginning points the start of env[] array */
while (*env!=NULL) {*env++;envars++;}
printf("%d\n",envars);
> How?
>
>
> Thanks
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-08 13:49 -0400 |
| Message-ID | <ohc2ha$7n2$1@dont-email.me> |
| In reply to | #111837 |
On 6/8/2017 12:43 PM, Lew Pitcher wrote:
> but, I'd probably write it something like...
>
> int envars;
>
> /* advance through env[] array, looking for NULL pointer */
> for (envars = 0; env[envars] != NULL; ++envars) {/*NOP*/}
>
> printf("%d\n",envars);
I just want to extract the Path env variable.
This code hangs. Am I misusing strncpy?
int envars=0;
char tmp[5];
for (envars = 0; env[envars] != NULL; ++envars)
{
strncpy(tmp,env[envars],5);
tmp[5]='\0';
if (strcmp(tmp,"Path=")==0)
{
printf("%d. %s\n", envars+1, env[envars]);
break;
}
}
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-08 13:58 -0400 |
| Message-ID | <42e3b033-99e2-d002-3b17-7314637f0095@verizon.net> |
| In reply to | #111847 |
On 06/08/2017 01:49 PM, DFS wrote:
> On 6/8/2017 12:43 PM, Lew Pitcher wrote:
>
>
>> but, I'd probably write it something like...
>>
>> int envars;
>>
>> /* advance through env[] array, looking for NULL pointer */
>> for (envars = 0; env[envars] != NULL; ++envars) {/*NOP*/}
>>
>> printf("%d\n",envars);
>
>
> I just want to extract the Path env variable.
>
> This code hangs. Am I misusing strncpy?
No, you're misusing tmp.
> int envars=0;
> char tmp[5];
> for (envars = 0; env[envars] != NULL; ++envars)
> {
> strncpy(tmp,env[envars],5);
> tmp[5]='\0';
You only declared tmp as having 5 elements: tmp[0], tmp[1], tmp[2],
tmp[3], and tmp[4]. There is no such object as tmp[5]. Increase the size
to 6, and your code should work (note: I'm far more reliable when I say
"I see a defect" than when I say "I see no defects").
> if (strcmp(tmp,"Path=")==0)
> {
> printf("%d. %s\n", envars+1, env[envars]);
> break;
> }
> }
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-08 14:45 -0400 |
| Message-ID | <ohc5q2$jn7$2@dont-email.me> |
| In reply to | #111849 |
On 6/8/2017 1:58 PM, James R. Kuyper wrote:
> On 06/08/2017 01:49 PM, DFS wrote:
>> This code hangs. Am I misusing strncpy?
>
> No, you're misusing tmp.
>
>> int envars=0;
>> char tmp[5];
>> for (envars = 0; env[envars] != NULL; ++envars)
>> {
>> strncpy(tmp,env[envars],5);
>> tmp[5]='\0';
>
> You only declared tmp as having 5 elements: tmp[0], tmp[1], tmp[2],
> tmp[3], and tmp[4]. There is no such object as tmp[5]. Increase the size
> to 6, and your code should work
And indeed it does! Suhweet!
> (note: I'm far more reliable when I say
> "I see a defect" than when I say "I see no defects").
Thanks for those eagle eyes!
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-08 12:10 -0700 |
| Message-ID | <lnmv9ii9dd.fsf@kst-u.example.com> |
| In reply to | #111847 |
DFS <nospam@dfs.com> writes:
> On 6/8/2017 12:43 PM, Lew Pitcher wrote:
>> but, I'd probably write it something like...
>>
>> int envars;
>>
>> /* advance through env[] array, looking for NULL pointer */
>> for (envars = 0; env[envars] != NULL; ++envars) {/*NOP*/}
>>
>> printf("%d\n",envars);
>
>
> I just want to extract the Path env variable.
> This code hangs. Am I misusing strncpy?
>
> int envars=0;
> char tmp[5];
> for (envars = 0; env[envars] != NULL; ++envars)
> {
> strncpy(tmp,env[envars],5);
> tmp[5]='\0';
Apart from the fact that you're assigning a value to the nonexisting
tmp[5] (which has already been covered), creating a copy of the initial
portion of the string is unnecessary. Just use strncmp().
And be careful with strncpy(); it's not just a "safer" version of
strcpy(). (Usually the best way to be careful with it is to avoid using
it.)
> if (strcmp(tmp,"Path=")==0)
> {
> printf("%d. %s\n", envars+1, env[envars]);
> break;
> }
> }
On Unix-like systems, there's an environment variable named "PATH", not
"Path".
I'm not sure about Windows. As I recall it does use a similarly named
environment variable, but a lot of things in Windows are
case-insensitive. I don't know whether you can rely on it being called
"Path" rather than, say, "path" or PATH".
And if your goal is to get the value of a particular environment
variable, I recommend the standard getenv() function.
--
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 | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-09 11:21 -0400 |
| Message-ID | <ohee7e$f5c$1@dont-email.me> |
| In reply to | #111857 |
On 6/8/2017 3:10 PM, Keith Thompson wrote:
> On Unix-like systems, there's an environment variable named "PATH", not
> "Path".
>
> I'm not sure about Windows. As I recall it does use a similarly named
> environment variable, but a lot of things in Windows are
> case-insensitive. I don't know whether you can rely on it being called
> "Path" rather than, say, "path" or PATH".
>
> And if your goal is to get the value of a particular environment
> variable, I recommend the standard getenv() function.
Any case of 'path' works on Windows:
getenv("Path")
getenv("path")
getenv("PATH")
getenv("pAtH")
You and jak (in another thread) mentioned getenv(). It's perfect:
test if(strstr(getenv("Path"),"string") against NULL
Thanks for your help.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-06-09 16:23 +0100 |
| Message-ID | <oheeb7$eu4$1@dont-email.me> |
| In reply to | #111857 |
On 08/06/17 20:10, Keith Thompson wrote: > And be careful with strncpy(); it's not just a "safer" version of > strcpy(). In fact, it's not /even/ a "safer" version of strcpy(). > (Usually the best way to be careful with it is to avoid using > it.) Legitimate uses of strncpy are indeed rare. As you hint, however, we lack a proof that they do not exist. -- 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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-09 11:48 -0400 |
| Message-ID | <b3cd0b00-fc9b-cd50-6476-b31e66c44882@verizon.net> |
| In reply to | #111882 |
On 06/09/2017 11:23 AM, Richard Heathfield wrote: > On 08/06/17 20:10, Keith Thompson wrote: >> And be careful with strncpy(); it's not just a "safer" version of >> strcpy(). > > In fact, it's not /even/ a "safer" version of strcpy(). > >> (Usually the best way to be careful with it is to avoid using >> it.) > > Legitimate uses of strncpy are indeed rare. As you hint, however, we > lack a proof that they do not exist. I've cited a case that comes up frequently in my own code which Keith conceded was an appropriate use. Had you forgotten it, or do you disagree? I have an output file format that I'm not free to modify, which contains fixed-length text fields. The text that should be placed in many of those fields is not guaranteed to be small enough to fit, in which case I'm permitted to truncate it. Since fixed width of the fields is documented, they don't need null termination, and we want to lose as little text as possible to truncation. Therefore, if the field is, for instance, 40 characters long, and the input is 50 characters long, I put the 40th character from the input source into field[39], rather than '\0'. When reading such fields, I never assume that they're null terminated: I read them into, for instance, the first 40 bytes of a 41-byte array, and then execute field[40]='\0' before passing them to any routine that expects null-termination. I frequently need to confirm that two different runs of my program displayed only the expected differences (if any) in the output file. The tools I have available for examining the contents of these files look at the entire length of the fixed-length text fields, not just the part before the terminating null character (if there is one). As a result, if I don't pay attention to what's put into the field after the terminating null character, it's likely to contain garbage, and most importantly, it's likely to contain different garbage during different runs of the program, producing spurious indications that the files differ. Therefore, if the input is 30 characters long, and the output is 40 characters, I want the last 10 bytes to all consistently contain '\0', to make it easier to compare the files. Do you think this is an appropriate context for using strncpy()? It certainly seems that way to me. The first time I described it, Keith said that it seemed almost tailor-made for strncpy().
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-06-09 16:53 +0100 |
| Message-ID | <oheg3n$m2f$1@dont-email.me> |
| In reply to | #111885 |
On 09/06/17 16:48, James R. Kuyper wrote: > On 06/09/2017 11:23 AM, Richard Heathfield wrote: >> On 08/06/17 20:10, Keith Thompson wrote: >>> And be careful with strncpy(); it's not just a "safer" version of >>> strcpy(). >> >> In fact, it's not /even/ a "safer" version of strcpy(). >> >>> (Usually the best way to be careful with it is to avoid using >>> it.) >> >> Legitimate uses of strncpy are indeed rare. As you hint, however, we >> lack a proof that they do not exist. > > I've cited a case that comes up frequently in my own code which Keith > conceded was an appropriate use. Had you forgotten it, I didn't see it. I've recently done a catch-up "Mark All As Read". Okay, so we have the opposite - an existence proof. Fine by me. :-) > or do you disagree? No, of course not. But I would still maintain that the number of legitimate applications of strncpy is perhaps somewhat limited in comparison to strcpy or even memcpy. > I have an output file format that I'm not free to modify, which contains > fixed-length text fields. The text that should be placed in many of > those fields is not guaranteed to be small enough to fit, in which case > I'm permitted to truncate it. Since fixed width of the fields is > documented, they don't need null termination, and we want to lose as > little text as possible to truncation. Therefore, if the field is, for > instance, 40 characters long, and the input is 50 characters long, I put > the 40th character from the input source into field[39], rather than > '\0'. When reading such fields, I never assume that they're null > terminated: I read them into, for instance, the first 40 bytes of a > 41-byte array, and then execute field[40]='\0' before passing them to > any routine that expects null-termination. > > I frequently need to confirm that two different runs of my program > displayed only the expected differences (if any) in the output file. The > tools I have available for examining the contents of these files look at > the entire length of the fixed-length text fields, not just the part > before the terminating null character (if there is one). As a result, if > I don't pay attention to what's put into the field after the terminating > null character, it's likely to contain garbage, and most importantly, > it's likely to contain different garbage during different runs of the > program, producing spurious indications that the files differ. > Therefore, if the input is 30 characters long, and the output is 40 > characters, I want the last 10 bytes to all consistently contain '\0', > to make it easier to compare the files. Hmmm. If you want my advice, use strncpy. I'm surprised you didn't think of it yourself. It's almost tailor-made for this kind of thing. -- 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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-09 12:18 -0400 |
| Message-ID | <074e99ae-c55d-ae8a-c116-458fea076c79@verizon.net> |
| In reply to | #111887 |
On 06/09/2017 11:53 AM, Richard Heathfield wrote: > On 09/06/17 16:48, James R. Kuyper wrote: >> On 06/09/2017 11:23 AM, Richard Heathfield wrote: >>> On 08/06/17 20:10, Keith Thompson wrote: >>>> And be careful with strncpy(); it's not just a "safer" version of >>>> strcpy(). >>> >>> In fact, it's not /even/ a "safer" version of strcpy(). >>> >>>> (Usually the best way to be careful with it is to avoid using >>>> it.) >>> >>> Legitimate uses of strncpy are indeed rare. As you hint, however, we >>> lack a proof that they do not exist. >> >> I've cited a case that comes up frequently in my own code which Keith >> conceded was an appropriate use. Had you forgotten it, > > I didn't see it. I've recently done a catch-up "Mark All As Read". I've explained it several times during the past couple of decades, but not recently. I was challenging your long-term memory, not your short term. I am, incidentally, in no position to criticize anyone else's memory, and that wasn't meant as criticism. > Okay, so we have the opposite - an existence proof. Fine by me. :-) > >> or do you disagree? > > No, of course not. But I would still maintain that the number of > legitimate applications of strncpy is perhaps somewhat limited in > comparison to strcpy or even memcpy. Oh, that's certainly the case.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-06-09 17:28 +0100 |
| Message-ID | <ohei4c$st4$1@dont-email.me> |
| In reply to | #111889 |
On 09/06/17 17:18, James R. Kuyper wrote: > On 06/09/2017 11:53 AM, Richard Heathfield wrote: >> On 09/06/17 16:48, James R. Kuyper wrote: >>> On 06/09/2017 11:23 AM, Richard Heathfield wrote: >>>> On 08/06/17 20:10, Keith Thompson wrote: >>>>> And be careful with strncpy(); it's not just a "safer" version of >>>>> strcpy(). >>>> >>>> In fact, it's not /even/ a "safer" version of strcpy(). >>>> >>>>> (Usually the best way to be careful with it is to avoid using >>>>> it.) >>>> >>>> Legitimate uses of strncpy are indeed rare. As you hint, however, we >>>> lack a proof that they do not exist. >>> >>> I've cited a case that comes up frequently in my own code which Keith >>> conceded was an appropriate use. Had you forgotten it, >> >> I didn't see it. I've recently done a catch-up "Mark All As Read". > > I've explained it several times during the past couple of decades, but > not recently. I was challenging your long-term memory, not your short > term. My long-term memory is a curate's egg - good in parts. > I am, incidentally, in no position to criticize anyone else's > memory, and that wasn't meant as criticism. I didn't take it as criticism, uh, uh, Keith. No, not Keith. Um... -- 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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-09 09:12 -0700 |
| Message-ID | <lna85hi1i4.fsf@kst-u.example.com> |
| In reply to | #111885 |
"James R. Kuyper" <jameskuyper@verizon.net> writes:
> On 06/09/2017 11:23 AM, Richard Heathfield wrote:
>> On 08/06/17 20:10, Keith Thompson wrote:
>>> And be careful with strncpy(); it's not just a "safer" version of
>>> strcpy().
>> In fact, it's not /even/ a "safer" version of strcpy().
Agreed.
>>> (Usually the best way to be careful with it is to avoid using
>>> it.)
>>
>> Legitimate uses of strncpy are indeed rare. As you hint, however, we
>> lack a proof that they do not exist.
>
> I've cited a case that comes up frequently in my own code which Keith
> conceded was an appropriate use. Had you forgotten it, or do you disagree?
I believe Richard was acknowledging the possible existence of cases
where using strncpy is legitimate.
> I have an output file format that I'm not free to modify, which contains
> fixed-length text fields. The text that should be placed in many of
> those fields is not guaranteed to be small enough to fit, in which case
> I'm permitted to truncate it. Since fixed width of the fields is
> documented, they don't need null termination, and we want to lose as
> little text as possible to truncation.
[snip]
Yes, that's just the (somewhat rare) kind of data format that strncpy is
designed to work with.
I might as well post this link again:
http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html
--
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]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web