strcat/access question resolution
Jim Klavetter
jjk at suns.UMD.EDU
Wed Oct 11 13:55:44 AEST 1989
I didn't know if it was appropriate to post a summary since there
was more than one reply I received which made me think that this was a
group only for C gurus, but a recent question persuaded me to
summarize what I learned. Here is the original code segment:
>if((home=getenv("HOME"))==(char *) 0)
> perror("GETENV\n");
>printf("%s:\n", home);
>printf("%s:\n", strcpy(string,strcat(home, "/astro/data/obs.list")));
>printf("%s:\n", string);
>printf("%d:\n", access(string, 4));
>printf("%d:\n", access(strcat(home, "/astro/data/obs.list"), 4));
And the associated output:
>/a/jjk:
>/a/jjk/astro/data/obs.list:
>/a/jjk/astro/data/obs.list:
>0:
>-1:
A note on what was NOT included in the original posting: the
declaration
char *home, *getenv();
There are two separate and fatal bugs in the code.
1. (This is the one similar to what has recently been "discussed" in
this group.) The variable "home" is a pointer to a char, and thus,
when I use "home" in the first strcat, I am possibly munging other
environmental variables. I had not allocated storage for home. Of
courses, the answer is to copy to what "home" is pointing to another
variable (correct english, it just sounds funny) and then strcat it.
And note that the other variable has to be large enough to contain
both the *home string and the "/astro/data/obs.list" string.
2. Remember that strcat returns a pointer to the concatenated string.
Thus, the first strcat made the appropriate string (although see
above: for the moment let's assume that home was declared as a large
array of characters or some other such fix). I print it out and
everything looks ok, so I do the same command impeded in the "access"
function. What did I do? I appended the suffix TWICE! Needless to
say, it did not find the required file and access returned -1. A
number of people pointed out that my code was very FORTRAN-like or
some other language in which strings are actual types. I grew up on C
so I wasn't making this particular mistake, but it is a good point to
keep in mind. I just made the mistake of not remembering that the
string functions I was using returned pointers and didn't care about
how I had allocated the character arrays.
As a side note, two people mentioned that instead of strcat and strcpy
I could use sprintf. Again, storage must be allocated appropriately,
but this IS another solution.
There are two other minor points about the code:
i. There is no need to cast the 0 in the getenv function.
ii. getenv() doesn't return an errno and thus the perror() is not
relevant.
I knew both of these things and changed my code from the original
because billions and billions in the civilized world were going to
look at me and I wanted to make it as simple as possible. As for the
cast, it is, in fact, correct. I am not certain if NULL would be
appropriate ANSI C or that all compilers would treat it appropriately
(no need to send me e-mail, comment on the net if you wish). As for
the perror(), I had my own error function but did not wish to explain
it so I substituted perror(). Very good of all of you who noticed,
though.
As a general comment, I would suggest that everyone try and find some
way to find the bug without posting to the net, but if someone does
post to the net a trivial question, don't flame at that person, either
answer it or not. There is no reason to be obnoxious. Unfortunately,
I am in the unenviable position that I know more C in my group than
anyone else, so I am at a bit of a lose if I have trouble. I do feel
appropriately ashamed for my oversight, but I hope that everyone can
post if they feel they have a question that they or their peers cannot
answer.
Further, I would like to thank all of those who responded to me, even
the less than friendly replies had the correct identification of the
problem. Thanks all.
jjk
More information about the Comp.lang.c
mailing list