I have a CSV file containing data such as
value;name;test;etc
which I'm trying to split by using strtok(string, ";"). However, this file can contain zero-length data, like this:
value;;test;etc
which strtok() skips. Is there a way I can avoid strtok from skipping zero-length data like this?
A possible alternative is to use the BSD function strsep() instead of strtok(), if available.
From the man page:
The strsep() function is intended as a replacement for the strtok()
function. While the strtok() function should be preferred for
portability reasons (it conforms to ISO/IEC 9899:1990 ("ISO C90"))
it is unable to handle empty fields, i.e., detect fields delimited by
two adjacent delimiter characters, or to be used for more than a
single string at a time. The strsep() function first appeared in
4.4BSD.
A simple example (also copied from that man page):
char *token, *string, *tofree;
tofree = string = strdup("value;;test;etc");
while ((token = strsep(&string, ";")) != NULL)
printf("token=%s\n", token);
free(tofree);
Output:
token=value
token=
token=test
token=etc
so empty fields are handled correctly.
Of course, as others already said, none of these simple tokenizer functions handles
delimiter inside quotation marks correctly, so if that is an issue, you should use
a proper CSV parsing library.
There is no way to make strtok() not behave this way. From man page:
A sequence of two or more contiguous delimiter bytes in the parsed
string is considered to be a single delimiter. Delimiter bytes at the
start or end of the string are ignored. Put another way: the tokens
returned by strtok() are always nonempty strings.
But what you can do is check the amount of '\0' characters before the token, since strtok() replaces all encountered tokens with '\0'. That way you'll know how many tokens were skipped. Source info:
This end of the token is automatically replaced by a null-character,
and the beginning of the token is returned by the function.
And a code sample to show what I mean.
char* aStr = ...;
char* ptr = NULL;
ptr = strtok (...);
char* back = ptr;
int count = -1;
do {
back--;
if (back <= aStr) break; // to protect against reads before aStr
count++;
} while (*back = '\0');
(written without ide or testing, may be an invalid implementation, but the idea stands).
No you can't.
From "man strtok":
A sequence of two or more contiguous delimiter characters in the
parsed string is considered to be a single delimiter. Delimiter
characters at the start or end of the string are ignored. Put
another way: the tokens returned by strtok() are always nonempty
strings.
You could also run into problems if your data contains the delimiter inside quotes or any other "escape".
I think the best solution is to get a CSV parsing library or write your own parsing function.
From recent experience, it looks like strtok() does not necessarily replace all delimiters with the end of string characters, but rather replaces the first delimiter it finds with an end of string character and skips the following delimiters but leaves them in place.
This means that in the nominal case (no zero-length strings before delimiters), every call to strtok() after the first call to strtok() will return a pointer to a string that begins after a \0 character.
In the case where strtok() reads zero-length strings between delimiters, strtok() will return a pointer to a string that begins after a delimiter character that has not been replaced with \0.
Here is my solution for finding out whether strtok() has skipped a zero-length string between delimiters.
// Previous code is needed to point strtok to a string and start ingesting from it.
char * field_string = strtok(NULL, ',');
// Note that this can't be done after the first call to strtok for a given buffer, since the previous character would be outside of the string's memory space.
if (*(field_string-1) == '\0') {
// no delimiters were skipped
} else {
// one or more delimiters were skipped
}
Related
I have the following query string
address=1234&port=1234&username=1234&password=1234&gamename=1234&square=1234&LOGIN=LOGIN
I am trying to parse it into different variables: address,port,username,password,gamename,square and command (which would hold LOGIN)
I was thinking of using strtok but I don't think it would work. How can I parse the string to capture the variables ?
P.S - some of the fields might be empty - no gamename provided or square
When parsing a sting that may contain an empty-field between delimiters, strtok cannot be used, because strtok will treat any number of sequential delimiters as a single delimiter.
So in your case, if the variable=values fields may also contain an empty-field between the '&' delimiters, you must use strsep, or other functions such as strcspn, strpbrk or simply strchr and a couple of pointers to work your way down the string.
The strsep function is a BSD function and may not be included with your C library. GNU includes strsep and it was envisioned as a replacement for strtok simply because strtok cannot handle empty-fields.
(If you do not have strsep available, you will simply need to keep a start and end pointer and use a function like strchr to locate each occurrence of '&' setting the end pointer to one before the delimiter and then obtaining the var=value information from the characters between start and end pointer, then updating both to point one past the delimiter and repeating.)
Here, you can use strsep with a delimiter of "&\n" to locate each '&' (the '\n' char included presuming the line was read from a file with a line-oriented input function such as fgets or POSIX getline). You can then simply call strtok to parse the var=value text from each token returned by strsep using "=" as the delimiter (the '\n' having already been removed from the last token when parsing with strsep)
An example inserting a specific empty-field for handling between "...gamename=1234&&square=1234...", could be as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
char array[] = "address=1234&port=1234&username=1234&password=1234"
"&gamename=1234&&square=1234&LOGIN=LOGIN",
*query = strdup (array), /* duplicate array, &array is not char** */
*tokens = query,
*p = query;
while ((p = strsep (&tokens, "&\n"))) {
char *var = strtok (p, "="),
*val = NULL;
if (var && (val = strtok (NULL, "=")))
printf ("%-8s %s\n", var, val);
else
fputs ("<empty field>\n", stderr);
}
free (query);
}
(note: strsep takes a char** parameter as its first argument and will modify the argument to point one past the delimiter, so you must preserve a reference to the start of the original allocated string (query above)).
Example Use/Output
$ ./bin/strsep_query
address 1234
port 1234
username 1234
password 1234
gamename 1234
<empty field>
square 1234
LOGIN LOGIN
(note: the conversion of "1234" to a numeric value has been left to you)
Look things over and let me know if you have further questions.
I have the following query string
address=1234&port=1234&username=1234&password=1234&gamename=1234&square=1234&LOGIN=LOGIN
I am trying to parse it into different variables: address,port,username,password,gamename,square and command (which would hold LOGIN)
I was thinking of using strtok but I don't think it would work. How can I parse the string to capture the variables ?
P.S - some of the fields might be empty - no gamename provided or square
When parsing a sting that may contain an empty-field between delimiters, strtok cannot be used, because strtok will treat any number of sequential delimiters as a single delimiter.
So in your case, if the variable=values fields may also contain an empty-field between the '&' delimiters, you must use strsep, or other functions such as strcspn, strpbrk or simply strchr and a couple of pointers to work your way down the string.
The strsep function is a BSD function and may not be included with your C library. GNU includes strsep and it was envisioned as a replacement for strtok simply because strtok cannot handle empty-fields.
(If you do not have strsep available, you will simply need to keep a start and end pointer and use a function like strchr to locate each occurrence of '&' setting the end pointer to one before the delimiter and then obtaining the var=value information from the characters between start and end pointer, then updating both to point one past the delimiter and repeating.)
Here, you can use strsep with a delimiter of "&\n" to locate each '&' (the '\n' char included presuming the line was read from a file with a line-oriented input function such as fgets or POSIX getline). You can then simply call strtok to parse the var=value text from each token returned by strsep using "=" as the delimiter (the '\n' having already been removed from the last token when parsing with strsep)
An example inserting a specific empty-field for handling between "...gamename=1234&&square=1234...", could be as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
char array[] = "address=1234&port=1234&username=1234&password=1234"
"&gamename=1234&&square=1234&LOGIN=LOGIN",
*query = strdup (array), /* duplicate array, &array is not char** */
*tokens = query,
*p = query;
while ((p = strsep (&tokens, "&\n"))) {
char *var = strtok (p, "="),
*val = NULL;
if (var && (val = strtok (NULL, "=")))
printf ("%-8s %s\n", var, val);
else
fputs ("<empty field>\n", stderr);
}
free (query);
}
(note: strsep takes a char** parameter as its first argument and will modify the argument to point one past the delimiter, so you must preserve a reference to the start of the original allocated string (query above)).
Example Use/Output
$ ./bin/strsep_query
address 1234
port 1234
username 1234
password 1234
gamename 1234
<empty field>
square 1234
LOGIN LOGIN
(note: the conversion of "1234" to a numeric value has been left to you)
Look things over and let me know if you have further questions.
Example Text:
bclk = /gsrpkg_te/gsrpkg/gsrdie/xxBCLK
I would like to ask question regarding to "strtok".Below is an example code with some doubts I have faced.
char *p4;
char *p5;
p4 = strtok (eqvline, "=");
p5 = strtok (NULL, ":");
if ( !strcmp (p4, "bclk") ) {
strcpy ( sa_de_bclk, p5 );
printf ( "[vTPSim] ---> bclk = %s.\n", p5);
}
From the above example text there is no ":"(colon) anywhere.For my understanding of strtok() when there is no the defined symbol is found NULL will be assigned as result.
However, why in this case even if there is no ":", p5 still have the assignment of "/gsrpkg_te/gsrpkg/gsrdie/xxBCLK".
Thanks for your helps.
For my understanding of strtok when there is no the defined symbol is found NULL will be assigned as result
Perhaps you are confusing strtok() with strchr() or strstr(). If none of the separator symbols is found in the remaining part of the string, then strtok() returns that remaining part (more precisely, a pointer to its first character). It may be the entire string if no delimiters could be found in it at all. Docs.
Quote from the docs for haters and deniers:
If no such byte is found, the current token extends to the end of the string pointed to by s1, and subsequent searches for a token shall return a null pointer.
Subsequent. Not immediately the call which couldn't find more delimiters, but the ones following it.
If first parameter is NULL, then strtok tries to get next token. Since first strtok call was strtok (eqvline, "=") with eqvline != NULL and token = the second call will find the next part which is /gsrpkg_te/gsrpkg/gsrdie/xxBCLK in your exmaple.
Maybe you should read this documentation of strtok http://www.cplusplus.com/reference/cstring/strtok/.
char * strtok ( char * str, const char * delimiters );
A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.
On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of last token as the new starting location for scanning.
When I look at you example, I would expect that p4 contains "bclk " not "bclk" as you didn't define the whitespace as delimiter. According to the doc, what you did on line 4 (p5 = ...) doesn't have a defined result as you changed delimiters between calls to strtok. I would expect it to use the first delimiters and therefore returning the rest of the string after "=". What it does...
Hope this helps
In the following program, strtok() works as expected in the major part but I just can't comprehend the reason behind one finding. I have read about strtok() that:
To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in delimiters (which becomes the beginning of the token). And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token.
Source: http://www.cplusplus.com/reference/cstring/strtok/
And as we know, strtok() places a \0 at the end of each token. But in the following program, the last delimiter is a dot(.), after which there is Toad between that dot and the quotation mark ("). Now the dot is a delimiter in my program, but there is no delimiter after Toad, not even a white space (which is a delimiter in my program). Please clear the following confusion arising from this premise:
Why is strtok() considering Toad as a token even though it is not between 2 delimiters? This is what I read about strtok() when it encounters a NULL character (\0):
Once the terminating null character of str has been found in a call to strtok, all subsequent calls to this function with a null pointer as the first argument return a null pointer.
Source: http://www.cplusplus.com/reference/cstring/strtok/
Nowhere does it say that once a null character is encountered,a pointer to the beginning of the token is returned (we don't even have a token here as we didn't get an end of the token as there was no delimiter character found after the scan begun from the beginning of the token (i.e. from 'T' of Toad), we only found a null character, not a delimiter). So why is the part between last delimiter and quotation mark of argument string considered a token by strtok()? Please explain this.
Code:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] =" Falcon,eagle-hawk..;buzzard,gull..pigeon sparrow,hen;owl.Toad";
char * pch=strtok(str," ;,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ;,.-");
}
return 0;
}
Output:
Falcon
eagle
hawk
buzzard
gull
pigeon
sparrow
hen
owl
Toad
The standard's specification of strtok (7.24.5.8) is pretty clear. In particular paragraph 4 (emphasis added by me) is directly relevant to the question, if I understand that correctly:
3 The first call in the sequence searches the string pointed to by s1 for the first character that is not contained in the current separator string pointed to by s2. If no such character is found, then there are no tokens in the string pointed to by s1 and the strtok function returns a null pointer. If such a character is found, it is the start of the first token.
4 The strtok function then searches from there for a character that is contained in the current separator string. If no such character is found, the current token extends to the end of the string pointed to by s1, and subsequent searches for a token will return a null pointer. If such a character is found, it is overwritten by a null character, which terminates the current token. The strtok function saves a pointer to the following character, from which the next search for a token will start.
In a call
char *where = strtok(string_or_NULL, delimiters);
the token (a pointer to which is) returned - if any - extends from the first non-delimiter character found from the starting position (inclusive) until the next delimiter character (exclusive), if one exists, or the end of the string, if no later delimiter character exists.
The linked description doesn't explicitly mention the case of a token extending until the end of the string, as opposed to the standard, so it is incomplete in that respect.
Going to the description in POSIX for strtok(), the description says:
char *strtok(char *restrict s1, const char *restrict s2);
A sequence of calls to strtok() breaks the string pointed to by s1 into a sequence of tokens, each of which is delimited by a byte from the string pointed to by s2. The first call in the sequence has s1 as its first argument, and is followed by calls with a null pointer as their first argument. The separator string pointed to by s2 may be different from call to call.
The first call in the sequence searches the string pointed to by s1 for the first byte that is not contained in the current separator string pointed to by s2. If no such byte is found, then there are no tokens in the string pointed to by s1 and strtok() shall return a null pointer. If such a byte is found, it is the start of the first token.
The strtok() function then searches from there for a byte that is contained in the current separator string. If no such byte is found, the current token extends to the end of the string pointed to by s1, and subsequent searches for a token shall return a null pointer. If such a byte is found, it is overwritten by a NUL character, which terminates the current token. The strtok() function saves a pointer to the following byte, from which the next search for a token shall start.
Note the second sentence of the third paragraph:
If no such byte is found, the current token extends to the end of the string pointed to by s1, and subsequent searches for a token shall return a null pointer.
This clearly states that in the example in the question, Toad is indeed a token. One way to think of it is that the list of delimiters always includes the NUL '\0' at the end of the delimiter string.
Having diagnosed that, note that strtok() is not a good function to use — it is not thread safe or reentrant. On Windows, you can use strtok_s() instead; on Unix, you can usually use strtok_r(). These are better functions because they don't store internally the pointer at which the search is to resume.
Because strtok() is not reentrant, you cannot call a function that uses strtok() from inside a function that itself uses strtok() while it is using strtok(). Also, any library function that uses strtok() must be clearly identified as doing so because it cannot be called from a function that is using strtok(). So, using strtok() makes life hard.
The other problem with the strtok() family of functions (and with strsep(), which is related) is that they overwrite the delimiter; you can't find out what the delimiter was after the tokenizer has tokenized the string. This can matter in some applications (such as parsing shell command lines; it matters whether the delimiter is a pipe or a semicolon or an ampersand (or ...). So shell parsers usually don't use strtok(), despite the number of questions on SO about shells where the parser does use strtok().
Generally, you should steer clear of plain strtok(), and it is up to you to decide whether strtok_r() or strtok_s() is appropriate for your purposes.
Because cplusplus.com isn't telling you the whole story. Cppreference.com has a better description.
Cplusplus.com also fails to mention that strtok is not thread-safe, and only documents the strtok function of the C++ programming language, whereas cppreference.com does mention the thread safety issue and documents the strtok functions of both the C and the C++ programming languages.
Are you perhaps just mis-reading the description?
Once the terminating null character of str has been found in a call to
strtok, all subsequent calls to this function with a null pointer
as the first argument return a null pointer.
Given 'subsequent', I'm reading this as every call to strtok after the one that discovered \0, not necessarily the current one itself. So, the definition is consistent with behavior (and with what you would expect from strtok).
strtok breaks a string to a sequence of tokens, separated by the given delimeters.
Delimeters only separate tokens, not necesarily terminate them on both side.
I am new to C and I am very much confused with the C strings. Following are my questions.
Finding last character from a string
How can I find out the last character from a string? I came with something like,
char *str = "hello";
printf("%c", str[strlen(str) - 1]);
return 0;
Is this the way to go? I somehow think that, this is not the correct way because strlen has to iterate over the characters to get the length. So this operation will have a O(n) complexity.
Converting char to char*
I have a string and need to append a char to it. How can i do that? strcat accepts only char*. I tried the following,
char delimiter = ',';
char text[6];
strcpy(text, "hello");
strcat(text, delimiter);
Using strcat with variables that has local scope
Please consider the following code,
void foo(char *output)
{
char *delimiter = ',';
strcpy(output, "hello");
strcat(output, delimiter);
}
In the above code,delimiter is a local variable which gets destroyed after foo returned. Is it OK to append it to variable output?
How strcat handles null terminating character?
If I am concatenating two null terminated strings, will strcat append two null terminating characters to the resultant string?
Is there a good beginner level article which explains how strings work in C and how can I perform the usual string manipulations?
Any help would be great!
Last character: your approach is correct. If you will need to do this a lot on large strings, your data structure containing strings should store lengths with them. If not, it doesn't matter that it's O(n).
Appending a character: you have several bugs. For one thing, your buffer is too small to hold another character. As for how to call strcat, you can either put the character in a string (an array with 2 entries, the second being 0), or you can just manually use the length to write the character to the end.
Your worry about 2 nul terminators is unfounded. While it occupies memory contiguous with the string and is necessary, the nul byte at the end is NOT "part of the string" in the sense of length, etc. It's purely a marker of the end. strcat will overwrite the old nul and put a new one at the very end, after the concatenated string. Again, you need to make sure your buffer is large enough before you call strcat!
O(n) is the best you can do, because of the way C strings work.
char delimiter[] = ",";. This makes delimiter a character array holding a comma and a NUL Also, text needs to have length 7. hello is 5, then you have the comma, and a NUL.
If you define delimiter correctly, that's fine (as is, you're assigning a character to a pointer, which is wrong). The contents of output won't depend on delimiter later on.
It will overwrite the first NUL.
You're on the right track. I highly recommend you read K&R C 2nd Edition. It will help you with strings, pointers, and more. And don't forget man pages and documentation. They will answer questions like the one on strcat quite clearly. Two good sites are The Open Group and cplusplus.com.
A "C string" is in reality a simple array of chars, with str[0] containing the first character, str[1] the second and so on. After the last character, the array contains one more element, which holds a zero. This zero by convention signifies the end of the string. For example, those two lines are equivalent:
char str[] = "foo"; //str is 4 bytes
char str[] = {'f', 'o', 'o', 0};
And now for your questions:
Finding last character from a string
Your way is the right one. There is no faster way to know where the string ends than scanning through it to find the final zero.
Converting char to char*
As said before, a "string" is simply an array of chars, with a zero terminator added to the end. So if you want a string of one character, you declare an array of two chars - your character and the final zero, like this:
char str[2];
str[0] = ',';
str[1] = 0;
Or simply:
char str[2] = {',', 0};
Using strcat with variables that has local scope
strcat() simply copies the contents of the source array to the destination array, at the offset of the null character in the destination array. So it is irrelevant what happens to the source after the operation. But you DO need to worry if the destination array is big enough to hold the data - otherwise strcat() will overwrite whatever data sits in memory right after the array! The needed size is strlen(str1) + strlen(str2) + 1.
How strcat handles null terminating character?
The final zero is expected to terminate both input strings, and is appended to the output string.
Finding last character from a string
I propose a thought experiment: if it were generally possible to find the last character
of a string in better than O(n) time, then could you not also implement strlen
in better than O(n) time?
Converting char to char*
You temporarily can store the char in an array-of-char, and that will decay into
a pointer-to-char:
char delimiterBuf[2] = "";
delimiterBuf[0] = delimiter;
...
strcat(text, delimiterBuf);
If you're just using character literals, though, you can simply use string literals instead.
Using strcat with variables that has local scope
The variable itself isn't referenced outside the scope. When the function returns,
that local variable has already been evaluated and its contents have already been
copied.
How strcat handles null terminating character?
"Strings" in a C are NUL-terminated sequences of characters. Both inputs to
strcat must be NUL-terminated, and the result will be NUL-terminated. It
wouldn't be useful for strcat to write an extra NUL-byte to the result if it
doesn't need to.
(And if you're wondering what if the input strings have multiple trailing
NUL bytes already, I propose another thought experiment: how would strcat know
how many trailing NUL-bytes there are in a string?)
BTW, since you tagged this with "best-practices", I'll also recommend that you take care not to write past the end of your destination buffers. Typically this means avoiding strcat and strcpy (unless you've already checked that the input strings won't overflow the destination) and using safer versions (e.g. strncat. Note that strncpy has its own pitfalls, so that's a poor substitute. There also are safer versions that are non-standard, such as strlcpy/strlcat and strcpy_s/strcat_s.)
Similarly, functions like your foo function always should take an additional argument specifying what the size of the destination buffer is (and documentation should make it explicitly clear whether that size accounts for a NUL terminator or not).
How can I find out the last character
from a string?
Your technique with str[strlen(str) - 1] is fine. As pointed out, you should avoid repeated, unnecessary calls to strlen and store the results.
I somehow think that, this is not the
correct way because strlen has to
iterate over the characters to get the
length. So this operation will have a
O(n) complexity.
Repeated calls to strlen can be a bane of C programs. However, you should avoid premature optimization. If a profiler actually demonstrates a hotspot where strlen is expensive, then you can do something like this for your literal string case:
const char test[] = "foo";
sizeof test // 4
Of course if you create 'test' on the stack, it incurs a little overhead (incrementing/decrementing stack pointer), but no linear time operation involved.
Literal strings are generally not going to be so gigantic. For other cases like reading a large string from a file, you can store the length of the string in advance as but one example to avoid recomputing the length of the string. This can also be helpful as it'll tell you in advance how much memory to allocate for your character buffer.
I have a string and need to append a
char to it. How can i do that? strcat
accepts only char*.
If you have a char and cannot make a string out of it (char* c = "a"), then I believe you can use strncat (need verification on this):
char ch = 'a';
strncat(str, &ch, 1);
In the above code,delimiter is a local
variable which gets destroyed after
foo returned. Is it OK to append it to
variable output?
Yes: functions like strcat and strcpy make deep copies of the source string. They don't leave shallow pointers behind, so it's fine for the local data to be destroyed after these operations are performed.
If I am concatenating two null
terminated strings, will strcat
append two null terminating characters
to the resultant string?
No, strcat will basically overwrite the null terminator on the dest string and write past it, then append a new null terminator when it's finished.
How can I find out the last character from a string?
Your approach is almost correct. The only way to find the end of a C string is to iterate throught the characters, looking for the nul.
There is a bug in your answer though (in the general case). If strlen(str) is zero, you access the character before the start of the string.
I have a string and need to append a char to it. How can i do that?
Your approach is wrong. A C string is just an array of C characters with the last one being '\0'. So in theory, you can append a character like this:
char delimiter = ',';
char text[7];
strcpy(text, "hello");
int textSize = strlen(text);
text[textSize] = delimiter;
text[textSize + 1] = '\0';
However, if I leave it like that I'll get zillions of down votes because there are three places where I have a potential buffer overflow (if I didn't know that my initial string was "hello"). Before doing the copy, you need to put in a check that text is big enough to contain all the characters from the string plus one for the delimiter plus one for the terminating nul.
... delimiter is a local variable which gets destroyed after foo returned. Is it OK to append it to variable output?
Yes that's fine. strcat copies characters. But your code sample does no checks that output is big enough for all the stuff you are putting into it.
If I am concatenating two null terminated strings, will strcat append two null terminating characters to the resultant string?
No.
I somehow think that, this is not the correct way because strlen has to iterate over the characters to get the length. So this operation will have a O(n) complexity.
You are right read Joel Spolsky on why C-strings suck. There are few ways around it. The ways include either not using C strings (for example use Pascal strings and create your own library to handle them), or not use C (use say C++ which has a string class - which is slow for different reasons, but you could also write your own to handle Pascal strings more easily than in C for example)
Regarding adding a char to a C string; a C string is simply a char array with a nul terminator, so long as you preserve the terminator it is a string, there's no magic.
char* straddch( char* str, char ch )
{
char* end = &str[strlen(str)] ;
*end = ch ;
end++ ;
*end = 0 ;
return str ;
}
Just like strcat(), you have to know that the array that str is created in is long enough to accommodate the longer string, the compiler will not help you. It is both inelegant and unsafe.
If I am concatenating two null
terminated strings, will strcat append
two null terminating characters to the
resultant string?
No, just one, but what ever follows that may just happen to be nul, or whatever happened to be in memory. Consider the following equivalent:
char* my_strcat( char* s1, const char* s2 )
{
strcpy( &str[strlen(str)], s2 ) ;
}
the first character of s2 overwrites the terminator in s1.
In the above code,delimiter is a local
variable which gets destroyed after
foo returned. Is it OK to append it to
variable output?
In your example delimiter is not a string, and initialising a pointer with a char makes no sense. However if it were a string, the code would be fine, strcat() copies the data from the second string, so the lifetime of the second argument is irrelevant. Of course you could in your example use a char (not a char*) and the straddch() function suggested above.