Do strings in C language change in the middle of program execution? - arrays

I was writing the code for Bit stuffing, but I am not getting appropriate answer, when I checked the values of the input string, there was another garbage value added at the end of the string.
#include<stdio.h>
#include<string.h>
void input(char[],int);
void stuff(char ch[],int n)
{
char str1[6]="11111";
char str2[6]="00000";
printf("str1=%s\n",str1);
printf("ch=%s\n",ch);
if(!strcmp(ch,str1))
{
printf("\n111101");
}
else if(!strcmp(ch,str2))
{
printf("\n000010");
}
else
{
puts(ch);
}
}
void main()
{
int flag=0;
char ch[5];
input(ch,5);
printf("ch0=%s\n",ch); //printing the input string
for(int i=0;i<5;i++)
{
if((ch[i]!='0')&&(ch[i]!='1'))
{
flag=1;
}
}
if(flag==0)
{
puts("Entered data:");
for(int i=0;i<5;i++)
{
printf("%c",ch[i]);
}
puts("\nAfter stuffing");
printf("ch1=%s\n",ch); //getting garbage value here
stuff(ch,5);
}
else
{
printf("Enter a valid data\n");
printf("%d",flag);
}
}
void input(char ch[],int n)
{
printf("Enter 5 digits\n");
for(int i=0;i<=n;i++)
{
scanf("%c",&ch[i]);
}
}
The output of the code is as follows.
Enter 5 digits
11111
ch0=11111
Entered data:
11111
After stuffing
ch1=11111♣
str1=11111
ch=11111♣
11111♣
Process returned 0 (0x0) execution time : 4.046 s
Press any key to continue.
I am using Code blocks IDE with MINGW. The code above should compare the string entered with the given sequence and stuff the bits if all five bits are homogenous.

Your code has undefined behavior. For example you declared a character array with 5 elements in main
char ch[5];
Then you are calling the function input
input(ch,5);
Within the function you are entering 6 characters in the for loop
void input(char ch[],int n)
{
printf("Enter 5 digits\n");
for(int i=0;i<=n;i++)
{
scanf("%c",&ch[i]);
}
}
That is you are overwriting the memory outside the array.
Taking into account the program output
Enter 5 digits
11111
ch0=11111
the call of scanf
scanf("%c",&ch[i]);
also stored the new line character '\n' in the memory after the last element of the array. You should at least write
scanf(" %c",&ch[i]);
^^^^^
instead of
scanf("%c",&ch[i]);
Pay attention to the leading space in the format string. It allows to skip white space characters.
The array does not contain a string but you are trying to output it as if it contains a string
printf("ch0=%s\n",ch); //printing the input string
or to use it in calls of strcmp as for example
if(!strcmp(ch,str1))
that again invokes undefined behavior.
To output the array you could use the following format string
printf("ch0=%.*s\n", 5, ch); //printing the input string
and to compare character arrays you could use either strncmp or memcmp.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )

Lack of null-byte:
A string in C is an array of null-terminated bytes. You do not terminate ch in the input function.
strcmp does compare two strings, but it requires them to be null-terminated.
printf too requires a null-terminated string with the %s format specifier, otherwise it doesn't know when to stop printing. And your code would most probably result in a segmentation fault.
Accessing memory out of bounds:
This line:
for(int i=0;i<=n;i++)
invokes undefined behaviour because it's writing to out of bounds memory. ch has been declared to only contain 5 bytes, which must include the '\0' character.

Related

C program that reads five strings and only prints strings that begin with the letter 'a'

I'm new to programming and cant figure out what I'm doing wrong.
From the 5 given strings I'm trying to print only strings that begin with the character 'a'.
This is what i have done so far
#include <stdio.h>
int main()
{
char str[5][100];
int i;
//For loop asks user to input 5 strings
for(i=0;i<5;i++)
{
printf("\nEnter line > ");
scanf("%s", str[i]);
}
for(i=0;i<5;i++)
{
//To check if the first character in a string is 'a'
if(!str[0]=='a')
{
printf("\n%s", str[i]);
}
}
return 0;
}
This part is not working. In my mind its supposed to check the first letter of every string but its not doing that. Instead the program doesn't print out anything when this if statement is there.
if(!str[0]=='a')
In your if statement, you need to remove the ! character and access the first element of the string i like this:
if(str[i][0]=='a')
Your are accessing the pointer to the first string which will be a random memory address. If you access the first value, you will need to access two array elements: First the correct character array (string) by using [i] and then the character you want to test [0]
The ! in front of the first value will turn any non-zero value to zero and a zero into a one (logical negation). Therefore you are always testing
if(0 == 'a')
which is always false

This is not an error but this getchar() function gives previous array's value why?

#include<stdio.h>
int main()
{
char a[10],b[10];
for(int i=0;i<10;i++)
{
a[i]=getchar();
}
for(int j=10;j<10;j++)
{
b[i]=getchar();
}
printf("%s",b);
}
In the above code the print section prints also the string a. Can you please explain why?
First, let us suppose true code is for(int j=0;j<10;j++) and not for(int j=10;j<10;j++)
In the above code the print section prints also the string a pls explain why?
Undefined behavior (UB).
"%s" expects a matching pointer to a string. Array b does not contain a string as it lacks a null character 1. Result: UB.
Likely code just kept on printing nearby data which happened to be the contents of a until it eventually encounter a null character somewhere.
Instead, append a null character or limit printing.
printf("%.10s",b);
// or
for(int j=0;j<(10-1);j++) { // start at 0 and up to 10-1
b[i]=getchar();
}
b[10-1] = '\0';
printf("%s",b);
1 a is not a string either as it too lacks a null character.

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] ="";

how to print a string in c without p┐ in the end of the string

so i've been writing a program that convert a decimal number to it's boolean representation but every time i compile the return value which is a string show additional characters like p┐ here is the program
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main (void)
{
signed char str[256];
int dec,rest;
int i = -1;
int j;
printf ("write a decimal number : ");
scanf ("%d",&dec);
do
{
rest = dec % 2;
dec/= 2;
for (j=i;j>-1;--j)
str[j+1]=str[j];
str[0]=rest+48;
++i;
} while (dec!=0);
printf ("the binary representation of this number is %s",str);
}
the output :
write a decimal number : 156
the binary representation of this number is 10011100p┐
i don't know if im missing something but i will be grateful if you guys help me
In C and C++, strings are null-terminated, this means that every valid string must end with a character with code 0. This character tells every function that is dealing with this string that it is in fact over.
In your program you create a string, signed char str[256]; and it is initially filled with random data; this means that you reserved space for 256 characters and they are all garbage, but the system does not know they are invalid. Try printing this string and see what happens.
In order to actually tell the system that your string is over after say, 8 characters, the 9th character hast to be the NUL character, or simply 0. In your code you can do it in two ways:
after the loop, assign str[i] = 0, or (even simpler)
initialize the string as signed char str[256]={0};, whiche creates the storage and fills it with nulls; after writing to the string you can be sure that the character after the last one you've written will be a NUL.
At the end of your do {} while () loop, you need to set the character after the last character in your string to 0. This is the array index of the last character you want (i) plus one. This lets printf know where your string ends. (Otherwise, how could it know?)
initialize the str variable to NUL.
void main (void)
{
signed char str[256];
int dec,rest;
int i = -1;
int j;
memset( str, '\0', sizeof(str) );
printf ("write a decimal number : ");
scanf ("%d",&dec);
do
{
rest = dec % 2;
dec/= 2;
for (j=i;j>-1;--j)
str[j+1]=str[j];
str[0]=rest+48;
++i;
} while (dec!=0);
printf ("the binary representation of this number is %s",str);
}

Given a string write a program to generate all possible strings by replacing ? with 0 and 1?

I have written this code it is working fine for a?b?c? and a?b?c?d? but for a?b?c?d?e? it is giving one additional garbage value at the end. At the end of s there is '\0' character attached then why and how is it reading that garbage value. I tried to debug it by placing printf statements in between the code but couldn't resolve it. please help.
#include<stdio.h>
void print(char* s,char c[],int l)
{
int i,j=0;
for(i=0;s[i]!='\0';i++)
{
if(s[i]=='?')
{
printf("%c",c[j]);
j++;
}
else
printf("%c",s[i]);
}
printf(", ");
}
void permute(char *s,char c[],int l,int index)
{
if(index==l)
{
print(s,c,l);
return;
}
c[index]='0';
permute(s,c,l,index+1);
c[index]='1';
permute(s,c,l,index+1);
}
int main()
{
char s[10],c[10];
printf("Enter a string.");
scanf("%s",s);
int i,ct=0;
for(i=0;s[i]!='\0';i++)
{
if(s[i]=='?')
ct++;
}
permute(s,c,ct,0);
return 0;
}
My output was like this :-
a0b0c0d0e0♣, a0b0c0d0e1♣,
...and so on.
As we can see from your code, with an array defined like char s[10] and the input being
a?b?c?d?e?
is too big an input to be held in s along with the null-terminator by
scanf("%s",s);
You need to use a bigger array. Otherwise, in attempt to add the terminating null after the input, the access is being made to out-of-bound memory which invokes undefined behaviour.
That said, never allow unbound input to the limited-sized array, always use the field-width to limit the input length (in other words, reserve the space for null-terminator), like
scanf("%9s",s);
The code is producing the correct output here, but note that it has undefined behavior for strings of size greater than or equal to 10 chars, because that's the size of your buffer.
So, for a?b?c?d?e? you need a buffer of at least 11 characters, to account for the null terminator. You should make s bigger.
See actually in C what happens in String is that everytime it appends a '\0' character at last.
Now notice in C there is nothing called string.
It's array of characters.
So if you have defined like this-
char s[10]
This actually accepts an array of less than of 9 characters as the last one will be the '\0' character.
If you add more than 9 character it will give erroneous output.

Resources