Reversed char array prints both the output and input? - arrays

Trying to input a 2 digit number e.g '35' and have the output return '53', however, my code makes it so that the output is '5335' rather than just '53' im completely lost and have been hunting for previous answers for hours to no success.
#include <stdio.h>
int main (void) {
char input[2];
char output[2];
int length;
printf("Enter a two-digit positive integer: ");
scanf("%s", input);
length = sizeof(input);
int x = 0;
while(length >=0) {
length--;
output[x]=input[length];
printf("%s", output);
x++;
}
printf("The reversed number is: %s", output);
return 0 ;
}

There are multiple things that needs to be changed in the code.
The char array length must be 3 in this case as your char ararys are supposed to store 2 characters. (One extra character for the null-terminating character '\0')
The length variable will store the number of bytes occupied by the character array but not the number of characters in the array. You might consider doing
length = sizeof(input)/sizeof(char)
Doing the modifications as mentioned in 1st and 2nd points will still result in an invalid result because the first thing you are appending to the input is the last character which will be '\0' and the output will always be an empty string. You should start appending from the 2nd last character of the input string and finally append a null-terminating character in the output.
Note:- It would be great if you can brush up on your knowledge of fundamental concepts of C.

Related

Count the amount of occurrences of a character in a string: how can I interpret this code?

The assignment asks to print out the number of times a chosen character appears in an input (no length limit) string. I wanted to solve it by only using do or do-while loops, and after a bit of googling I found this code (source: https://www.tutorialgateway.org/c-program-to-count-all-occurrence-of-a-character-in-a-string/.).
I get the gist of it, but there are many things I still haven't covered, such as the meaning of str[i], the meaning of the variable ch, and kind of how the structure works. How can I interpret it piece by piece? Or if there's any simpler way, how can I work on it? I'm a beginner and I fear this is much easier than expected but I don't have the base to move on, thank you
#include <stdio.h>
#include <string.h>
int main() {
char str[10], ch;
int i, Count;
i = Count = 0;
printf("\n Please Enter any String : ");
gets(str);
printf("\n Please Enter the Character that you want to Search for : ");
scanf("%c", &ch);
while (str[i] != '\0') {
if (str[i] == ch) {
Count++;
}
i++;
}
printf("\n The Total Number of times '%c' has Occurred = %d ", ch, Count);
return 0;
}
Well i am giving an easy example regarding that problem with a proper explanation. Hope you might understand.
char is a datatype which will accepts character type of variable. Here str[100] will be an array of length 100, where we will store our search example. ch is a character type variable where we will store the character for which we will find the concurrence.
i and count are integer variables where i will be loop variable and the count will keep count of the concurrence.
after taking the text string using puts function we are storing it in the str[100] array.
then we are taking the search letter and stored it in ch.
we are now running for loop from 0 to the length of the string we have given.
strlen() function returning us the length.
now str[i] will search from i=0 to the length size of the string. each time loop will go forward one by one letter and compare the letter with the letter inside ch.
if match found then we will increase the count value.
after the ending of the loop count will be the result of the concurrency.
reference: Concurrency of a letter in a string
#include <stdio.h>
#include <string.h>
int main()
{
char str[100], ch;
int i, Count;
Count = 0;
printf("\n Please Enter any String : ");
gets(str);
printf("\n Please Enter the Character that you want to Search for : ");
scanf("%c", &ch);
for(i = 0; i <= strlen(str); i++)
{
if(str[i] == ch)
{
Count++;
}
}
printf("\n The Total Number of times '%c' has Occured = %d ", ch, Count);
return 0;
}
The code has the following parts:
1)The header files: These contain predefined functions like scanf() which you use in your program
2)The main function: Here you are performing your character count. Usually, this function contains the driver code for the program
ch is a variable for the character you want to count in your string. You are taking this as input from the user using scanf()
str is the string you are performing your count operation in. It is also taken as input.
str[i] is used to denote the index i in the string. For example in "test", the index of 's' will be 2 as it is the 3rd character and your index starts from 0.
Final note: I recommend going through the basic syntax and usage of arrays if you do not know indexing. Also, as someone commented, do not use gets(). It causes security issues in programs as user can access stack values by giving malicious inputs containing format specifiers.
Instead, use a scanf with proper format specifiers or use fgets() when accessing content from files.

Function made for counting Letters in C doesn't work for the weirdest reasons

I have an assignment to make which has been giving me a headache. I have an array of characters
called "word[]". It's at most 64 chars long, which is why 'i' is counting up to that number.
Now I want to count all the vowels in that array, but for some reason it's telling me that
there is one more vowel than there really is, up to a number of 9 vowels. From 9 vowels onward, it seems to be giving me the correct number of vowels.
#include<stdio.h>
#include<ctype.h>
int vowelcounter(char word[]) {
int count = 0;
for (int i=0; i<64; i++) {
word[i] = toupper(word[i]);
if (word[i]=='A' || word[i]=='E' || word[i]=='I' || word[i]=='O' || word[i] == 'U') {
count++;
}
}
return count;
}
int main() {
char word[64];
scanf(" %s", word);
printf("Number of vowels is %i\n", vowelcounter(word));
return 0;
}
I tried to have a switch case instead of a if case, but to no avail.
OP's Problem:
The user may enter a string shorter than the max length, you should iterate through the array until you find the \0 character. Or calculate it's length with strlen and use it as a stopping point.
As is, you haven't initialised the array to 0, and iterate through the whole array regardless of the length of the string. Hence undefined behaviour.
Buffer Overflow Vulnerability:
The program is vulnerable to a buffer overflow. What's stopping one to enter more than 64 characters at a time? Consider using fgets to read a whole line instead, and then parse it accordingly. It reads at most n - 1 characters and nul-terminates the string.

C multidimensional array pointing problem?

Trying to take strings as input and place it in 2d array. Why is this given code showing different behavior. The last for loop "arr[i][j]" is not printing the string.It is not even printing a character also.
Why this code does not work.only this code.Not a new way to write it
This code takes input just fine(or at least the way needed.each row a single string no white space)And when a short string is stored remaining are filled with null after carriage return. When the arr[] is passed in last for loop everything seems fine only when arr[][] is passed ,the problem arises.But again arr[][] is initialized as arr[1][0] then arr[2][0] so should not it work!
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("please enter a string");
scanf("%s",&arr[i][j]);
/*j is always 0. arr[i] takes string without space and store ending with null*/
break;
}
}
//Everything fine upto this,including storing a small continuous string in arr[i](where i<50) and null terminating*/
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("%s\n",arr[i][j]);
break;
}
}
}
You program has several issues, like using wrong format specifier:
scanf("%s",&arr[i][j]);
arr[i][j] is a character and you are using %s format specifier. If you want your program should take string as input, you just need to do:
scanf("%s",arr[i]);
Since, you have given the size 50 characters, put a restriction in scanf() to not to read more than 49 characters (the remain one character space is for null terminating character) like this:
scanf("%49s",arr[i]);
^^
Beware with this, it does not discard the remaining input from input stream when the input characters are more than 49 and the remaining characters will be consumed by consecutive scanf() call.
If you want to drop the extra input which wasn't consumed by scanf(), one way of doing it is to read and discard the extra input using a loop, like this:
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
In case if you have any doubt on how this will discard the extra input, I would suggest first go through getchar().
Putting all these together, you can do:
#include <stdio.h>
int main(void){
int i,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter a string");
scanf("%49s",arr[i]);
int c;
while((c = getchar()) != '\n' && c != EOF) // <=== This loop read the extra input characters and discard them
/* discard the character */;
}
for(i=0;i<m;i++){
printf("%s\n",arr[i]);
}
return 0;
}
EDIT
The below edit is because OP updated question and added - Why this code does not work.only this code.Not a new way to write it
Above in my answer, I have already stated that you are using wrong format specifier in the scanf(). In this part of your code:
for(i=0;i<m;i++){
for(j=0;j<50;j++){ // <====== Nested for loop
printf("please enter a string");
scanf("%s",&arr[i][j]);
// since the nested loop is supposed to run 50 times, assuming you are trying to read character by character and using %s format specifier
break;
// the nested loop will break in the first iteration itself unconditionally, do you really need nested loop here!
}
}
Check the inline comments. Hope this might give an idea of the mistakes you are doing.
Seems that you want to read string character by character using scanf(). If this is the case than make sure to take care of null terminating character because, in C, strings are actually one-dimensional array of characters terminated by a null character '\0'.
You can do:
#include <stdio.h>
void discard_extra_input() {
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
}
int main(void){
int i,j,m;
printf ("Enter number of strings: ");
scanf("%d",&m);
discard_extra_input();
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter string number %d: ", i+1);
for(j=0;j<49;j++){
scanf("%c",&arr[i][j]);
if (arr[i][j] == '\n') {
//need to add null terminating character manually
arr[i][j] = '\0';
break;
}
}
if (j==49) {
// In case where the input from user is more than 50 characters,
// need to add null terminating character manually.
arr[i][j] = '\0';
// discard the extra input when input from user is more than 50 characters.
discard_extra_input();
}
}
for(i=0;i<m;i++){
for(j=0;j<50 && arr[i][j]!='\0';j++){
printf("%c",arr[i][j]);
}
printf ("\n");
}
return 0;
}
The code is self explanatory except one thing - call to discard_extra_input() function after first input from user scanf("%d",&m);. Reason -
Look at the statement:
scanf("%c",&arr[i][j]);
the %c format specifier will consume the leftover newline character '\n' from the input stream due to the ENTER key pressed after first input by the user (number of strings input from user). Hence, in order to discard it, calling discard_extra_input() function. In the other place it has been used to discard the characters when user entered string of size more than 49.
Hope this helps.
I know the code. But looking for specific ans. Where the problem lies with the code
The problem is here:
scanf("%s",&arr[i][j]);
and here:
printf("%s", arr[i][j]);
This is the specific answer you are looking for.
%s won't do any bound checking. It adds the characters starting from the memory location arr + i * m + j to arr + i * m + j + (length of input) + 1 (one extra char for the additional null character that scanf appends). Take a sample input. Assume an arbitrary starting address for arr and do the maths.
Also consider any writes beyond the allocated space for arr leads to undefined behavior.
Similarly printf("%s", arr[i][j]); will try to start reading from the address arr[i][j] till it finds a null character. It would usually lead to crash of the code because if your string has ascii characters, the address would be too low to point to any valid user-mapped memory.
If your code is working, its mostly because you already have a UB in your scanf.
Get a pen and paper and do some dry runs
This is a pretty simple problem buddy. You've got the idea right actually, that you need to use 2d array to store strings. Just that the usage is slightly wrong.
First of all let me tell you how 2d arrays need to be used to store in c. In your 2-D array, you've got rows and columns. Say, row represented by i and columns by j, i.e, each row arr[i] contains j elements. So in your context, each row arr[i] contains each string of upto 50 chars. So scanf should be just for arr[i]. And you need to loop with for, m times to accept m strings.
Same applies to printing as well.
Here is the working code:
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
printf("\nenter m value:");
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("\nplease enter a string no %d: ", (i+1));
scanf("%s",arr[i]);
}
printf("\nthe strings are: \n");
for(i=0;i<m;i++){
printf("\n%s\n",arr[i]);
}
}
And the output in case you want to cross check:
OUTPUT:
enter m value: 3
please enter a string no 1: qwerty
please enter a string no 2: asdfgh
please enter a string no 3: zxcvbn
the strings are:
qwerty
asdfgh
zxcvbn

Allocating Memory to String at runtime

I am writing a program to count the occurrence of '2' followed by '1' in a sting.
I dynamically allocated string
Code is:
#include <stdio.h>
#include<stdlib.h>
int penalty_shoot(char* s){
int count=0,i=0;
while(s[i]!='\0'){
if(s[i]=='2')
if(s[i+1]=='1')
count++;
i++;
}
return count;
}
int main() {
int t;
int i=0;
scanf("%d",&t); //t is for number of test cases.
while(t--){
char *str, c;
str = (char*)malloc(1*sizeof(char));
while(c = getc(stdin),c!='\n')
{
str[i] = c;
i++;
str=realloc(str,i*sizeof(char));
}
str[i] ='\0';
printf("%s\n",str);
printf("%d\n",penalty_shoot(str));
free(str);
str=NULL;
i=0;
}
return 0;
}
Input is :
3
101201212110
10101
2120
I am facing 2 problems:
1) I feel the dynamic allocation is not working fine.I wrote the code for dynamic allocation seeing various codes on stackoverflow . (Can anyone suggest some changes.)
2) The code isn't reading '2120' as the 3rd input.
(why is it so ?)
Three errors:
Not checking for EOF:
Change while(c = getc(stdin),c!='\n') to while(c=getc(stdin),c!='\n'&&c!=EOF)
Reallocating with the wrong number of bytes:
Change str=realloc(str,i*sizeof(char)); to str=realloc(str,(i+1)*sizeof(char));
After taking one character input we increment i (i++), so the next character will be stored at the ith position. Now, in order to store the character at ith position, the length of the character array must be i+1. So, we realloc with i+1.
Just for the sake of brevity, as suggested by Basile, you
might as well do this:
Change str=realloc(str,(i+1)*sizeof(char)); to str=realloc(str,i+1);
Why? Because sizeof char is 1 byte
Not consuming the \n after inputting t:
Change scanf("%d",&t); to scanf("%d ",&t); or scanf("%d\n",&t);
scanf("%d ",&t); or scanf("%d\n",&t);.
Either of them works. Why, you ask? Read this explanation taken from another SO answer here:
An \n - or any whitespace character - in the format string consumes
an entire (possibly empty) sequence of whitespace characters in the
input. So the scanf only returns when it encounters the next
non-whitespace character, or the end of the input stream.
Tested here.
you can use scanf("%d ", &t); when user input to test
then just before second while loop, which condition should be c != '\n' write c = getchar();
and then make sure you create a char variable, i called mine clear, that receives 0 so when you loop after initiating your string you write c = clear; and under it c = getchar() again. and when you use realloc make sure you make it bigger by (i+1) since char is only the size of 1 byte.
we create the clear variable in order to clear the buffer.
it worked for me. make sure you insert the string all at once.

Reading multiple user input strings inside a loop

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

Resources