String is adding special characters - c

I started following tutorials on C, and then I (from scratch) attempted to do a program where the program chooses a word and you have to guess letters, until you find out the word or run out of attempts.
But I am stuck at the string part, really weird :
srand(time(NULL));
char pWord[6][15] = {"chocolate","peanut","bowling","helicopter","school","controller"}; // Possible words
int repeat=0;
int rNum = rand()%6;
char solution[strlen(pWord[rNum])];
while(repeat<strlen(pWord[rNum])) {
solution[repeat]=pWord[rNum][repeat];repeat++;
}
printf("Answer : %s", solution); printf("\n");
printf("R Answer : %s", pWord[rNum]); printf("\n");
printf("R length : %i", strlen(pWord[rNum])); printf("\n");
strcpy(solution,pWord[rNum]);
For bowling it is fine, but for others it adds weird special characters at random.
I have no idea why this is happening ( i come from java, somewhere lazy and easy ).

In C, the string ends with null character '\0'. So when you declare the character string solution, you need to add one to the length of the char array since strlen() function doesn't count the null character at the end.
char solution[strlen(pWord[rNum])+1];
Then after the while loop, you need to assign the '\0' to the last element of the char array:
while(repeat<strlen(pWord[rNum])) {
solution[repeat]=pWord[rNum][repeat];
repeat++;
}
solution[repeat]='\0';
A better way to do this string copying is to use strcpy() function instead of the while loop:
strcpy(solution, pWord[rNum]);
This way you don't have to assign the null character to the last character. This function does it for you.

Related

String concatenation in C?

I am trying to understand string's behavior in C and it is bothering me since my following two code snippets result into different output:
(For the sake of this question, Let us assume user enters 12)
int main(void)
{
char L_Red[2];
char temp[] = "I";
printf("Enter pin connected to red: ");
scanf("%s", L_Red);
strcat(temp,L_Red);
printf("%s \n", temp);
return 0;
}
this yields: 12 as output (and not I12) Why ?
int main(void)
{
char L_Red[2];
printf("Enter pin connected to red: ");
scanf("%s", L_Red);
char temp[] = "I";
strcat(temp,L_Red);
printf("%s \n", temp);
return 0;
}
This yields: I12I (and not, I12) Why ?
I have read about string in C and as per my understanding, neither am I allocating temp any fixed size and changing it later to get these vague outputs nor am I using strings like the way they are not supposed to. Is there any other concept at play here ?
The array temp is an array of two characters (the 'I' and the string terminator '\0'). That's it. Attempting to append more characters to that array will write out of bounds and lead to undefined behavior.
You need to make sure that the destination array temp have enough space to fit its original content plus the string you want to append (plus the terminator).
Also, if you want to input more than one character for the "string" L_Red you need to increase its size as well.
I also recommend you use a limit in the format specifier so you can't write out of bounds:
char L_Red[3]; // Space for two characters, plus terminator
scanf("%2s", L_Red); // Read at most two characters of input
You are getting strange answers because your destination string (ie the first argument to strcat) is not long enough to handle both strings plus a null termination character. Also the length of L_Red is too short as it does not have enough space for the null termination character either.

Why this code can't print characters in an array?

I compiled this code using gcc (tdm-1) 5.1.0 and please tell me why the output doesn't contain "hello"
#include<stdio.h>
void main()
{
int i;
char st[20];
printf("Enter a string ");
scanf("%s",st);
for(i=0;i<20;i++)
{
printf("%c",st[i]);
}
}
Input:hello
Output: # #
You print all 20 elements of the array, but if the user entered a string smaller than that not all elements would be initialized. They would be indeterminate and seemingly random.
Remember that char strings in C are really called null-terminated byte strings. That null-terminated bit is important, and mean you can easily find the end of the string by checking the current character agains '\0' (which is the terminator character).
Or you could just use the strlen function to get the length of the string instead:
for(i=0;i<strlen(st);i++) { ... }
Or use the "%s" format to print the string:
printf("%s", st);
Also note that without any protection the scanf function will allow you give longer input than is space for in the array, so you need to protect agains that, for example by limiting the amount of characters scanf will read:
scanf("%19s",st); // Write at most 19 character (*plus* terminator) to the string
Now for why your input doesn't seem to be printed, it's because the indeterminate contents of the uninitialized elements. While you're not going out of bounds of your array, you still go out of bounds of the actual string. Going out of bounds leads to undefined behavior.
What's probably is happening is that some of the "random" indeterminate contents happens to be a carriage return '\r', which moves the cursor to the start of the line and the output already written will be overwritten by the uninitialized elements in your array.
Here's a short example as Qubit already explained:
#include <stdio.h>
void main () {
char str1[20];
printf("Enter name: ");
scanf("%s", str1);
printf("Entered Name: %s", str1);
}
Here
char st[20];
st is a local variable & default array st contents are garbage not zero. So if you scan less than 20 characters into st, in that case remaining location of array st contains garbage, hence it's printing some junk data like # # in case of
char st[20];
printf("Enter a string ");
scanf("%s",st);
for(i=0;i<20;i++) {
printf("%c",st[i]);
}
& it's a bad practice as if user entered few char lets say 5 char, then your loop rotates 20 times, internally it will do more operations or consume more CPU cycle.
So if you want to print a char array char by char, then you should rotate a loop until \0 char encounters, for e.g
for(i=0;st[i];i++) { /* this fails when \0 encounters */
printf("%c",st[i]);
}
Or
as others suggested you can print char array st using single printf by using %s format specifier like
printf("%s\n",st); /*here printf starts printing from base address of st
and prints until \0 */
Also it's better to initialize char array st while declaring itself. for e.g
char st[20] ="";

While entering a string in an single element of array in c why does the following code gives the shown output?

#include <stdio.h>
int main(int argc, char *argv[])
{
int i, n, m;
scanf("%d %d", &n, &m);
char s[m][n];
for (i = 0; i < m; i++) {
printf("the string --\n");
scanf("%s", s[i]);
}
for (i = 0; i < m; i++) {
printf("the strings are %s \n",s[i]);
printf("\n");
}
return 0;
}
The output is:
2 2
the string --
10
the string --
11
the strings are 1011
the strings are 11
Why is the first string 1011 instead of 10?
In C, strings are represented as a sequence of char values, terminated by a null character (0 or '\0'). This means that to store a two-character string, you need space for three characters: the two characters of string content, plus the null terminator character.
Here, you've only allocated enough space for two characters in each string, but you need space for three.
So, it reads the first string into the array s[0], but the null terminator doesn't fit, and so it overflows into the second array s[1]. Now your array of arrays s looks like this: {{'1', '0'}, {'\0', ... }}.
Then, when it reads the second string into the array s[1], it overwrites the overflowed null terminator from before. And the null terminator for the second string doesn't fit into its own array, so it overflows again into the rest of the stack. The program might crash here, or corrupt other data, because you're overflowing past the end of the array.
So now your array of arrays s ends up looking like this: {{'1', '0'}, {'1', '1'}}, followed by a '\0' somewhere after the end of the array.
When printf goes to read your first string, it prints characters until it finds a null terminator. But it doesn't find one in the first string, so it keeps going, and hits the second string. It doesn't find one there either, and continues past the end of the array. In your case, luckily a null terminator was right there, but for all we know there could be something else.
To fix this, you need to allocate an extra character per string on line 9, for the null terminator:
char s[m][n+1];
There's another problem here, however. What if your input gives you the wrong length? For example, what if your input says 2 3, i.e. that the following strings will have a length of 3, but gives you the string foobar, which is 6 characters? Your code right now would overflow the buffer when it read that string, because it doesn't ensure it's the right length.
One way to avoid this would be to use gets_s instead of sscanf() for reading the strings on line 13:
gets_s(s[i], n+1);
This will read at most n characters, so avoid crashing your program or creating a security issue. However, gets_s is a C11 function, so you may not be able to use it.
You must set column size to 3 if you insert 2 characters per string, 4 for 3 characters per string and so on.
This because string in C have a termination character ('\0') in the last position.
#include <stdio.h>
int main(int argc, char *argv[])
{
int i, n, m;
scanf("%d %d", &n, &m);
char s[m][n+1];
for (i = 0; i < m; i++) {
printf("the string --\n");
scanf("%s", s[i]);
}
for (i = 0; i < m; i++) {
printf("the strings are %s \n",s[i]);
printf("\n");
}
return 0;
}
%s expects null terminated strings as an argument. When first string is read by scanf, there is not enough space for the null terminator within the allocated memory of first string. It will goes to the space next to the allocated space. Writing to unallocated space invokes undefined behavior.
While printing the strings with %s specifier, printf write the string character by character till it finds a null terminator '\0'. Here it may be the case that both the strings 10 and 11 are stored one after another in memory, so printf writes the first string till it read the null character of second string.
Input n as 3 and you will get the desire results.
In my opninion using scanf to read strings is just pure evil.
That said the array s[m][n] is just s[m*n] of course.
That said that evil thing scanf is going to load on *s[0] 10\n\0 and on *s[1*n] or *s[2] 11 and *s will be 1011\n\0
And this is a monument to bad C coding. I guess it's just an example but if I was asked this question i would say: "Come on, get me real things"

C programming : Strings

My problem is: Input the string then replace the word that we want to change
For example: input: i love coke
word: coke
replace: pepsi
result: i love pepsi
But when i run this code it crashed. Can you help show me the mistake?
#include <stdio.h>
#include<string.h>
char replace(char s1[100],char s2[100],char s3[100])
{
int k,i,j;
for(i=0;i<strlen(s1);i++)
for(j=0;j<strlen(s2);j++)
for(k=0;k<strlen(s3);k++)
{
if(s1[i]==s2[j])
{
s1[i]=s3[k];
}
}
return s3;
}
int main()
{
char s1[100],s2[100],s3[100];
printf("input string: ");gets(s1);
printf("Find string: ");gets(s2);
printf("Replace: ");gets(s3);
printf("Result: %s",replace(s1,s2,s3));
return 0;
}
I suggest you use a 4th buffer to store the generated result. You won't be able to replace locally if the word to be replaced and the new word aren't the same length.
Also, you are comparing characters individually. Just because you found a c doesn't automatically mean you found coke and that you should replace it. You must check the entire word is there before replacing anything. Use strstr() to locate substrings inside a string.
In addition, your function is returning a char, it should return a string (char *).
Furthermore, there are plenty of examples online on how to write a function to replace words on a string, so lets not be reduntant. Google it.
Strings in C are null terminated e.g. "i love coke\0". The string length does not include the null terminator. Because of this you are overwriting the null terminator after the 'e' with the 'i' in "pepsi".
A quick hack to check if null terminating the string would help, is to memset s1, s2, and s3 to 0.
Your approach doesn't quite work. What you need to do is search the input string for the word you wish to replace. So, before you even start switching things around, you need to search for the whole word you wish to replace.
Once you find that word, you need to then put in your new word in it's place, and then start searching for the word again untill you finish your input string.
So, for pseudo code:
for i in input //for every letter
if input[i] != lookfor[0]
results[i] put input[i] into new "results" array
else // We might have found it.
for j in lookfor // Go through coke, one at a time
if input[i+j] != lookfor[j] "c,o,k,e"
break; //You didn;t find coke, just "c" or "co" or "cok"
// If you got all the way through, you found coke.
//So now you have to switch that out for the new that in the result
results[i] = "pepsi" //Just be careful here, because this has a different index than i, because pespi's length != coke's length
Did that make sense?
First of all, your replace function is returning to char instead of char*. You can also define your function's return type as void and can make it return to char* buffer (in/out) parameter after in-function string operations. Moreover, you can use strtok(), strcmp() and strstr() predefined string.h functions to accomplish any kind of string operations.
Check this out to get information about standart string operation functions: String Operations

swapping string in c using pointer

Need help
this is my code
void swapstringfun()
{
int i=0,j=0;
char *str=(char *)malloc(sizeof(char)*15);
char *mystr=(char *)malloc(sizeof(char)*15);
system("cls");
printf("Please enter first string :\t");
scanf("%s",str);
printf("Please enter second string :\t");
scanf("%s",mystr);
while(*(str+i)!='\0' && *(mystr+i)!='\0')
{
*(str+i) ^=*(mystr+i);
*(mystr+i) ^=*(str+i);
*(str+i) ^=*(mystr+i);
i++;
}
printf("%s swapped to %s",str,mystr);
getch();
main();
}
I wrote the above code to swap the string using XOR operator. The problem with this code is. when my input is lets say.. RAJESH and ASHISH. Then, it shows output ASHISH and RAJESH. And, that is expected.
But, when input is let say.. ABHISHEK and CODER .Then, output is CODERHEK and ABHIS. But, the expected output is CODER and ABHISHEK. Anyone help me to solve this problem. I will appreciate.
You iterate and swap until you reach the end of the shorter string
while(*(str+i)!='\0' && *(mystr+i)!='\0')
(or both, if the lengths are equal). To iterate until you reach the end of the longer string, you need an || instead of the && and be sure that 1. both pointers point to large enough memory blocks, and 2. the shorter string ends with enough 0 bytes. So you should calloc the memory, not malloc.
However, you should swap the pointers, really,
char *tmp = str;
str = mystr;
mystr = tmp;
You also need to swap the terminating 0, as its part of what is called a string in C.
The 0 is the stopper element in the character array, describing the string.
You need to XOR the entire length of both strings. Since in your second example, the strings are different lengths, your algorithm won't work.
This is the statement you'll have to reconsider:
while(*(str+i)!='\0' && *(mystr+i)!='\0')

Resources