Concatenating two char arrays in C - c

I have two char arrays (char string1[7] and char string2[256]) which I need to print in a specific format. Both strings have a random number of entries terminated with a '\0' null byte.
I need to print string1
followed by a space on 9th character
followed by string2 - which MUST begin printing from the 10th character onwards.
I have tried implementing this by copying the strings to a new array which I can print directly, however it is not working.
while(string2[i]!='\0')
{
if(i<9 && string1[i]!='\0')
{
Printline[i]=string1[i];
}
else if (i>9)
{
Printline[i]=string2[i];
}
i++;
}
printf("%s\n",Printline);
Any help is much appreciated :)

int main(void) {
char string1[7];
char string2[256];
strncpy(string1, "str1", 6);
strcpy(string2, "This is string 2.");
printf("%-8s %s", string1, string2);
return 0;
}
When compiled and run, the code above will print out:
str1 This is string 2.
The %-8s format specification says that, if the given string of characters is less than 8 characters long (not including '\0'), the string will be followed by whitespaces (blanks) to take up 8 rooms.
Furthermore, the 9th character is going to be a space and the rest will be filled up by string2.
Edit: strncpy function is used for string1 to ensure that no more than 6 characters will be copied from src to dest. Keep in mind that the 7th character will be a null-terminator ('\0').

I believe the following needs to be corrected/clarified and not going to post the code, so that you would have a chance to learn and try to fix it.
while(string2[i]!='\0') /* and further checks in the code, it appears that
the string2 has larger set of characters and
exceeds a count of 9 */
{
if (i<9 && string1[i]!='\0') /* What happens when (i < 9)
but string1[i] has already
reached the '\0'? */
{
Printline[i]=string1[i];
}
else if (i>9)
{
Printline[i]=string2[i];
}
/* What about (i == 9)? */
i++;
}
/* Not including '\0' from string2 before printing Printline
would eventually crash the program */
printf("%s\n",Printline);

Related

File i/o parsing in c giving garbage characters at end of string [duplicate]

I have a char array buffer that I am using to store characters that the user will input one by one. My code below works but has a few glitches that I can't figure out:
when I execute a printf to see what's in Buffer, it does fill up but I get garbage characters at the end
it won't stop at 8 characters despite being declared as char Buffer[8];
Can somebody please explain to me what is going on and perhaps how I could fix this? Thanks.
char Buffer[8]; //holds the byte stream
int i=0;
if (/* user input event has occurred */)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
Output:
tagBuffer is 1┬┬w!
tagBuffer is 12┬w!
tagBuffer is 123w!
tagBuffer is 1234!
tagBuffer is 12345!
tagBuffer is 123456=!
tagBuffer is 1234567!
tagBuffer is 12345678!
tagBuffer is 123456789!
You have to end the string with a \0 character. That's why they are called zero terminated strings.
It is also wise to allocate 1 extra char to hold the \0.
The only thing you are passing to the printf() function is a pointer to the first character of your string. printf() has no way of knowing the size of your array. (It doesn't even know if it's an actual array, since a pointer is just a memory address.)
printf() and all the standard c string functions assume that there is a 0 at the end of your string. printf() for example will keep printing characters in memory, starting at the char that you pass to the function, until it hits a 0.
Therefore you should change your code to something like this:
char Buffer[9]; //holds the byte stream
int i=0;
if( //user input event has occured )
{
Buffer[i] = charInput;
i++;
Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result.
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
In addition to the previous comments about zero termination, you also have to accept responsibility for not overflowing your own buffer. It doesn't stop at 8 characters because your code is not stopping! You need something like the following (piggy-backing onto Jeremy's suggestion):
#define DATA_LENGTH 8
#define BUFFER_LENGTH (DATA_LENGTH + 1)
char Buffer[BUFFER_LENGTH]; //holds the byte stream
int charPos=0; //index to next character position to fill
while (charPos <= DATA_LENGTH ) { //user input event has occured
Buffer[i] = charInput;
Buffer[i+1] = '\0';
// Display a response to input
printf("Buffer is %s!\n", Buffer);
i++;
}
In other words, make sure to stop accepting data when the maximum length has been reached, regardless of what the environment tries to push at you.
If you are programming in C or C++, you have to remember that:
1) the strings are finished with a \0 character.
2) C does not have boundary check at strings, they are just character arrays.
It's odd that no-one has mentioned this possibility:
char Buffer[8]; //holds the byte stream
int i = 0;
while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %.*s!\n", i, Buffer);
}
This notation in the printf() format string specifies the maximum length of the string to be displayed, and does not require null termination (though null termination is ultimately the best way to go -- at least once you leave this loop).
The while loop is more plausible than a simple if, and this version ensures that you do not overflow the end of the buffer (but does not ensure you leave enough space for a trailing NUL '\0'. If you want to handle that, use sizeof(Buffer) - 1 and then add the NUL after the loop.
Since Buffer is not initialized, it starts with all 9 garbage values.
From the observed output, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th and 2 immediate next memory location(outside the array) elements are clearly 'T', 'T', 'W', '\0', '\0', '=', '\0', '\0', '\0'.
Strings consume all the characters up until they see NULL character. That is why, in every iteration, as the array elements are assigned one by one, buffer is printed up to the part where a garbage NULL is present.
That is to say, string has an undefined behavior if the character array doesn't end with '\0'. You can avoid this by having an extra space for '\0' at the end of the buffer.
You might also want to look into using a stringstream.

Understanding this program which prints a sentence in reverse but keeps the words unchanged

I don't quite understand this program. I don't understand what is happening in the for loop. Can someone explain to me in simple words. And the site also didn't explain it well-enough. This is the link to the site. https://www.geeksforgeeks.org/print-words-string-reverse-order/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void printReverse(char str[])
{
int length = strlen(str);
FILE *fptr;
if((fptr=fopen("Question1.txt","w"))==NULL)
{
printf("Invalid file");
exit(0);
}
int i;
for (i = length - 1; i >= 0; i--) {
if (str[i] == ' ')
{
str[i] = '\0';
printf("%s ", &(str[i]) + 1);
fprintf(fptr,"%s ", &(str[i]) + 1);
}
}
fprintf(fptr,"%s",str);
printf("%s.", str);
fclose(fptr);
}
int main()
{
char str[1000];
//clrscr();
printf("Enter string: ");
scanf("%[^\n]s", str);
printReverse(str);
//getch();
return 0;
}
In the for loop, why put &(str[i])+1? And also in printf("%s.", str)--this only has the first word; how?
Okay, let's see if I can help. I'll go through the code carefully.
I suspect you already understand this. It's just a method call.
void printReverse(char str[])
{
strlen is a standard method that returns the length of a null-terminated string. That means that str might contain Hello (5 characters), but there's one more byte with a 0 in it, which is how C has always marked the end of the string. In this case, str itself takes 6 bytes, but length will be 5.
int length = strlen(str);
This is how you open a file in C. C++ has better ways. The file is written for writing.
FILE *fptr;
if((fptr=fopen("Question1.txt","w"))==NULL)
{
printf("Invalid file");
exit(0);
}
Here's your for-loop. Let's assume str contains Hello, so length is 5, but the indexes into string are str[0..4]. C uses the index as "offset from the beginning", so the first element is 0, not 1. Thus, when this loop starts, str[i] == o (using Hello as our example string). We then loop, decrementing i each time. Once i goes below 0, the loop ends.
int i;
for (i = length - 1; i >= 0; i--) {
Okay, remember we're printing the words in normal order, but the words themselves are in reverse order. So this looks for a space -- between words. So if we use Hello there as our input text, this if-statement is true when i is pointing to the space between the two words.
Now here's the trick. Remember what I said earlier about null-terminated strings? What this does is to step on that space and replace it with a 0. That makes the rest of this magic work.
if (str[i] == ' ')
{
str[i] = '\0';
And here's the magic. Now, this is a strange way to do it. I would have done it with &str[i+1], but this works. What this is doing is saying "Print the string that begins after the space we just clobbered." We do it to the terminal and the file.
printf("%s ", &(str[i]) + 1);
fprintf(fptr,"%s ", &(str[i]) + 1);
}
}
This writes the produced rearranged string to the file that was opened as well as to your terminal then makes sure the file is closed.
fprintf(fptr,"%s",str);
printf("%s.", str);
fclose(fptr);
}
This all works because we step on the spaces with a zero. For Hello world, we:
Start from the tail
Find the space and stick a zero in it
Print world
Keep backing up to the end of the data.
Drop out of the for-loop and print whatever is left: Hello
Answer to your specific questions
In the for loop why put? &(str[i])+1?
&str[i] is the address of the character at index i where a space has been replaced with a NUL character. With +1 you get the address of the character after it, i.e. the beginning of the word that follows the space that was just replaced. (In case of double spaces this would result in an empty string.)
And also in printf("%s.", str); this only has the first word how?
Assuming the first word is not preceded by a space, the loop will not print it.
This printf("%s.", str); will print the string from the beginning until the first NUL character that replaces a former space character, hence resulting in the first word.
Additional question from comment
So... for example if I input Hello World does the W in that get the index 0?
The W is at index 6. (H is 0, e is 1 etc.)
When i has been counted down to 5, the space at this position will be replaced with a NUL ('\0') character, and it will print the remaining string from the W up to the end of the string which is also marked by a NUL character. (As defined by the C standard.)
And what if the character is not a NULL character? Then it won't go execute if right? It'll just increment i again till it encounters another NULL right?
I don't fully understand these questions. In case there was no NUL character at the end of the string printf would read past the end of the string leading to undefined behavior.
In case of an input string Hello World and Universe", all spaces after Worldwould have been replaced with NUL characters before, so when the program reaches the position of the space beforeWorld`, the string will be
Hello World\0and\0Universe\0
before the replacement and
Hello\0World\0and\0Universe\0
after the replacement.

Why does this string with a pointer return a random set of symbols? [duplicate]

I have a char array buffer that I am using to store characters that the user will input one by one. My code below works but has a few glitches that I can't figure out:
when I execute a printf to see what's in Buffer, it does fill up but I get garbage characters at the end
it won't stop at 8 characters despite being declared as char Buffer[8];
Can somebody please explain to me what is going on and perhaps how I could fix this? Thanks.
char Buffer[8]; //holds the byte stream
int i=0;
if (/* user input event has occurred */)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
Output:
tagBuffer is 1┬┬w!
tagBuffer is 12┬w!
tagBuffer is 123w!
tagBuffer is 1234!
tagBuffer is 12345!
tagBuffer is 123456=!
tagBuffer is 1234567!
tagBuffer is 12345678!
tagBuffer is 123456789!
You have to end the string with a \0 character. That's why they are called zero terminated strings.
It is also wise to allocate 1 extra char to hold the \0.
The only thing you are passing to the printf() function is a pointer to the first character of your string. printf() has no way of knowing the size of your array. (It doesn't even know if it's an actual array, since a pointer is just a memory address.)
printf() and all the standard c string functions assume that there is a 0 at the end of your string. printf() for example will keep printing characters in memory, starting at the char that you pass to the function, until it hits a 0.
Therefore you should change your code to something like this:
char Buffer[9]; //holds the byte stream
int i=0;
if( //user input event has occured )
{
Buffer[i] = charInput;
i++;
Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result.
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
In addition to the previous comments about zero termination, you also have to accept responsibility for not overflowing your own buffer. It doesn't stop at 8 characters because your code is not stopping! You need something like the following (piggy-backing onto Jeremy's suggestion):
#define DATA_LENGTH 8
#define BUFFER_LENGTH (DATA_LENGTH + 1)
char Buffer[BUFFER_LENGTH]; //holds the byte stream
int charPos=0; //index to next character position to fill
while (charPos <= DATA_LENGTH ) { //user input event has occured
Buffer[i] = charInput;
Buffer[i+1] = '\0';
// Display a response to input
printf("Buffer is %s!\n", Buffer);
i++;
}
In other words, make sure to stop accepting data when the maximum length has been reached, regardless of what the environment tries to push at you.
If you are programming in C or C++, you have to remember that:
1) the strings are finished with a \0 character.
2) C does not have boundary check at strings, they are just character arrays.
It's odd that no-one has mentioned this possibility:
char Buffer[8]; //holds the byte stream
int i = 0;
while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %.*s!\n", i, Buffer);
}
This notation in the printf() format string specifies the maximum length of the string to be displayed, and does not require null termination (though null termination is ultimately the best way to go -- at least once you leave this loop).
The while loop is more plausible than a simple if, and this version ensures that you do not overflow the end of the buffer (but does not ensure you leave enough space for a trailing NUL '\0'. If you want to handle that, use sizeof(Buffer) - 1 and then add the NUL after the loop.
Since Buffer is not initialized, it starts with all 9 garbage values.
From the observed output, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th and 2 immediate next memory location(outside the array) elements are clearly 'T', 'T', 'W', '\0', '\0', '=', '\0', '\0', '\0'.
Strings consume all the characters up until they see NULL character. That is why, in every iteration, as the array elements are assigned one by one, buffer is printed up to the part where a garbage NULL is present.
That is to say, string has an undefined behavior if the character array doesn't end with '\0'. You can avoid this by having an extra space for '\0' at the end of the buffer.
You might also want to look into using a stringstream.

How to replace a character in a string with NULL in ANSI C?

I want to replace all 'a' characters from a string in ANSI C. Here's my code:
#include <stdio.h>
#include <stdlib.h>
void sos(char *dst){
while(*dst){
if(*dst == 'a')
*dst = '\0';
dst++;
}
}
int main(void){
char str[20] = "pasternak";
sos(str);
printf("str2 = %s \n", str);
return 0;
}
When I run it, result is:
str2 = p
But it should be
str2 = psternk
It works fine with other characters like 'b' etc. I tried to assign NULL to *dst, but I got error during compile.
How can I remove 'a' characters now?
In C, strings are zero-terminated, it means that when there's a '\0' in the string it is the end of the string.
So what you're doing is spliting the string in 3 different ones:
p
stern
k
If you want to delete the a you must move all the characters after the a one position.
What printf does is: read bytes until a '\0' is found.
You transformed "pasternak" to "p\0astern\0k", so printf prints p.
This convention is used on the string functions of the stdlib so that you don't have to pass string length as an argument.
This is why it is said that in C strings are null terminated: it is just a convention followed by the C stdlib.
The downside, as you discovered, is that strings cannot contain \0.
If you really want to print a given number of bytes, use something like fwrite, which counts the number of bytes to be printed, so it can print a \0.
The answers previously provided are perfect to explain why your code does not work. But you can try to use strtok to split the string based on the 'a' characters, to then join the parts together or simply print them appart. Check this example: http://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm
'\0' is how the C language tools recognize the end of the string. In order to actually remove a character, you'll need to shift all of the subsequent characters forward.
void sos(char *dst) {
int offset = 0;
do {
while (dst[offset] == 'a') ++offset;
*dst = dst[offset];
} while (*dst++);
}

string array with garbage character at end

I have a char array buffer that I am using to store characters that the user will input one by one. My code below works but has a few glitches that I can't figure out:
when I execute a printf to see what's in Buffer, it does fill up but I get garbage characters at the end
it won't stop at 8 characters despite being declared as char Buffer[8];
Can somebody please explain to me what is going on and perhaps how I could fix this? Thanks.
char Buffer[8]; //holds the byte stream
int i=0;
if (/* user input event has occurred */)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
Output:
tagBuffer is 1┬┬w!
tagBuffer is 12┬w!
tagBuffer is 123w!
tagBuffer is 1234!
tagBuffer is 12345!
tagBuffer is 123456=!
tagBuffer is 1234567!
tagBuffer is 12345678!
tagBuffer is 123456789!
You have to end the string with a \0 character. That's why they are called zero terminated strings.
It is also wise to allocate 1 extra char to hold the \0.
The only thing you are passing to the printf() function is a pointer to the first character of your string. printf() has no way of knowing the size of your array. (It doesn't even know if it's an actual array, since a pointer is just a memory address.)
printf() and all the standard c string functions assume that there is a 0 at the end of your string. printf() for example will keep printing characters in memory, starting at the char that you pass to the function, until it hits a 0.
Therefore you should change your code to something like this:
char Buffer[9]; //holds the byte stream
int i=0;
if( //user input event has occured )
{
Buffer[i] = charInput;
i++;
Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result.
// Display a response to input
printf("Buffer is %s!\n", Buffer);
}
In addition to the previous comments about zero termination, you also have to accept responsibility for not overflowing your own buffer. It doesn't stop at 8 characters because your code is not stopping! You need something like the following (piggy-backing onto Jeremy's suggestion):
#define DATA_LENGTH 8
#define BUFFER_LENGTH (DATA_LENGTH + 1)
char Buffer[BUFFER_LENGTH]; //holds the byte stream
int charPos=0; //index to next character position to fill
while (charPos <= DATA_LENGTH ) { //user input event has occured
Buffer[i] = charInput;
Buffer[i+1] = '\0';
// Display a response to input
printf("Buffer is %s!\n", Buffer);
i++;
}
In other words, make sure to stop accepting data when the maximum length has been reached, regardless of what the environment tries to push at you.
If you are programming in C or C++, you have to remember that:
1) the strings are finished with a \0 character.
2) C does not have boundary check at strings, they are just character arrays.
It's odd that no-one has mentioned this possibility:
char Buffer[8]; //holds the byte stream
int i = 0;
while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF)
{
Buffer[i] = charInput;
i++;
// Display a response to input
printf("Buffer is %.*s!\n", i, Buffer);
}
This notation in the printf() format string specifies the maximum length of the string to be displayed, and does not require null termination (though null termination is ultimately the best way to go -- at least once you leave this loop).
The while loop is more plausible than a simple if, and this version ensures that you do not overflow the end of the buffer (but does not ensure you leave enough space for a trailing NUL '\0'. If you want to handle that, use sizeof(Buffer) - 1 and then add the NUL after the loop.
Since Buffer is not initialized, it starts with all 9 garbage values.
From the observed output, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th and 2 immediate next memory location(outside the array) elements are clearly 'T', 'T', 'W', '\0', '\0', '=', '\0', '\0', '\0'.
Strings consume all the characters up until they see NULL character. That is why, in every iteration, as the array elements are assigned one by one, buffer is printed up to the part where a garbage NULL is present.
That is to say, string has an undefined behavior if the character array doesn't end with '\0'. You can avoid this by having an extra space for '\0' at the end of the buffer.
You might also want to look into using a stringstream.

Resources