patterncMinorCanonical
Pointer version of strcat()
Viewed 0 times
versionpointerstrcat
Problem
Seems to work fine, I guess it won't work if the destination array's size is not defined by a macro, but a variable or something else, I thought about adding a third argument which is the size and let the user enter it, but that might be worse.
#include
#include
#include
#define MAX_SIZE 100
char *ptr_str_cat(char *dest, const char* src){
char *original;
original = dest;
if((strlen(dest) + strlen(src)) > MAX_SIZE){
puts("The source string is too big for the destination");
exit(EXIT_FAILURE);
}
dest = strchr(dest, '\0');
*dest = '0';
while((*dest++ = *src++) != '\0'){
; /*do nothing*/
}
return original;
}
int main(void){
char dest [MAX_SIZE];
char source [MAX_SIZE];
puts("Enter the destination string");
fgets(dest, sizeof(dest), stdin);
dest[strlen(dest) -1 ] = '\0'; /*Remove trailing newline*/
puts("Enter the source string");
fgets(source, sizeof(source), stdin);
printf("%s", ptr_str_cat(dest, source));
return 0;
}Solution
ptr_str_cat function:
-
The ISO C90
Edit: See @JS1's answer to take a look at the approach of
-
If you want to completely leave out library function calls, you could even replace the
-
There is no need to explicitly overwrite the null terminator in
-
The
-
This is what you would come up with:
You don't even need to include `
-
The ISO C90
strcat requires the string dest to have sufficient space to hold the result of the concatenation. On the other hand strncat takes another argument size_t n and won't copy more then n characters to dest (+ the null terminator). You should definitely consider to implement one of these approaches, since the macro seems rather randomly chosen (you don't know whether dest is big enough to hold src). Edit: See @JS1's answer to take a look at the approach of
strncat. He also has a good catch with the Off-by-one-error.-
If you want to completely leave out library function calls, you could even replace the
strchr call with a simple loop. while(*dest != '\0')
dest++;-
There is no need to explicitly overwrite the null terminator in
dest. It will get overwritten by the contents of src and in the case of an empty src the null terminator is actually wanted. -
The
while-loop doesn't require extra curly braces. The NULL statement is sufficient.while((*dest++ = *src++) != '\0')
; /* Intentionally left blank */-
This is what you would come up with:
char *ptr_str_cat(char *dest, const char* src){
char *original = dest
while(*dest != '\0')
dest++;
while((*dest++ = *src++) != '\0')
; /* Intentionally left blank */
return original;
}You don't even need to include `
using this implementation (since you don't use exit anymore).
main function:
- Minor:
dest[strlen(dest) - 1] = '\0'; will overwrite valid input (not the '\n'), when the first input line is longer than MAX_SIZE.
EDIT:
Good question regarding how to handle large input. I think this somehow depends on the target. I'd say our goal here is to create a piece of software, which is able to read in two strings (of any unknown size, separated by '\n') and later on have a pointer to the concatenation of these two strings.
One approach would be to allocate MAX_SIZE bytes of memory using malloc. Using fgets we fill the allocated memory and each time the string does not end on '\n' we reallocate MAX_SIZE` more bytes and read in more characters. This will work until you run out of memory.Code Snippets
while(*dest != '\0')
dest++;while((*dest++ = *src++) != '\0')
; /* Intentionally left blank */char *ptr_str_cat(char *dest, const char* src){
char *original = dest
while(*dest != '\0')
dest++;
while((*dest++ = *src++) != '\0')
; /* Intentionally left blank */
return original;
}Context
StackExchange Code Review Q#159735, answer score: 4
Revisions (0)
No revisions yet.