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);
}
Related
Going through Kernighan, and I am coding on visual studio with windows. Why doesn't the following program doesn't pick up tab characters, new lines, or spaces? I have to manually type its associated integer. Here's the word count program:
#define IN 1 /*State of being inside word*/
#define OUT 0 /*State of being outside word*/
countWords() {
int c, nl, nw, nc, state;
state = OUT;
nl = (nw = (nc = 0));
while ((c = getchar() != EOF)) {
nc++;
if (c == '\n') {
nl++;
}
if (c == ' ' || c == '\n' || c == '\t') {
state = OUT;
}
else if (state == OUT) {
state = IN;
nw++;
}
printf("%d %d %d\n", nl, nw, nc);
}
}
My test input was 'one two three' and the output was '0 1 14'. Indicating that it didn't recognise space character ' '. Is there a setting on VS that needs to be changed to get this working?
Be careful with operator precedence.
while ((c = getchar() != EOF)) {
The c variable gets the boolean value of the expression getchar() != EOF. It doesn't hold the character that was read in like you are probably expecting.
You probably meant to write it as:
while ((c = getchar()) != EOF) {
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.
int getop(char *s) {
int i, c;
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if(!isdigit(c) && c != '.') {
return c;
}
i = 0;
if(isdigit(c))
while(isdigit(s[++i] = c = getch()))
;
if(c == '.')
while(isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if(!isdigit(c))
ungetch(c);
return NUMBER;
}
I came across this fucntion while working on an example named "Reverse polish calculator".
we can input numbers for calculator operations via this function, but I'm not getting the working of this function. Like.,
if we enter some input like ---->
12.34 11.34 +
From
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
s will contain 1. But from where does the remaining input goes inside s ?
I've gone through this function well and I came to know it's working but then I want to know the deep working, like the complete flow.
Any help is highly appriciated.
edit:-
After testing various inputs I came to the conclusion that what is the need for getch() and ungetch(), I mean yeah they are there to unread character that is not needed but than look at the test cases.,
int getop(char *s) {
int i, c;
while((s[0] = c = getchar()) == ' ' || c == '\t')
;
s[1] = '\0';
if(!isdigit(c) && c != '.') {
return c;
}
i = 0;
if(isdigit(c))
while(isdigit(s[++i] = c = getchar()))
;
if(c == '.')
while(isdigit(s[++i] = c = getchar()))
;
s[i] = '\0';
/* if(!isdigit(c))
ungetch(c);*/
return NUMBER;
}
Here I replaced getch() with getchar() and it still accepted the input
12a 12 -
and the output was absolutely correct and it unread 'a' character as well
144
and so was the case when I was using getch() ?
Lets break it down piece by piece:
while((s[0] = c = getch()) == ' ' || c == '\t') skips all spaces and tabulation from the beginning fo the string. At the end of this loop s[0] contains the first char which is not either of the two mentioned before.
Now if c is something other than . or a digit we simply return that.
if(!isdigit(c) && c != '.') {
return c;
}
If c is not a digit we are done and it's quite right to set s[1] to null!
Otherwise, if c is a digit we read as much digit chars as we can overwriting s from position 1. s[1] was '\0' but it does not matter because s[++i] would be s[1] at the very first iteration of
i = 0;
if(isdigit(c))
while(isdigit(s[++i] = c = getch()))
so s is kept in a consistent status.
This code takes multiple fs and prints only 1. Can someone please explain to me why this code does not print two fs? putchar appears twice while not EOF. I have been staring at it for hours and I do not understand how it prints only 1 f.
The code is functioning correctly. I just do not understand how it works step by step.
/* A program that takes input of varied 'f's and out puts 1 f */
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF)
{
if (c == 'f')
{
putchar(c);
}
while (c == 'f')
{
c = getchar();
}
if (c != EOF) putchar(c);
}
}
Thanks
I'll step through with comments in the code; for f (or in reality f\n) as input:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) // You type f and hit return key (remember this)
{
if (c == 'f') // c contains 'f' is true
{
putchar(c); // print 'f'
}
while (c == 'f') // c == 'f' is true
{
c = getchar(); // '\n' is buffered on stdin from return key
// so getchar() returns '\n'. So c will be set to '\n'
// It goes back to the while loop and checks if c == 'f'
// but it's not, it's '\n'! So this will run once only.
}
if (c != EOF) putchar(c); // '\n' != EOF, so print '\n' newline, back to loop
}
}
Thus giving f\n as input will yield the output f\n
In the case of input fffff (in reality fffff\n), see below:
#include <stdio.h>
main()
{
int c;
while ((c = getchar()) != EOF) // You type fffff and hit return key
{
if (c == 'f') // c contains 'f' is true, first 'f'
{
putchar(c); // print 'f'
}
while (c == 'f') // First loop, c == 'f'
// Second loop, c == 'f'
// Last loop, c == '\n', so false
{
c = getchar(); // First loop: 'ffff\n' is still buffered on stdin
// c = 'f', loop again
// Last loop: c = '\n'
}
if (c != EOF) putchar(c); // '\n' != EOF, so print '\n' newline, back to loop
}
}
You see that your inner while loop will eat all the f until you hit \n, thus the same affect as above.
if(c == 'f')
putchar(c);
This prints one f, the one you see.
while(c == 'f')
getchar(c);
This is where the f disappears. If you just used putchar(c) before, that means that the loop will execute at least once because c == f. So the f is gone (c != f)
Finally, you just use putchar(c) on the first character which is not f.
int getop(char s[])
{
int i = 0, c, next;
/* Skip whitespace */
while((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
/* Not a number but may contain a unary minus. */
if(!isdigit(c) && enter code herec != '.' && c != '-')
return c;
if(c == '-')
{
next = getch();
if(!isdigit(next) && next != '.')
return c;
c = next;
}
else
c = getch();
while(isdigit(s[++i] = c)) //HERE
c = getch();
if(c == '.') /* Collect fraction part. */
while(isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if(c != EOF)
ungetch(c);
return NUMBER;
};
what if there is no blank space or tab than what value will s[0] will initialize .......& what is the use of s[1]='\0'
what if there is no blank space or tab than what value will s[0] will intialize
The following loop will continue executing until getch() returns a character that's neither a space nor a tab:
while((s[0] = c = getch()) == ' ' || c == '\t')
;
what is the use of s[1]='\0'
It converts s into a C string of length 1, the only character of which has been read by getch(). The '\0' is the required NUL-terminator.
If there is no space or tab, you're stuck with an infinite loop.
s[1]='\0' is a way of marking the end so functions like strlen()
know when to stop reading through c strings. it's called "Null-Terminating" a string: http://chortle.ccsu.edu/assemblytutorial/Chapter-20/ass20_2.html
while((s[0] = c = getch()) == ' ' || c == '\t')
Read character until its not a tab or space.
s[1] = '\0';
Convert char array s to a proper string in C format (all strings in c must be terminated with a null byte, which is represented by '\0'.