how to scan a character and integer together in c - c

I am writing code for scanning character and integer together in the format like
R 2
but the following code gives unexpected result and i am not able to scan a character and integer togather
int main()
{
long int m,i;
scanf("%ld",&m);
char que[m];
long int d[m];
for (i=0; i<m; i++) {
scanf("%c ",&que[i]);
scanf("%ld",&d[i]);
}
for (i=0; i<m; i++) {
printf("%c %ld",que[i],d[i]);
}

You have to add a space before the %c in scanf() to excape the left out newline \n character.
After the change, the code works fine, check out below..
#include<stdio.h>
int main()
{
long int m,i;
scanf("%ld",&m);
char que[m];
long int d[m];
for (i=0; i<m; i++) {
scanf(" %c",&que[i]);
scanf("%ld",&d[i]);
}
for (i=0; i<m; i++) {
printf("%c %ld\n",que[i],d[i]);
}
}

First of all, if you create array like this:
char que[m];
You will create a static array of char, which is needed to be given an exact value (and also can't be changed/constant) of how big you want your array to be, so you can't put 'm' there. The same goes to:
long int d[m];
Second, if you use C, you really can't declare the data type of variable after you use a function in your program (in your case, you declare the array of char and array of long int after you put scanf()).
Third, if you press 'Enter' after give the input, the input will be read by line 1 (i = 0), and will put \n in line 2 (i = 1), because the \n is still in the buffer (in scanf() case, stdin). It's one of an error that will happen if you use scanf(). There is at least 2 solutions to this:
1.Put fflush(stdin) after every scanf() (not recommended since fflush() is supposed to be used with output stream, not input stream)
2.Create a function like this:
void clear(void) {
while (getchar() != '\n');
return;
}
and use clear() after every scanf().

Related

2D array of characters, printing extra character over limit?

The output of code
I want to create an array of character in which there are 'n' rows and each row have a character. In the given code I asked the user to enter the number of rows(n) then I create a variable 'chr' and each row contain only one character. Then I asked the characters one by one and store them in their respective rows but when I take the print of those characters something strange happens. The first row which should only store one character of its own stores all the characters of different rows. Why? can anyone explain to me this?
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
char chr[n][1];
for (int i = 0; i < n; i++) {
printf("Enter the %d character?\n", i);
scanf("%s", chr[i]);
}
// printing
for (int i = 0; i < n; i++) {
printf("\n%s\n", chr[i]);
}
return 0;
}
The first row which should only store one character of its own stores all the characters of different rows. Why? can anyone explain to me this?
scanf("%s", chr[i]);
%s reads a whole string until it encounters a white space character, such as newline \n, and writes it (excluding the white space character) into the first dimension; not only one character.
You also forgot that since you are trying to read a string a \0 is automatically appended to each string, but since the declaration of chr there is just place for one character in a dimension, not two.
A multi-dimensional array is allocated continously in memory, which provides the effect that the \0 character for the string in the previous dimension is stored at the first and only character of the next dimension; in the next iteration scanf overwrites then this \0 character to store the second character but again writes the \0 of this string into the first an only object of the following dimension and goes so on and on for each iteration, which ends up in a complete mess of Undefined Behavior, plus the \0 of the last string is written beyond the bounds of the complete multi-dimensional array.
So you can´t even say that they were stored in just one dimension, which isn´t the case, even if it seems like it would.
For more information about Undefined Behavior look at this question:
Undefined, unspecified and implementation-defined behavior
Rather use
scanf(" %c", &chr[i][0]);
with the %c format specifier to read only one character per iteration and implement a white space character before the %cformat specifier to catch the newline \n left in stdin by the scanf consumption of the previous loop walkthrough or any leading white space.
Also, change:
for(int i = 0; i<n; i++) {
printf("\n%s\n", chr[i]);
to
for(int i = 0; i<n; i++) {
printf("\n %c \n", chr[i][0]);
The whole code shall then be:
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
char chr[n][1];
for(int i = 0; i<n; i++) {
printf("Enter the %d character?\n", i);
scanf(" %c", &chr[i][0]);
}
// printing
for(int i = 0; i<n; i++) {
printf("\n %c \n", chr[i][0]);
}
return 0;
}
as to answer why its printing the other caracters, they are directly behind each other in memory, and as others pointed out since you told it to print a string, it treats those chars in a row as one string (which is an array of chars) until it encounters a termination char.
so in memory this
char array[3][1] = {{'a'},{'b'}{'c'}};
looks just like this:
char array[3] ={'a','b','c'};
or this
char array[3] = {"abc"};
the array variable is a pointer to the address in memory where the first char is positioned, if you use [] you just jump sizeof(char) amount of bytes to the next char,
with the 2D array this is similar, the 1st bracket makes you jump sizeof(2darray[0]) bytes, which is in this case the same as sizeof(char) since length is 1

How to scan input from terminal and add to array?

as a homework assignment for my computing 1 college course, my professor has given me the task of having the user input a string of characters into the terminal, taking that string, adding it into an array, then printing the array and printing the array backwards. I think that I know of a way to print the array backwards, however, I cannot come up with a way to read from the terminal and add the characters from the terminal to an array. I have tried doing the following:
char ch;
for (int i = 0; i <= 80 || str[i] == '\n'; ++i) {
scanf_s("%c", &str[i]);
}
I am wondering if someone could explain to me why this section of code does not operate as expected, and if someone could give me some other ideas to try. Thank you.
You are using scanf_s with %c specifier incorrectly.
Please take notice of compiler warnings, there is a size argument missing.
Microsoft's scanf_s is not a direct replacement for scanf.
Unlike scanf ... scanf_s ... requires the buffer size to be specified for all input parameters of type c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable.
scanf_s("%c", &str[i], 1);
You might also want to filter out any newline which may have been left in the buffer, with
scanf_s(" %c", &str[i], 1);
notice the added space.
Why your code is showing this type of behaviour...
use scanf instead of scanf_s
the conditions you have provided in the for loop are wrong
#include <stdio.h>
int main()
{
char ch;
char str[1000];
int i;
for (i = 0; i <= 80 ; i++)
{
scanf("%c", &str[i]);
if(str[i]=='\n')
{
str[i]='\0';
break;
}
}
printf(str);
}
I could show you the same task in simple manner. I have tried to answer your question in your way. That's why it may seem complicated.
#include <stdio.h>
#define MAX 25
int main()
{
char buf[MAX];
fgets(buf, MAX, stdin);
printf("%s\n", buf);
return 0;
}
fgets- Reads until new line character encountered or maximum limit of character array.

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.

Unable to convert values from lowercase to uppercase using toupper

i'm attempting to create a program that asks the user to firstly enter the amount of values they would like to convert from lowercase to uppercase. The for loop then assigns each value into an array. The array then goes through another for loop to convert the values into uppercase using LowerToUpper function.
When i go to run the program, it will take in values and then start doubling them on the command window, and will cease when you have completed entering the values, rather than printf the results. Could you please explain why. Thank you in advance
#include<stdio.h>
#include <string.h>
#include <ctype.h>
void LowerToUpper(char* array)
{
toupper(*array);
}
int main(void)
{
int i, amount;
printf("How many values?\n");
scanf("%d", &amount);
char *d;
char array1 [amount];
printf("Please enter the values\n");
for(i=0; i<amount; i++)
{
scanf("%c", &array1[i]);
}
for(i=0; i<amount; i++)
{
d=&array1[i];
LowerToUpper(d);
scanf("%c", &array1[i]);
printf("%c", array1[i]);
}
return 0;
}
You are not using toupper() properly. The function returns the converted value in case of success. You need to make use of the returned value. The supplied argument is not changed.
That said, the program structure is unnecessarily complicated. you can simplify it like
for(i=0; i<amount; i++)
{
int result = toupper (array1[i]);
if (result != array1[i]) printf("%c", result); //just checkin', if converted
}
That said, you have many other issue which you don't see at this moment, like
scanf("%c", &array1[i]);
this will, to your surprise, only ask you for half the number of inputs. Why? You forgot to ignore the newline entered by RETURN key.
Then, you did not check for the success of scanf("%d", &amount); call. In case, the scanning fails, you'll end up with undefined behavior.
The second scanf() inside the last for loop is probably something you don;t want, it's useless, at best.
Change this:
toupper(*array);
to this:
*array = toupper(*array);
since toupper ref's mentions:
Return Value
The uppercase equivalent to c (*array in your case), if such value exists, or c (unchanged) otherwise. The value is returned as an int value that
can be implicitly casted to char.
PS: Defining a function LowerToUpper() for this operation (one line of code) is an overkill, and you could call that one line of code inside main() instead (I mean the body of the function to be moved into main()).

Problem while scanning a char and float simultaneously

I am trying to take five character and 5 float input.
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
scanf("%f",q+i);
}
}
But the output is absurd. After two sequential scans, it skips third scan and then again skips fifth scan.
I am not able to understand why is it showing such a behaviour.
I am working on gcc compiler.
Use of scanf is not recommended because of problems like this.
Instead use fgets to read the entire line and then use sscanf to extract what you want(a char or a float) from the line just read:
char line[MAX];
for(i=0;i<5;i++)
{
if( fgets(line,MAX,stdin) && sscanf(line,"%c", c+i)!=1 )
*(c+i) = 0;
if( fgets(line,MAX,stdin) && sscanf(line,"%f", q+i)!=1 )
*(q+i) = 0.0;
printf("%c %f\n",*(c+i),*(q+i));
}
To directly answer why the 3rd and every other scan "skips", it is the way scanf() and the %c format works. When there is a call to scanf(), you typically have to press enter to "submit" the input. Consequently that inserts a newline character into the stdin stream.
When the previous float scan got inputted, the newline is still left in the stream. When the character scan gets reached, that remaining newline character is read in since it fits effectively "skipping" the call.
You should use fgets() with sscanf() as codaddict suggests.
But as a quick fix, you could try adding a call to getchar() after the float scan to consume that newline character from the stream.
edit:
You're saying this doesn't work? (assuming you input the correct kinds of values, one per scanf call)
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
scanf("%f",q+i);
getchar();
}
}
You should try this:
int main(){
char c[6];//char array size must be 6 to store five charecter
//as null-terminator('\0')will use the last one
float q[5];
int i;
for(i=0;i<5;i++){
printf("\n%d\n",i);fflush(stdout);
scanf("%c",&c[i]);fflush(stdin);//fflush(stdin) to clear input stream that
//next scanf() won't skip
scanf("%f",&q[i]);fflush(stdin);//fflush(stdin) to clear input stream that
//scanf() won't skip at new loop
}
return 0;
}
fflush() is not defined on an input stream, like stdin. Don't do it.
If you want to "read and discard until newline", then do:
int ch;
do {
ch = getchar();
} while (ch != EOF && ch != '\n');
Note that %c means "read the next character in the input stream, even if it's whitespace, then stop". %f means "read and discard whitespace, then try to read a float from the input stream, then stop."
Your code should be like this :
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
while (getchar()!='\n');
scanf("%f",q+i);
while (getchar()!='\n');
}
}
the sentence while (getchar()!='\n'); search till the end of input, so it would not take '\n' as an input value for q+i.Also another while (getchar()!='\n'); after scanf q+i,since you use loop.
Problem in scanning a char value after a float value.
Solution is very simple!!!
instead of writting your code like this
scanf("%c",&...)
try this,
scanf(" %c",&...)
A Space before the"%c" will resolve the problem by neglecting the value of the Return(Enter) key when pressed after typing the value of the float as an input.
When a float value is scanned before a character value.
The value obtained by pressing the Return(Enter) key is collected in the following char variable. Using a space before(" %c",&...) discards the value collected of the Return(Enter) Key, Causing the Char value to be scanned in the next line. Thus solving The Scanning Float-Char problem.

Resources