This is a program to concatenate strings using malloc
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
char *sconcat(char *ptr1,char *ptr2);
void main()
{
char string1[20],string2[20],*ptr;
clrscr();
printf("enter string 1: ");
gets(string1);
printf("enter string 2: ");
gets(string2);
ptr=sconcat(string1,string2);
printf("output string : %s",ptr);
getch();
}
char *sconcat(char *ptr1,char *ptr2)
{
int len1,len2,i,j;
char *ptr3;
len1=strlen(ptr1);
len2=strlen(ptr2);
ptr3=(char *)malloc((len1+len2+1)*sizeof(char));
for(i=0;ptr1[i]!='\0';i++)
ptr3[i]=ptr1[i];
j=i;i=0;
for(;ptr2[j]!='\0';j++,i++)
ptr3[j]=ptr2[i];
ptr3[j]='\0';
return(ptr3);
}
output:
enter string 1 : this program does
enter string 2 : not give output
output string : this program does
What correction is needed to concatenate strings. When I use char string1[20],string2[20],*ptr; after void main(),
output:
enter string 1 : is this
enter string 2 : correct ?
output string : correct? ?
The test in your second for loop is incorrect; it should be ptr2[i] != '\0', not ptr2[j] != '\0'.
Several remarks on the code:
Don't cast the return value of malloc.
sizeof(char) is 1 by definition, so multiplying by sizeof(char) only makes the code harder to read.
Declare the parameters of sconcat as const char *, since they're not modifying the strings they receive.
malloc can return NULL; you must handle that case in your program, for example by displaying an error message and exiting.
gets is unsafe and will crash your program if the user enters more characters than were allocated. Replace gets(string) with fgets(string, sizeof(string), stdin), and getting rid of the trailing newline.
clrscr() and getch(), as well as the infamous <conio.h> header, are not standard C and are non-portable; avoid them in simple programs like this one.
You can more simply use strcat
printf("enter string 1: ");
gets(string1);
printf("enter string 2: ");
gets(string2);
strcat(string1,string2);
It would, however, change string1 so you might want to use strcpy too (to copy string1 to another string and then return it).
Related
I created a struct datatype 'ans' that contains three string datatype member variables a[2],b[2],c[2]. Inside main, I created a struct variable 'p' to accept the three string inputs and then pass it to a function - void f1(ans *x) via call by reference to print the strings. Now in the function, instead of printing the three separate strings (*x).a,(*x).b,(*x).c, it is printing the whole string joined together. I am attaching the code and output for reference:
#include <stdio.h>
typedef struct
{
char a[2];
char b[2];
char c[2];
} ans;
void f1(ans *x) {
printf("The strings are :\n");
printf("%s\n",(*x).a);
printf("%s\n",(*x).b);
printf("%s\n",(*x).c);
}
int main() {
ans p;
printf("Enter for a:\n");
scanf("%s", p.a);
printf("Enter for b:\n");
scanf("%s", p.b);
printf("Enter for c:\n");
scanf("%s", p.c);
f1(&p);
return 0;
}
Sample output:
Enter for a:
ab
Enter for b:
cd
Enter for c:
ef
The strings are :
abcdef
cdef
ef
Can anyone explain why is this showing as output instead of the following:
The strings are:
ab
cd
ef
I can't figure out what's happening :(
In scanf("%s", p.a);, scanf reads characters and writes them to the memory pointed to by p.a. It also writes a terminating null character after them. Since the a member of the structure is declared as char a[2];, when scanf writes more than two characters, including the terminating null, the behavior is not defined by the C standard.
In printf("%s\n",(*x).a);, for %s, printf takes a pointer to a char and prints the characters it finds there until a terminating null character marks the end of the string. When there is no terminating null character the array that is (*x).a, printf overruns the array, and the behavior is not defined by the C standard.
To fix the problem, ensure there is enough space in the arrays for all the characters to be written into them, including the terminating null character, or ensure that no more characters are written in the arrays than will fit.
if you enter "ab", scanf will scan string as "ab\0" which is 3 characters, therefore your a[2] won't fit as same as other variabls.
To prevent scanf from overruns the array, a simple adaptation of your program, from the several that can be suggested:
#define MAXCH 3
typedef struct
{
char a[MAXCH];
char b[MAXCH];
char c[MAXCH];
} ans;
void f1(ans *x)
{
printf("The strings are :\n");
printf("%s\n",(*x).a);
printf("%s\n",(*x).b);
printf("%s\n",(*x).c);
}
int main()
{
ans p;
char in[128];
printf("Enter for a:\n");
scanf("%s",in);
snprintf(p.a,MAXCH,"%s",in);
printf("Enter for b:\n");
scanf("%s",in);
snprintf(p.b,MAXCH,"%s",in);
printf("Enter for c:\n");
scanf("%s",in);
snprintf(p.c,MAXCH,"%s",in);
f1(&p);
return 0;
}
Sample output:
Enter for a:
abcdefgh
Enter for b:
cdefghij
Enter for c:
efghijkl
The strings are :
ab
cd
ef
The program is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
setbuf(stdout,NULL);
int l,i;
char s[10],c;
printf("Enter the string: ");
gets(s);
l=strlen(s);
for(i=0;i<l/2;i++){
c=s[i];
s[i]=s[l-1-i];
s[l-1-i]=c;
}
printf("The reversed string is: %s ",s);
return EXIT_SUCCESS;
}
The output is:
Enter the string: hello world.
The reversed string is: hlrow olleo.
First of all, as mentioned by #Passerby, the gets function should no longer be used. Instead, you can use the fgets() function to take the input.
fgets(s, sizeof(s), stdin); // read string
Secondly, you are storing your input in an array of size 10, whereas your input string is of length 11. So, the 'd' of 'world' is not read at all. Change the array size to a bigger value and replace gets with fgets, and the problem will be fixed.
char s[15], c;
just try to increase the size of array of character bcoz the size of input string "hello world" is greater than 10 OR try to insert small string like "hi world"
The problem I have is the following: I want to read from keyboard 3 strings(s1,s2,s3).What is the best way to do this without any problem and then I want to print those 3 strings.I give the 3 strings but in the print section I only get s2 and s3,but s1 is blank!
Here's my code guys!:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 4
int main(){
char buffer[255];
char s1[M],s2[M],s3[M+1];
printf("Give first string: ");
scanf("%s",buffer);
while(strlen(buffer) > 4){
printf("lenght of string must be <= 4\n");
printf("Give first String again : ");
scanf("%s",buffer);
}
strncpy(s1,buffer,5);
printf("Give second string: ");
scanf("%s",buffer);
while(strlen(buffer) > 4){
printf("lenght of string must be <= 4\n");
printf("Give second String again : ");
scanf("%s",buffer);
}
strncpy(s2,buffer,5);
printf("Give third string: ");
scanf("%s",buffer);
while(strlen(buffer) > 5){
printf("lenght of string must be <= 5\n");
printf("Give third String again : ");
scanf("%s",buffer);
}
strncpy(s3,buffer,5);
printf("First String : %s\n",s1);
printf("Second String : %s\n",s2);
printf("Third String : %s\n",s3);
return 1;
}
strncpy() doesn't null terminate the strings and you need to take care of it else your code will lead to undefined behavior.
Also
M=4
and you are copying 5 character which will lead to undefined behavior.
It's because your strings are not terminated. You need to allow for an extra space in each buffer for a '\0' character at the end of the string. Make all your buffers bigger by 1 and ether set the to 0 to start with
memset(&buf1, 0, sizeof(buf1));
or explicitly set the last index of that buffer to '\0'
#define M 4
...
char s1[M],s2[M],s3[M+1];
...
strncpy(s1,buffer,5)
In the code above (extracted from your program) you copy 5 bytes (or less) in a buffer of size 4. When buffer contains a string of size 4 (strlen(buffer) == 4), strncpy(s1, buffer, 5) copies 5 characters to s1 and the fifth character is the NUL character (the string terminator).
Because s1 has room for only 4 characters, the terminator is written in a memory that does not belong to s1 but to a different variable.
It's recommended to use strncpy() and not strcpy() when you deal with user input to avoid buffer overflows. However, what you accomplished here is exactly a buffer overflow.
The solution is simple and it involves two easy steps:
declare s1 and s2 as char [5] too;
use M everywhere, avoid the hardcoded constants in the code; using constants (#defines) allows easier change of the value, if needed:
...
char s1[M+1],s2[M+1],s3[M+1];
printf("Give first string: ");
scanf("%s",buffer);
while(strlen(buffer) > M){
printf("length of string must be <= %d\n", M);
printf("Give first String again : ");
scanf("%s",buffer);
}
strncpy(s1,buffer,M+1);
...
(repeat the changes above to `s2` and `s3`)
In your code,
strncpy(s1,buffer,5);
creates memory overrun , as s1 is having only 4 bytes allocated. This, in turn invokes undefined behaviour.
Same for
strncpy(s2,buffer,5);
Solution:
Either use #define M 5
or, keep #define M 4, and define your arrays like
char s1[M+1],s2[M+1],s3[M+1];
so that, there is enough space to store the terminating null. (\0)
I am trying to store a string at run time.
#include<stdio.h>
#include<string.h>
void main()
{
char string[4];
printf("Enter the String\n");
scanf("%s", &string[4]);
printf("The String entered is %s\t", string);
}
Output:
Enter the String
ABCD
The String entered is
But Actual Expected output should be The String entered is ABCD. Why i am getting Empty.
&string[4] is the address of the end of the the array, not the start of it.
Change it to
scanf("%s", string);
And if you want to hold 4 chars, you need to make it at least with size = 5 (last one is the null termination character):
char string[5];
&string[4] is one past the end of the array just use string to refer to the beginning of the array.
you also should leave space at the end to put a null termination character.
I am currently trying to solve a problem from CodeChef but I am having troubles with using fgets() inside a loop.
The first input (T) is going to be a positive integer containing the number of user inputs.
Then delimited by newline characters, the user is going to input a string below the length of 10 under any circumstances.
So, I've tried this:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int T;
int diffX, diffY;
char s[SIZE];
scanf("%d", &T);
while (T--){
fgets(s, SIZE, stdin);
printf("%s\n", s);
}
return 0;
}
However, when I attempted to test the code with the following inputs:
3 Hello Hi What
I was only able to input until "Hi" then the program exited successfully (returning 0).
Why is this the case and how can I fix it?
Thank you in advance,
kpark.
fgets() consumes the newline left behind by the first call to scanf(). So, it is consuming 3 lines, but the first line looks like an empty line to the fgets() loop you have.
You can fix this by using fgets() to get the first line too, and parse the string into a number using sscanf().
fgets(s, SIZE, stdin);
sscanf(s, "%d", &T);
/* ... */
It is counting the read of the T as part of the counting. Add a newline in the scanf.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int T;
int diffX, diffY;
char s[SIZE];
scanf("%d\n", &T);
while (T--){
fgets(s, SIZE, stdin);
printf("%s\n", s);
}
return 0;
}
Is your Question is about how to read Multiple Strings in C ?
Then it can be done by 2 ways :-
1.By declaring two dimensional Array of characters.
//Let say we want 6 strings each of them having max 10 characters.
char set[6][10] ;
for(int i=0;i<6;i++)
scanf("%s",set[i])
2.By declaring one dimensional Array of pointers to character (Notice the naming Conventions), in which each of those pointer pointing to a String.
int main(){
int i,numOfStrings;
char temp[30];
printf("Enter Number of strings in set ");
scanf("%d",&numOfStrings);
//Here We have defined array of pointer that will store each string sepratly.
//Arry of pointer to character.
char *setOfStrings[numOfStrings];
for(i=0;i<numOfStrings;i++)
{
printf("Enter string ");
scanf("%s",temp);
setOfStrings[i]= (char*)malloc(sizeof(temp)); //allocted new memory and gave it to array of pointer
strcpy(setOfStrings[i],temp);
}
for(i=0;i<numOfStrings;i++)
{
printf("string = %s \n",setOfStrings[i]);
}
return 0;
}
But that need to understand :
In case of array of pointers we may initialize them with String but Can't take as input from Command line like
char *set[2]={"Dinesh","Kandpal"}; //Its valid but you can't do this from command line
for doing so What we do we will create an space dynamically ,store that address in the one of the element in 1-D array of pointers and then whatever value we have scanned copy that content to the another string to the location that we created using malloc