C strcat() gives wrong appended string - c

I am appending a string using single character, but I am not able to get it right. I am not sure where I am making mistake. Thank you for your help in advance. The original application of the method is in getting dynamic input from user.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){
int j;
char ipch=' ';
char intext[30]="What is the problem";
char ipstr[30]="";
printf("Input char: ");
j=0;
while(ipch!='\0'){
//ipch = getchar();
ipch = intext[j];
printf("%c", ipch);
strcat(ipstr,&ipch);
j++;
}
puts("\n");
puts(ipstr);
return;
}
Following is the output I am getting.
$ ./a.out
Input char: What is the problem
What is h e
p
oblem

change
strcat(ipstr,&ipch);
to
strncat(ipstr, &ipch, 1);
this will force appending only one byte from ipch. strcat() will continue appending some bytes, since there's no null termination character after the char you are appending. as others said, strcat might find somewhere in memory \0 and then terminate, but if not, it can result in segfault.
from manpage:
char *strncat(char *dest, const char *src, size_t n);
The strncat() function is similar to strcat(), except that
it will use at most n characters from src; and
src does not need to be null-terminated if it contains n or more characters.

strcat requires its second argument to be a pointer to a well-formed string. &ipch does not point to a well-formed string (the character sequence of one it points to lacks a terminal null character).
You could use char ipch[2]=" "; to declare ipch. In this case also use:
strcat(ipstr,ipch); to append the character to ipstr.
ipch[0] = intext[j]; to change the character to append.
What happens when you pass &ipch to strcat in your original program is that the function strcat assumes that the string continues, and reads the next bytes in memory. A segmentation fault can result, but it can also happen that strcat reads a few garbage characters and then accidentally finds a null character.

strcat() is to concatenate strings... so passing just a char pointer is not enough... you have to put that character followed by a '\0' char, and then pass the pointer of that thing. As in
/* you must have enough space in string to concatenate things */
char string[100] = "What is the problem";
char *s = "?"; /* a proper '\0' terminated string */
strcat(string, s);
printf("%s\n", string);

strcat function is used to concatenate two strings. Not a string and a character. Syntax-
char *strcat(char *dest, const char *src);
so you need to pass two strings to strcat function.
In your program
strcat(ipstr,&ipch);
it is not a valid statement. The second argument ipch is a char. you should not do that. It results in Segmentation Fault.

Related

Usage of pointers as parameters in the strcpy function. Trying to understand code from book

From my book:
void strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
I'm trying to understand this snippet of code from my textbook. They give no main function so I'm trying to wrap my head around how the parameters would be used in a call to the function. As I understand it, the "i-number" of characters of string t[ ] are being copied to the string s[ ] until there are no longer characters to read, from the \0 escape sequence. I don't really understand how the parameters would be defined outside of the function. Any help is greatly appreciated. Thank you.
Two things to remember here:
Strings in C are arrays of chars
Arrays are passed to functions as pointers
So you would call this like so:
char destination[16];
char source[] = "Hello world!";
strcpy(destination, source);
printf("%s", destination);
i is just an internal variable, it has no meaning outside the strcpy function (it's not a parameter or anything). This function copies the entire string t to s, and stops when it sees a \0 character (which marks the end of a string by C convention).
EDIT: Also, strcpy is a standard library function, so weird things might happen if you try to redefine it. Give your copy a new name and all will be well.
Here's a main for you:
int main()
{
char buf[30];
strcpy(buf, "Hi!");
puts(buf);
strcpy(buf, "Hello there.");
puts(buf);
}
The point of s and t are to accept character arrays that exist elsewhere in the program. They are defined elsewhere, at this level usually by the immediate caller or one more caller above. Their meanings are replaced at runtime.
Your get compile problems because your book is wrong. Should read
const strcpy (char *s, const char *t)
{
...
return s;
}
Where const means will not modify. Because strcpy is a standard function you really do need it to be correct.
Here is how you might use the function (note you should change the function name as it will conflict with the standard library)
void my_strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
int main()
{
char *dataToCopy = "This is the data to copy";
char buffer[81]; // This buffer should be at least big enough to hold the data from the
// source string (dataToCopy) plus 1 for the null terminator
// call your strcpy function
my_strcpy(buffer, dataToCopy);
printf("%s", buffer);
}
In the code, the i variable is pointing to the character in the character array. So when i is 0 you are pointing to the first character of s and t. s[i] = t[i]copies the i'th character from t to the i'th character of s. This assignment in C is self an expression and returns the character that was copied, which allows you to compare that to the null terminator 0 ie. (s[i] = t[i]) != ’\0’ which indicates the end of the string, if the copied character is not a null terminator the loop continues otherwise it will end.

C program -special characters in output

Output of this program gives a special character in the beginning.Wat is the reason?
#include<stdio.h>
#include<conio.h>
#include<string.h>
main() {
int i, j,count=0,nl;
char str2[100];
char str1[100];
char str[100];
char init[8];
char final[8];
//clrscr();
printf("enter the bit string: ");
gets(str);
puts(str);
strcat(init,"10101010");
strcat(final,"10101010");
strcpy(str1,(strcat(init,str)));
strcpy(str2,(strcat(str1,final)));
puts(str2);
printf("%d",(strlen(str2)));
getch();
}
You can't use strcat() on init because it's uninitialized, you need at least the nul terminator, example
init[0] = '\0';
but I would recommend strcpy() instead,
strcpy(init, "10101010");
would not require the initialization metioned above, but would require an extra character.
But then you need one extra character for the nul terminator, i.e.
char init[9];
instead of char init[8].
Also, gets() is a deprecated function, because it has potential to overflow the buffer, you should be using fgets() instead, like
fgets(str, sizeof(str), stdin);
You need a NUL terminated string to use strcat
Change
char init[8];
char final[8];
to
char init[8] = "";
char final[8] = "";
And note that gets is deprecated, change to
fgets(str, sizeof str, stdin);
/* remove the trailing newline */
char *ptr = strchr(str, '\n');
if (ptr) *ptr = '\0';
strcat() must be used on initialized strings because before it can do its thing it must find the current string's end. Since init and final are supposed to be empty, its best if you use strcpy() instead.
Also, strings in C are null-terminated, which means theres always an additional symbol \0 at the end. Storing the string 10101010 actually takes 9 bytes. init and final can only take 8 bytes.
Also, you are trying to strcat(init, str). init is already full at this point, so any additional char you are trying to append to it is out of bound and overwriting the stack. This application will invoke undefined behaviour and probably crash. init must be big enough to hold the content of str plus 9 bytes.

Using strcat() with a char from a string?

I'm trying to append characters from a string into a new string. For the code below:
int main(void)
{
char s1[] = "cat";
char s2[] = "hsklsdksdhkjadsfhjkld";
strcat(s1, &s2[1]);
printf("s1 is now %s\n", s1);
}
Why is the output catsklsdksdhkjadsfhjkld and not cats? Why is the whole string added, instead of just the 's' located at s2[1]?
Thanks.
since a char * is only a pointer to the start of a string; C supposes the end of the string is a \0 character. So all characters are added until he meets the \0 character
you suppose &s2[1] points to "s", (which is true), but since it is a char pointer, it points to the whole char array, until the \0 character at the end. Try this for example:
printf("%s\n", &s2[1]);
which will yield:
sklsdksdhkjadsfhjkld
from the reference of strcat:
Concatenate strings
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
EDIT
if you want to add only one (or some) characters, use strncat:
strncat(s1, &s2[1], 1 /*number of chars to append*/);
EDIT2
make sure your char arrays are large enough, as suggested by #PaulR:
char s1[32] = "cat";
Both arguments to strcat are pointers to char objects, and both are assumed to point to (the initial character of) a string.
For example, this:
strcat(s1, &s2[0]);
is equivalent to this:
strcat(s1, s2);
In both cases, the second argument is a pointer to the initial character of a string, which strcat uses to access the entire string up to and including the terminating '\0' null character.
But your program has undefined behavior. By declaring
char s1[] = "cat";
you let the compiler determine the size of s1 based on the initializer. In this case, s1 is an array of 4 chars (including the terminating '\0'). There is no room to append anything to it. Apparently when you ran it, it copied characters into the memory space immediately following s1, which is why it seemed to "work".
A working version of your program is:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[50] = "cat";
char s2[] = "hsklsdksdhkjadsfhjkld";
strcat(s1, &s2[1]);
printf("s1 is now %s\n", s1);
}
Note the #include directives. These are not optional, even though you might get away with omitting them.
You can use strncat instead of strcat:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[32] = "cat"; // NB: s1 needs to be large enough to hold additional chars !
char s2[32] = "hsklsdksdhkjadsfhjkld";
strncat(s1, &s2[1], 1);
printf("s1 is now %s\n", s1);
return 0;
}
LIVE DEMO
Because strcat() takes two string arguments, and because &s2[1] isn't a character, it's the string "sklsdksdhkjadsfhjkld";
So strcat(s1, &s2[1]); concatenates
"cat" + "sklsdksdhkjadsfhjkld"
Giving the result
"catsklsdksdhkjadsfhjkld"
If you want to append a single character you could do this
len = strlen (s1);
s1[len] = s2[1];
s1[len+1] = '\0'; // new string terminator
but you would have to ensure there is enough array (string) space available.

Why am I getting segmentation fault while dynamically allocating in c?

This is my code and when I run it, I am getting segmentation fault.
char *s = NULL;
s = (char *)malloc(5*sizeof(char));
s[0]='10';
s[1]='20';
printf("%s",s[1]);
please tell where the error is and why this is happening. My intension of the program is to dynamically create a string, give it some value byte by byte and print the values byte by byte.
Is there any way to add integer values to string. Because, I have a situation where length of string is to be in first part of string followed by data. Kindly suggest any method to do this in C.
printf("%s", s[1]); means print string starting at address (int)'20'. That's clearly a bug. Should be: s[2]='\0'; printf("%s", s+1 /*&s[1]*/);
You are storing multibyte characters in s[0] and s[1]. Beside of this use %c format specifier to print a character.
1.s[0] is a char you can not assign 10 to it. (It will compile with warnings but it is not doing what you have expected)
2.printf("%s",s[1]); will also cause undefined behavior as string followed bys[1] is not null terminated.
Don't cast the result of malloc and family.
s[0] and s[1] will take only one byte value.
Then your string is not a null terminated string.
Try this.
s[0]='h';
s[1]='i';
s[2]='\0';
printf("%s",s);
%s is for printing the string. Use %c for printing the character.
printf("%c",s[1]);
You can use like this to store the integer into an char array,
char *s=malloc(123);
sprintf(s,"%d",integer_value);
Then use strcat to store the string in that.
Passing to the function use like this,
void func(char *);
main() {
. . .
func(s);
. . .
}
void func(char *str)
{
// do what you need
}
if between integer and string slash is available ( like in your comment) you can use the strtok function. Before using the strtok function take backup for your string. It will modify your content. Or els you can use like this,
sscanf(str,"%d / %s",&int,string);
Now string have the value "hello".
char s[10];
sprintf(s,"%d",int);
strcat(str,s);
Try this,
int fd;
char str[]="data7";
char st[12];
sscanf(str,"%[^ 0-9] %d",st,&fd);
printf("st:%s\tfd:%d\n",st,fd);

strcat in C error segmentation

#include <stdio.h>
#include <string.h>
int main() {
char tab[2]={"12"};
FILE *outfile;
char *outname = "/home/dir/";
printf("%s", strcat(outname,tab));
outfile = fopen(strcat(outname,btab), "w");
if (!outfile) {
printf("There was a problem opening %s for writing\n", outname);
}
}
I have this error: Segmentation Fault.
How can I fix it?
At least two errors:
char tab[2] = {"12"};
You'd better use tab[3] or even better tab[] -- you need one extra char for the terminating NUL character.
Also,
char *outname = "etc...";
creates a constant string in the data segment of the executable -- it can't be overwritten, since strcat is using its first parameter to concatenate the two strings. So when strcat() tries to do so, it segfaults. Use
char outname[50]; // something big enough
strcpy(outname, "/home/dir");
instead.
outname is a string literal and string literals are not modifiable. Modifying a string literal is undefined behavior.
outname is Const pointer so once you have entered some thing in it, you can't modify it.
However if you want to copy things in it, make a char array of the size equal to tab[] array because here the size of string to be copied is known. Most of the time char pointers like OUTNAME are used when you are taking input from a user once and you don't know how long that input will be.
In your code,
char *outname = "/home/dir/";
outname is a string literal and hence when used with strcat, it does not have enough length to hold the concatenated string.This results in segmentation fault.
Same is the case had you declared it as below,
char outname[] = "/home/dir/";
The solution for this to declare the size of the outname big enough to hold the concatenated string.
char outname[80] = "/home/dir/";

Resources