strcat concat a char onto a string? - c

Using GDB, I find I get a segmentation fault when I attempt this operation:
strcat(string,&currentChar);
Given that string is initialized as
char * string = "";
and currentChar is
char currentChar = 'B';
Why does this result in a segmentation fault?
If strcat can't be used for this, how else can I concat a char onto a string?

As responded by others, &currentChar is a pointer to char or char*, but a string in C is char[] or const char*.
One way to use strcat to concatenate a char to string is creating a minimum string and use it to transform a char into string.
Example:
Making a simple string, with only 1 character and the suffix '\0';
char cToStr[2];
cToStr[1] = '\0';
Applying to your question:
char * string = "";
char currentChar = 'B';
cToStr will assume the string "B":
cToStr[0] = currentChar;
And strcat will work!
strcat ( string, cToStr );

Because &currentChar is not a string, it doesn't finish with \0 character. You should define B as char *currentChar = 'B';. Also according to http://www.cplusplus.com/reference/clibrary/cstring/strcat string should have enough space to hold the result string (2 bytes in this case), but it is only 1 byte.
Or if you want to use char then you can do something like (depending of your code):
char string[256];
...
char currentChar = 'B';
size_t cur_len = strlen(string);
if(cur_len < 254) {
string[cur_len] = currentChar;
string[cur_len+1] = '\0';
}
else
printf("Not enough space");

I think the simplest method (not efficient) would be sprintf
sprintf(str, "%s%c", str, chr);

strcat() takes two '\0'-terminated strings. When you pass the address of a character, the routine will look at the memory that follows the character, looking for the terminator.
Since you don't know what that memory even refers to, you should expect problems when your code accesses it.
In addition to that, your string argument does not have room to have any characters appended to it. Where is that memory written to? It will attempt to write past the end of the memory associated with this string.

Both of the strings must be null-terminated. A single char isn't null terminated, so it's undefined when strcat will stop concatenating characters to the end. Also, string must contain at least enough space for both the original string and resultant string.
This works:
char string[10] = "";
char* currentChar = "B";
strcat(string, currentChar);

We know that currentChar = 'B'.
This can be done
strcat(string, "B\0");
If we know currentChar will be hardcoded as 'B', this would be a good approach.
It also removes the need for char currentChar = 'B';

The first argument of strcat must have enough space to hold the rest of the string. "" is a constant string and as such GCC does not allocate space.
Make it an array with enough space:
char buf[1024];
strcat(buf, "");
strcat(buf, "B");

Related

C program to search only files in a given folder [duplicate]

Why does this code produce runtime issues:
char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");
but this doesn't?
char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");
strcat will look for the null-terminator, interpret that as the end of the string, and append the new text there, overwriting the null-terminator in the process, and writing a new null-terminator at the end of the concatenation.
char stuff[100]; // 'stuff' is uninitialized
Where is the null terminator? stuff is uninitialized, so it might start with NUL, or it might not have NUL anywhere within it.
In C++, you can do this:
char stuff[100] = {}; // 'stuff' is initialized to all zeroes
Now you can do strcat, because the first character of 'stuff' is the null-terminator, so it will append to the right place.
In C, you still need to initialize 'stuff', which can be done a couple of ways:
char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
// so 'stuff' is effectively ""
strcpy(stuff, "hi "); // this initializes 'stuff' if it's not already.
In the first case, stuff contains garbage. strcat requires both the destination and the source to contain proper null-terminated strings.
strcat(stuff, "hi ");
will scan stuff for a terminating '\0' character, where it will start copying "hi ". If it doesn't find it, it will run off the end of the array, and arbitrarily bad things can happen (i.e., the behavior is undefined).
One way to avoid the problem is like this:
char stuff[100];
stuff[0] = '\0'; /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");
Or you can initialize stuff to an empty string:
char stuff[100] = "";
which will fill all 100 bytes of stuff with zeros (the increased clarity is probably worth any minor performance issue).
Because stuff is uninitialized before the call to strcpy. After the declaration stuff isn't an empty string, it is uninitialized data.
strcat appends data to the end of a string - that is it finds the null terminator in the string and adds characters after that. An uninitialized string isn't gauranteed to have a null terminator so strcat is likely to crash.
If there were to intialize stuff as below you could perform the strcat's:
char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
Strcat append a string to existing string. If the string array is empty, it is not going go find end of string ('\0') and it will cause run time error.
According to Linux man page, simple strcat is implemented this way:
char*
strncat(char *dest, const char *src, size_t n)
{
size_t dest_len = strlen(dest);
size_t i;
for (i = 0 ; i < n && src[i] != '\0' ; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}
As you can see in this implementation, strlen(dest) will not return correct string length unless dest is initialized to correct c string values. You may get lucky to have an array with the first value of zero at char stuff[100]; , but you should not rely on it.
Also, I would advise against using strcpy or strcat as they can lead to some unintended problems.
Use strncpy and strncat, as they help prevent buffer overflows.

Cant add characters to a char pointer assigned to ""

Say I have this code
char *string = "";
string += 'A';
string += 'B';
string += 'C';
printf("%s\n", string);
It just prints an empty line. Why does it do this and is there an easy way to concatenate single characters starting from an empty string if I don't know how long it'll be?
In statements like this
string += 'A';
there is used the pointer arithmetic. The value of the internal representation of the character 'A' is added to the value of the pointer string and as a result the pointer has an invalid value because it does not point to an actual object.
You need to declare a character array as for example
char string[4] = "";
and then you can set respective elements of the array to character literals like for example
int i = 0'
string[i++] = 'A';
string[i++] = 'B';
string[i++] = 'C';
string[i] = '\0';
printf("%s\n", string);
Also you have a typo in this call
printf("&s\n", string);
If a character array already contains a string like
char string[4] = "AB";
and you want to append a character to the end of the string then either you can write using a character literal
size_t n = strlen( string );
string[n] = 'C';
string[n + 1] = '\0';
Or you can use a string literal and the standard C function strcat like
strcat( string, "C" );
In any case the character array shall have enough space to accommodate a new character.
string is just a pointer to the string literal "", so when you add a char with +, you're actually just moving the pointer instead of concatenating to the string. In C, you can allocate a sufficiently large string and use strcat to add strings into it:
char string[100] = "";
strcat(string, "A");
strcat(string, "B");
strcat(string, "C");
printf("%s\n", string);
If you want to use chars, then you can convert the char to a string first.
string += 'A'; does not append a character to the string, it increments the char pointer string by the value of 'A' which on systems that use ASCII is 65 and makes string point well beyond the end of the "" string literal. Hence this code has undefined behavior.
printf("&s\n", string); should print &s and a newline.
Assuming you mistyped your code in the question, printf("%s\n", string); would have undefined behavior, and printing an empty line is possible, as well as a crash or any other nasty side-effect.
If you want to construct a string one character at a time, use this:
char buf[20];
char *string = buf;
*string++ = 'A';
*string++ = 'B';
*string++ = 'C';
*string = '\0'; // set the null terminator
printf("%s\n", buf);
Conversely, you can use strcat with string literals:
char string[20] = "";
strcat(string, "A");
strcat(string, "B");
strcat(string, "C");
printf("%s\n", string);
It just prints an empty line.
You are unfortunate, but not surprisingly so, that your code's undefined behavior manifests as printing an apparently-empty string. It would have been more indicative of the nature of the problem if it threw a segfault, or some other variety of memory-related violation, as would be entirely appropriate.
Why does it do this
Because you are performing arithmetic on the pointer, not modifying the thing to which it points. This expression ...
string += 'A';
... computes the pointer addition of string with the integer character constant 'A' (whose numeric value is system dependent, but is often the ASCII code for capital letter A), and stores the resulting pointer in string. This makes string point to something different than it previously did. It does not in any way modify the contents of the memory to which string pointed.
and is there an easy
way to concatenate single characters starting from an empty string if
I don't know how long it'll be?
If you have an upper bound on how long the data can be, then the easiest thing to do is declare a large-enough array to contain the data and initialize it to all-zero ...
char string[MAX_LEN + 1] = {0};
You can then add a single character by by writing it to the next available index (which index you may either track, or compute at need via strlen()):
unsigned next_index = 0;
string[next_index++] = 'A';
string[next_index++] = 'B';
string[next_index++] = 'C';
Note that this relies on the zero-initialization -- which is not automatic for local variables -- to ensure that the array contents at all times comprise a null-terminated string. Having done that, you can print the expected result:
printf("%s\n", string);
If you did not know in advance a reasonable upper bound on how long the string may be, or if the upper bound were exceedingly large, then you would need to relying on dynamic memory allocation and reallocation. This is a subject for you to defer until later.

Printing a string in C

I understand that in C, a string is an array of characters with a special '\0' character at the end of the array.
Say I have "Hello" stored in a char* named string and there is a '\0' at the end of the array.
When I call printf("%s\n", string);, it would print out "Hello".
My question is, what happens to '\0' when you call printf on a string?
The null character ('\0') at the end of a string is simply a sentinel value for C library functions to know where to stop processing a string pointer.
This is necessary for two reasons:
Arrays decay to pointers to their first element when passed to functions
It's entirely possible to have a string in an array of chars that doesn't use up the entire array.
For example, strlen, which determines the length of the string, might be implemented as:
size_t strlen(char *s)
{
size_t len = 0;
while(*s++ != '\0') len++;
return len;
}
If you tried to emulate this behavior inline with a statically allocated array instead of a pointer, you still need the null terminator to know the string length:
char str[100];
size_t len = 0;
strcpy(str, "Hello World");
for(; len < 100; len++)
if(str[len]=='\0') break;
// len now contains the string length
Note that explicitly comparing for inequality with '\0' is redundant; I just included it for ease of understanding.

Convert Char to String in C

How do I convert a character to a string in C. I'm currently using c = fgetc(fp) which returns a character. But I need a string to be used in strcpy
To answer the question without reading too much else into it I would
char str[2] = "\0"; /* gives {\0, \0} */
str[0] = fgetc(fp);
You could use the second line in a loop with whatever other string operations you want to keep using chars as strings.
You could do many of the given answers, but if you just want to do it to be able to use it with strcpy, then you could do the following:
...
strcpy( ... , (char[2]) { (char) c, '\0' } );
...
The (char[2]) { (char) c, '\0' } part will temporarily generate null-terminated string out of a character c.
This way you could avoid creating new variables for something that you already have in your hands, provided that you'll only need that single-character string just once.
Using fgetc(fp) only to be able to call strcpy(buffer,c); doesn't seem right.
You could simply build this buffer on your own:
char buffer[MAX_SIZE_OF_MY_BUFFER];
int i = 0;
char ch;
while (i < MAX_SIZE_OF_MY_BUFFER - 1 && (ch = fgetc(fp)) != EOF) {
buffer[i++] = ch;
}
buffer[i] = '\0'; // terminating character
Note that this relies on the fact that you will read less than MAX_SIZE_OF_MY_BUFFER characters
I use this to convert char to string (an example) :
char c = 'A';
char str1[2] = {c , '\0'};
char str2[5] = "";
strcpy(str2,str1);
A code like that should work:
int i = 0;
char string[256], c;
while(i < 256 - 1 && (c = fgetc(fp) != EOF)) //Keep space for the final \0
{
string[i++] = c;
}
string[i] = '\0';
//example
char character;//to be scanned
char merge[2];// this is just temporary array to merge with
merge[0] = character;
merge[1] = '\0';
//now you have changed it into a string
This is an old question, but I'd say none of the answers really fits the OP's question. All he wanted/needed to do is this:
char c = std::fgetc(fp);
std::strcpy(buffer, &c);
The relevant aspect here is the fact, that the second argument of strcpy() doesn't need to be a char array / c-string. In fact, none of the arguments is a char or char array at all. They are both char pointers:
strcpy(char* dest, const char* src);
dest : A non-const char pointer
Its value has to be the memory address of an element of a writable char array (with at least one more element after that).
src : A const char pointerIts value can be the address of a single char, or of an element in a char array. That array must contain the special character \0 within its remaining elements (starting with src), to mark the end of the c-string that should be copied.
Here is a working exemple :
printf("-%s-", (char[2]){'A', 0});
This will display -A-
FYI you dont have string datatype in C. Use array of characters to store the value and manipulate it. Change your variable c into an array of characters and use it inside a loop to get values.
char c[10];
int i=0;
while(i!=10)
{
c[i]=fgetc(fp);
i++;
}
The other way to do is to use pointers and allocate memory dynamically and assign values.

Why do I first have to strcpy() before strcat()?

Why does this code produce runtime issues:
char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");
but this doesn't?
char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");
strcat will look for the null-terminator, interpret that as the end of the string, and append the new text there, overwriting the null-terminator in the process, and writing a new null-terminator at the end of the concatenation.
char stuff[100]; // 'stuff' is uninitialized
Where is the null terminator? stuff is uninitialized, so it might start with NUL, or it might not have NUL anywhere within it.
In C++, you can do this:
char stuff[100] = {}; // 'stuff' is initialized to all zeroes
Now you can do strcat, because the first character of 'stuff' is the null-terminator, so it will append to the right place.
In C, you still need to initialize 'stuff', which can be done a couple of ways:
char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
// so 'stuff' is effectively ""
strcpy(stuff, "hi "); // this initializes 'stuff' if it's not already.
In the first case, stuff contains garbage. strcat requires both the destination and the source to contain proper null-terminated strings.
strcat(stuff, "hi ");
will scan stuff for a terminating '\0' character, where it will start copying "hi ". If it doesn't find it, it will run off the end of the array, and arbitrarily bad things can happen (i.e., the behavior is undefined).
One way to avoid the problem is like this:
char stuff[100];
stuff[0] = '\0'; /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");
Or you can initialize stuff to an empty string:
char stuff[100] = "";
which will fill all 100 bytes of stuff with zeros (the increased clarity is probably worth any minor performance issue).
Because stuff is uninitialized before the call to strcpy. After the declaration stuff isn't an empty string, it is uninitialized data.
strcat appends data to the end of a string - that is it finds the null terminator in the string and adds characters after that. An uninitialized string isn't gauranteed to have a null terminator so strcat is likely to crash.
If there were to intialize stuff as below you could perform the strcat's:
char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
Strcat append a string to existing string. If the string array is empty, it is not going go find end of string ('\0') and it will cause run time error.
According to Linux man page, simple strcat is implemented this way:
char*
strncat(char *dest, const char *src, size_t n)
{
size_t dest_len = strlen(dest);
size_t i;
for (i = 0 ; i < n && src[i] != '\0' ; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}
As you can see in this implementation, strlen(dest) will not return correct string length unless dest is initialized to correct c string values. You may get lucky to have an array with the first value of zero at char stuff[100]; , but you should not rely on it.
Also, I would advise against using strcpy or strcat as they can lead to some unintended problems.
Use strncpy and strncat, as they help prevent buffer overflows.

Resources