No, there is a comp.std.c group for discussing the standard *itself*,
not for discussing code conforming with the standard.
Understood.
I mostly agree. The problem is that in some cases, you have to know a fair
bit about a platform to know whether something is an error or not.
Consider the UNIX faq:
if (fd = open("foo", O_RDWR) != -1) {
write(fd, "hello!\n", 7);
}
Why does this print hello instead of writing it to a file?
It turns out that you can't easily answer this if you don't know a
fair bit about Unix, but you don't need to know anything about Unix
to guess at the problem.
Basically... I figure people are justified in not trying to answer such
questions, or suggesting that you'll get a better answer in a
platform-specific group. But I also try to answer them when I notice
a generic-C answer.
I understand. I would consider that example off topic because
understanding it depends entirely on knowing how "open" and "write"
operate. I'll give an example of a problem I had that illustrates
what I mean. It has non-standard calls in it, but I believe the
problem can be ascertained in spite of them.
Please note that I'm posting this code only as an illustration of my
view of on topic code with OS specific calls. It has been corrected
since and I did perform a Bull Shannon when I discovered the obvious
fault.
The purpose of the code is to take a MS wide "multistring" (a single
character array with zeros delimiting the individual strings and a
single zero to terminate the multistring), separate it into its
individual strings and return them as an array of non-wide strings. It
returns an error status and the number of strings returned (via
stringcount). It is up to the caller to free the strings and the
array itself. A function is provided for that.
The definitions for the error messages (and DWORD) are not included
here, but I believe their meaning is clear.
DWORD MultistringWToStringArray(const wchar_t *multistring,
char **stringarray, int *stringcount)
{
size_t msi, wsl, asl;
size_t sl;
char **temp;
char *astring;
wchar_t *wstring;
DWORD ret = NO_ERROR;
/* returns the length in characters of the longest string in
multistring */
sl = FindLongestStringLengthInMultistringW(multistring);
if(sl == 0)
return ST_EMPTY_MULTISTRING;
/* allocate temp space for each individual wide string */
wstring = malloc(sl * sizeof(wchar_t));
if(wstring == NULL)
{
return ST_OUT_OF_MEMORY;
}
stringarray = NULL;
*stringcount = 0;
msi = 0;
while(multistring[msi] != 0)
{
/* allocate space in array for next string pointer */
temp = realloc(stringarray, (*stringcount + 1) *
sizeof(stringarray));
if(temp == NULL)
{
FreeStringArray(stringarray, *stringcount);
ret = ST_OUT_OF_MEMORY;
break;
}
else
stringarray = temp;
/* dstrcpylW is a library function of mine that is a combination of
the wide versions of strcpy and strlen. It copies a wide string from,
in this case, multistring+msi to wstring. It returns the length of
the destination string in characters (wstring) eliminating the need to
traverse wstring twice */
wsl = dstrcpylW(wstring, multistring + msi) + 1;
msi += (wsl * sizeof(wchar_t));
/* Windows API call that converts the wide string to an ASCII string.
if the ASCII string pointer (astring) is NULL, it returns the size
needed to hold the ASCII string */
astring = NULL;
asl = WideCharToMultiByte(CP_ACP, 0, wstring, -1, astring, 0,
NULL, NULL);
if(asl == FALSE)
{
/* WideCharToMultiByte failed, get the error code and clean up */
ret = GetLastError();
FreeStringArray(stringarray, *stringcount);
break;
}
/* else, WideCharToMultiByte returns the length of astring, including
ending zero. */
astring = malloc(asl);
if(astring == NULL)
{
FreeStringArray(stringarray, *stringcount);
ret = ST_OUT_OF_MEMORY;
break;
}
/* Windows API call that converts the wide string wstring to an ASCII
string astring */
WideCharToMultiByte(CP_ACP, 0, wstring, -1, astring, asl,
NULL, NULL);
/* allocate space for the string and copy it to the array */
stringarray[*stringcount] = malloc(asl);
strcpy(stringarray[*stringcount], astring);
free(astring);
(*stringcount)++;
msi++;
}
free(wstring);
return ret;
}
void FreeStringArray(char **stringarray, int stringcount)
{
int i;
for(i = 0; i < stringcount; i++)
free(stringarray
);
free(stringarray);
}
I won't state the error here just to see if I am correct and it can
be easily determined, even with non-standard code.
DSF