#include<stdio.h>
#include<ctype.h>
int peekchar() {
int c;
c = getchar();
if (c != EOF) {
ungetc(c, stdin);
}
return c;
}
int readNumber(void) {
int c;
int accumulator = 0;
while ((c = peekchar() != EOF) && isdigit(c)) {
c = getchar();
accumulator *= 10;
accumulator += c - '0';
}
return accumulator;
}
int main() {
int result = readNumber();
printf("%d\n", result);
return 0;
}
I am trying to read an integer written in decimal notation from stdin until the first non-digit. But its not giving the correct result:
M1508444:CProg sb054043$ gcc -g3 readNumber.c -o readNumber
M1508444:CProg sb054043$ ./readNumber
123
0
Can someone please help me identify the problem?
The issue is with operator precedence. c = peekchar() != EOF is grouped as c = (peekchar() != EOF), and so c is either 0 or 1, which accounts for the result.
Fix with (c = peekchar()) != EOF.
Or, given that isdigit is defined to be 0 for EOF, your loop conditional can be simplified to
while (isdigit(c = peekchar())){
Hi you need to modify your while loop like below:-
while ( (c = peekchar()) != EOF && isdigit(c)) {
c = getchar();
accumulator *= 10;
accumulator += c - '0';
}
First of all you need to read the value and store it in variable c and that you can achieve by doing (c = peekchar()). Once the value stored in c now your while loop will first check whether it is EOF if not then only it will check whether it is a digit or not.
Related
So currently I'm learning C from the C programming language 2nd edition book and it says that:
while (c = getchar() != EOF) {
}
is identical to:
while (c != EOF) {
c = getchar();
}
However, when I run the code I just had written:
#include <stdio.h>
int main() {
char c;
int times;
while (c = getchar() != EOF) {
if (c == 'a') {
++times;
}
}
printf("%d\n", times);
}
The value of times it outputs is 0 instead of actual value of times I typed in 'a' character.
Now in this code, it works fine:
#include <stdio.h>
int main() {
char c;
int times;
while (c != EOF) {
c = getchar();
if (c == 'a') {
++times;
}
}
printf("%d\n",times);
}
and if I type a 3 times, the value it outputs is 3.
Precedence!
c = getchar() != EOF
means
c = ( getchar() != EOF ) // Assigns `0` or `1` to `c`.
but you want
( c = getchar() ) != EOF
Also note that c needs to be an int.
This means you could use
for (int c; ( c = getchar() ) != EOF; ) {
...
}
but I prefer
while (1) {
int c = getchar();
if (c == EOF)
break;
...
}
Operator precedence.
!= operator is higher in precedence than =, so your expression is equivalent to:
while (c = (getchar() != EOF))
use a parenthesis around c=getchar() and it will work.
#include<stdio.h>
#include<ctype.h>
int peekchar() {
int c;
c = getchar();
if (c != EOF) {
ungetc(c, stdin);
}
return c;
}
int readNumber(void) {
int c;
int accumulator = 0;
while ((c = peekchar() != EOF) && isdigit(c)) {
c = getchar();
accumulator *= 10;
accumulator += c - '0';
}
return accumulator;
}
int main() {
int result = readNumber();
printf("%d\n", result);
return 0;
}
I am trying to read an integer written in decimal notation from stdin until the first non-digit. But its not giving the correct result:
M1508444:CProg sb054043$ gcc -g3 readNumber.c -o readNumber
M1508444:CProg sb054043$ ./readNumber
123
0
Can someone please help me identify the problem?
The issue is with operator precedence. c = peekchar() != EOF is grouped as c = (peekchar() != EOF), and so c is either 0 or 1, which accounts for the result.
Fix with (c = peekchar()) != EOF.
Or, given that isdigit is defined to be 0 for EOF, your loop conditional can be simplified to
while (isdigit(c = peekchar())){
Hi you need to modify your while loop like below:-
while ( (c = peekchar()) != EOF && isdigit(c)) {
c = getchar();
accumulator *= 10;
accumulator += c - '0';
}
First of all you need to read the value and store it in variable c and that you can achieve by doing (c = peekchar()). Once the value stored in c now your while loop will first check whether it is EOF if not then only it will check whether it is a digit or not.
I want to accept the string and the float value in between the '#' is present. I have tried some what like this but it's not working; it is taking the whole input as the string.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[10000];
float number;
scanf("%s#%f",str,&number); //input BMW#23.5 Expected output BMW 23.5
printf("%s %f\n",str,number); //actual output BMW#23.5 0.000000
}
Can anyone help me to solve this?
Get all as a char[] and parse it:
int main()
{
char str[10000];
float number;
scanf("%s", str);
char *at_pos = strrchr(str, '#');
if (at_pos)
{
number = atof(at_pos + 1);
// manage errors in number
printf("%s %f\n", str, number);
}
else
{
// manage error
}
}
//using the "[^#]" can really save your time.
//But you can do a lot in this approach of mine. Not just in that case.
//Feel free to ignore this but if you want to check and understand the logic there, there's the code that i wrote. Then you can just improve it. Tnx.
#include <stdio.h>
int main(void)
{
char str[10000];
char c;//The idea is, collect the input 1 by 1.
float f;
float power = 10;
int counter = 0;//We need this for the string.
c = getchar();//get the first character
str[counter] = c;//store it in the first element
counter++;
c = getchar();//Since we know that the input is string, we assume that there's a next character of course.
while(c != '#')
{
//But what if the user didn't enter a '#' character?
//Do this!
if(c == 10)
{
printf("I can't find the '#' there. =)\n\n");
return 0;
}
str[counter++] = c; //Test the recently collected character if
c = getchar(); //it's '#' or not. If not, then store it
} //in the string and continue to collect the
//next characters then store each of it in
//the string again and again until it reaches the '#'. From there you stop.
//after collecting all the characters, start collecting the numbers.
c = getchar();//collect
f = c - '0';//convert character to digit. I would bet you know this. Then store it in your float variable.
c = getchar();//collect again
//then test the recently collected again. Just like before
while(c != 10 && c != '.')//10 is the ASCII of the <enter> or new line right?. //We will also stop if we encounter '.' (dot)..
{
//while if it's not 10 or dot, add it your float variable. But don't forget the rules. use the power of 10 to.
f = f * 10 + (c - '0');
c = getchar();//collect again.
}
//do this again
c = getchar();
f += (c - '0') / power;//now divide it with power
c = getchar();
power *= 10;//then increase the power.
//Now collect the decimals
while(c != 10)//just like before
{
f += (c - '0') / power; //just do this over and
power *= 10; //over again until
c = getchar(); //it reaches the ASCII 10.
}
//Test it if you got it. =)
printf("%s # %f", str, f);
return 0;
}
//here's the clean code.
#include <stdio.h>
int main(void)
{
char str[1000];
char c;
float f;
float power = 10;
int counter = 0;
c = getchar();
str[counter] = c;
counter++;
c = getchar();
while(c != '#')
{
//But what if the user didn't enter a '#' character?
//Do this!
if(c == 10)
{
printf("I can't find the '#' there. =)\n\n");
return 0;
}
str[counter++] = c;
c = getchar();
}
c = getchar();
f = c - '0';
c = getchar();
while(c != 10 && c != '.')
{
f = f * 10 + (c - '0');
c = getchar();
}
c = getchar();
f += (c - '0') / power;
c = getchar();
power *= 10;
while(c != 10)
{
f += (c - '0') / power;
power *= 10;
c = getchar();
}
printf("%s # %f", str, f);
return 0;
}
I want to get an input from the user like (4,5).But I just want to get the integer values.(4 and 5) I wrote a code for this.But it did not work.How can I fix the problem.
int x, y;
int c;
c = getchar();
while (c != EOF) {
while (c != '(' && c != EOF) {
c = getchar();
}
while (c != ',' && c != EOF) {
c = getchar();
}
x = c;
while (c != ',' && c != EOF) {
c = getchar();
}
while (c != ')' && c != EOF) {
c = getchar();
}
y = c;
}
I get input(1,4). outputs is x= 44 and y= 45 ?
After you find the opening parenthesis, read characters while they are digits (see e.g. isdigit), and create your number.
When the character is not a digit, make sure it's a comma. If it is you read the next number the same as above. Finally make sure you got the closing parenthesis.
The above assumes that there are no whitespace between the parentheses and the numbers, or between the numbers or the comma. Those can be handled by looping and isspace.
As for converting digits to numbers, assuming your system is using ASCII encoding (which is standard on modern PC-like systems) then it's easy since you just subtract '0' from the character to get the digit (see the linked ASCII table to help you understand why). Store the value in a variable, initialized to zero, and multiply by ten as needed.
Depending on the parser you're writing, you could do the handling and recognition of tuples in the parser instead of the lexer. That would make it more flexible.
follow your code flow x value will be character comma.
int c ,x ,y;
c = getchar();
while (c != EOF) {
while (c != '(' && c != EOF) {
c = getchar();
}
c = getchar();
x = c;
while (c != ',' && c != EOF) {
c = getchar();
}
/*x = c;
while (c != ',' && c != EOF) {
c = getchar();
}
*/
c = getchar();
y = c;
while (c != ')' && c != EOF) {
c = getchar();
}
//y = c;
printf("x = %c ,y = %c ",x,y);
}
My question is based on a CodeChef problem called Lucky Four.
This is my code:
int count_four() {
int count = 0;
char c = getchar_unlocked();
while (c < '0' || c > '9')
c = getchar_unlocked();
while (c >= '0' && c <= '9') {
if (c == '4')
++count;
c = getchar_unlocked();
}
return count;
}
int main() {
int i, tc;
scanf("%d", &tc);
for (i = 0; i < tc; ++i) {
printf("%d\n", count_four());
}
return 0;
}
Let's say I make a slight change to count_four():
int count_four() {
int count = 0;
char c = getchar_unlocked();
while (c >= '0' && c <= '9') {
if (c == '4')
++count;
c = getchar_unlocked();
}
while (c < '0' || c > '9') // I moved this `while` loop
c = getchar_unlocked();
return count;
}
This is my output after moving the while loop below the other one:
0
3
0
1
0
instead of:
4
0
1
1
0
The input used to test the program:
5
447474
228
6664
40
81
Why is this happening? How do getchar() and getchar_unlocked() work?
getchar_unlocked is just a lower level function to read a byte from the stream without locking it. In a single thread program, it behaves exactly like getchar().
Your change in the count_four function changes its behavior completely.
The original function reads the standard input. It skips non digits, causing an infinite loop at end of file. It then counts digits until it gets a '4'. The count is returned.
Your version reads the input, it skips digits, counting occurrences of '4', it then skips non digits, with the same bug on EOF, and finally returns the count.