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.
Related
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.
int main () {
char str1[121];
char str2[4];
unsigned char x=255;
unsigned char y=2;
memset(str1, 0, 121);
memset(str2, 0, 4);
strncpy(str2, "jyot",4);
sprintf(str1,"%d-%d-%s", x,y,str2);
printf("%s",str1);
return(0);
}
Why is it printing 255-2-jyot-255-2?? Should sprintf automatically not append null character after writing last char array?
You are very lucky that your computer did not explode when it had to run this code.
This program is one huge UB. Your str2 is too short. Even if you copy (using strncpy only 4 chars the array does not have enough space to accommodate the trailing zero and strncpy does not copy the last zero.
Change it to:
char str2[5];
strcpy(str2, "jyot");
and delete the memset calls as they are not needed here.
Do not ignore warnings!!!! And compile using more modern standard which does not allow to call functions with no prototypes
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.
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.
I'm creating a char* which essentially will be treated as an string. The string is suppose to be used over and over again. Everytime I'm attempting to check with the while loop and see if its correct to the "quit"...
*I keep getting a segmentation fault...What am I doing wrong -- Pretty idiotic mistake - possibly?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
char* input = (char*)malloc(sizeof(char));
input = "CONTINUE";
while(strcmp(input, "quit") != 0)
{
printf("%s", "System: ");
scanf("%s", input);
}
return 0;
}
Two problems I see in first look:
char* input = (char*)malloc(sizeof(char));
You are assigning your pointer a memory of just one character. It should have enough memory to hold your string not just one character.
You should copy the string in to the allocated buffer using strcpy. Not aassign a string literal to your pointer. Note that modifying such a string literal results in Undefined Behavior.
input = "CONTINUE";
Correct way of doing the above 2 are:
char* input = (char*)malloc(sizeof(MAX_LENGTH));
strcpy(input, "YOURSTRING");
Where MAX_LENGTH is sufficient to hold your input strings.
You are trying to change a literal which is illegal.
Try:
char* input = (char*)malloc(sizeof(char)); /* You need more than one char. */
char* input = (char*)malloc(LENGTH); /* Allocate `LENGTH` chars. */
input = "CONTINUE"; /* You can't write (scanf) over a string literal. */
strcpy(input, "CONTINUE"); /* Now it's legal to write over `input`. */
Other points to watch out for:
Using scanf with a bare "%s" is unsafe. You should use something like "%10s" to make sure a potentially malicious user doesn't enter more than 10 characters
Did you know sizeof(char) isn't needed since it's guaranteed to be 1 ?