Let's say that we have a very simple code that begins like:
#include <stdio.h>
int main() {
char c;
int x;
printf("Num here: ");
c = getchar();
x = 0;
while (c!=EOF) {
x = c - 48; //to convert x from ASCII
In this program, I'm trying to get the user to type a number (ex. 42) and am trying to add the ones digit to the tens (and to the hundreds, etc.); I'm having a lot of trouble understanding how you can get the while loop to go back to the loop until the end of the number.
So, I need a lot of help understanding how I can get the loop to read until the end of the character, read the char input the user puts in as a number (42), and then, treat the numbers individually using just getchar().
Normally, you'd use:
int c; // Because getchar() returns an int, not a char
int x = 0;
while ((c = getchar()) != EOF)
{
if (isdigit(c))
x = x * 10 + (c - '0');
else
...
}
This reads a character each time it reaches the top of the loop. You get the loop to go back by running into the brace at the end of the loop (or, occasionally, by using a continue statement). You might exit the loop with a break, for example if you read some character that can't be part of a number.
If the user types 42 (followed by Enter), then you first read c == '4' and then c == '2' and then you read newline '\n'. For every digit from '0' to '9', digit - '0' yields the number corresponding to the digit. The newline can't be part of the number, so you either put it back with ungetc(c, stdin) or break the loop when you've read it.
Beware of overflow if the user types 43219876543 where you expected just 42 (and int is a 32-bit quantity).
You could write the loop condition as:
while ((c = getchar()) != EOF && isdigit(c))
or even:
while (isdigit(c = getchar()))
I'd be extremely reluctant to actually put the latter into production code but it is, in theory, safe.
How could I treat each number individually so that I can use the entirety of the numbers later on? So that if the user types 10 20 30, I can multiply 10 by 20, then (10*20) by 30?
Wheels within wheels — or loops within loops. You'll need to specify your criteria a bit. If the user types 1 you want the answer 1; if they type 1 2, you want 2; if they type 1 2 3, you want 6; and so on (where these are all the numbers on a single line of input). You'll need an outer loop that skips over blanks and tabs, then uses the inner loop to read a number, and then multiplies the current product (initial value 1) by the new number, and after the outer loop, you'll print the product. This will print 1 for an empty line; maybe that doesn't matter (and maybe it does).
Here's some code that approximates what is appropriate:
#include <ctype.h>
#include <stdio.h>
int main(void)
{
int c;
while ((c = getchar()) != EOF && c != '\n')
{
int product = 1;
while (c != EOF && c != '\n')
{
while (isspace(c))
c = getchar();
int number = 0;
while (isdigit(c))
{
number = number * 10 + (c - '0');
c = getchar();
}
printf("Number: %d\n", number);
product *= number;
}
printf("Product: %d\n", product);
}
return 0;
}
I also tried a version with a slightly different 'skip' loop:
while (c != EOF && c != '\n' && !isdigit(c))
c = getchar();
Both work OK on sane inputs. Empty lines are treated as end of input; lines containing blanks are not. If you input 1a2b3c with the second condition, you will get the output 0; with the first, you get an infinite loop. There is no overflow protection; don't try doing factorial 20 and expect the correct answer (with 32-bit int). Tweak to your heart's content.
Your code :
#include <stdio.h>
#include<ctype.h>
int main() {
int c;//getchar() returns integer
int x;
printf("Num here: ");
x=0;
//As #Jonathan Leffler suggested ,
//usage of while loop like this is very helpful the moment you press Enter loop breaks.
while (isdigit(c = getchar())) //isdigit is a function from ctype.h checks for Entered character is digit or not
x = x*10 + c - 48; //here '0'==48
printf("%d",x);
}
when you enter 42
loop rotates two times for c==4 and c==2
c==4
x=0*10+'4'-48 //here '4'==52 ==> x=0+52-48 ==>x=4
c==2
x=4*10+'2'-48 //here '2'==50 ==> x=40+50-48 ==>x=42
to add ones digits to tens and then hundreds ... if you want to add digits in input number use this below while loop
int sum=0,num;
//read num
while(num>0)
{
sum=sum+num%10; //get the last digit and add to sum
num=num/10; //reduce last digit of num
}
Read in character by character and convert that to a numeral using the while loop in Jonathan's answer. Every time you read a numeral, simply multiple your current sum by 10, and add the number. That way by the time you read the last numeral and add it in, you'll have the correct number.
Sometimes the way we think a problem should be solved, can be solved in a different method when all of the languages capabilities are considered.
#include <stdio.h>
int main() {
int x;
printf("Num here: ");
scanf("%d", x);
}
implements the same functionality as your program.
Related
#include <stdio.h>
#include <stdlib.h>
int main()
{
int end;
while(( end = getchar() ) != EOF ){
printf("%d\n",end);
}
system("pause");
return 0;
}
I want to print the ASCII codes of characters with this code but whenever I run the code after it gets the char from me it prints its ASCII equivalent with decimal 10. For example if I run the code and pass "a", it will print 97 and 10. Why does it print 10, this happens with all other characters too.
Thank you for answers and as a followup question when I add a counter after I input a character counter's value increases by two, why does this happen
#include <stdio.h>
#include <stdlib.h>
int main()
{
int end;
int count=0;
while(( end = getchar() ) != EOF ){
printf("%d\n",end);
count++;
printf("counter is now %d\n",count);
}
system("pause");
return 0;
}
As stated you are printing the ASCII decimal codes for 'a' and '\n' respectively, this is because, in your code, getchar reads all the characters in the stdin buffer, including the newline character which is present because you press Enter.
You can avoid this by simply making it be ignored by your condition:
while((end = getchar()) != EOF && end != '\n'){
printf("%d\n", end);
}
Disclaimer: David Ranieri added a comment with the exact same solution as I was writing my answer (which he kindly deleted) so credit to him as well.
Regarding your comment question and the question edit:
If you don't want the '\n' to interrupt your parsing cycle, you can simply place the condition inside it.
while((end = getchar()) != EOF){
if(end != '\n'){ //now as '\n' is ignored, the counter increases by one
printf("%d\n", end);
count++;
printf("counter is now %d\n",count);
}
}
The reason why the counter is increased by two is, again, because two characters are parsed, whatever character you input and the newline character. As you can see in the sample, if you ignore the '\n', the counter will only increase by one, provided that you only enter one character at a time.
In ASCII, a newline is represented by the value 10.
Anytime you type a sequence of characters and press the ENTER key, you get the ASCII values for the letters/numbers/symbols you types as well as the value 10 for the newline.
{
char ch;
int count, lineCount;
count = 0;
lineCount = 0;
printf("Please enter one alphabet\n");
for (lineCount = 0; (ch = getchar()) != '\n'; lineCount++)
{
putchar(ch-'0');
printf("\n");
for (count = 0; count <= (ch - '0'); count++)
printf("%c \n", ch);
}
return 0;
}
This is my code so far. I need to do more stuff later but I'm just taking one step at a time. So I'd enter a letter. For example, d.
I put that putchar there to check that ch-'0' equals to the number I want. It does. d comes out to 4.
So in theory, I thought this code would print d out 4 times. But in reality, it printed it out a good 30-40 times.
It's the same with any other letter. It prints out a good 40 times. Plus, the count has no effect. I initialized it with a 5, which is obviously greater than 4. It still prints out like 40 times.
I haven't used for loops much. I know the concept, but I perhaps I'm making a huge C language mistake.
What's wrong here??
haha well I only copied the parts that count. I have the main.
And isn't 4 the integer value for 'd' - '0'? that's what it printed out as in that putchar statement and I actually tried changing it into int, but it made no difference. Well, not saying you are wrong at all. I'm the one that's wrong obviously. But that was my thinking behind it.
Please, can you explain the logistics behind it and what I should do?
Well, based on Please enter one alphabet you can reduce your for loop to
for (lineCount = 0; (ch = getchar()) != '\n'; lineCount++)
{
putchar(ch);
printf("\n");
printf("From Printf: %c \n", ch);
}
Note: ch - '0' is usually used to get the integer value of the char digit(s), '0' to '9'.
'd' - '0' is not 4. If you refer to an ASCII chart, you'll see that the value for 'd' in decimal is 100 and the value for '0' in decimal is 48, so I would expect the inner loop to repeat 100-48 = 52 times.
Since you did a putchar, it sent a byte having the decimal value 52 to the output, which happens to correspond to the ASCII character '4'.
Note that if you typed '4' instead of 'd', you should see it loop 4 times.
The basic issue is that of the relationship between quantitative values and representations of values in a given character set.
So I'm trying to find the sum of an unknown amount of user-input numbers. Here's my code
int main()
{
int tmp1 = 1;
int tmp2 = 1;
int total = 0;
printf("Enter numbers for a sum: ");
tmp2 = scanf(" %d", &tmp1);
while(tmp2 > 0){
total+=tmp1;
tmp2 = scanf(" %d", &tmp1);
}
printf("total is %d", total);
return 0;
}
It gets stuck in an endless loop, and then once i hit ctrl-c to end it, it prints the correct sum. So what I'm doing wrong is how will i know when it's done scanning all the integers, and for the loop to end; since i'm not doing it correctly now
Decided to make it stop via ctrl d, and its acceptable. thanks
In your question, it is not clear how you expect your programme to understand that there won't be anymore numbers to input. Shall it be through a specific character? Or shall it just get a line of space-separated numbers and respond with a sum?
From your code, my most sensible guess is: You want it to understand that there won't be any more numbers to add, whenever it encounters a non-digital character. My guess is so, because this is almost exactly what your code does by checking the return value from scanf.
First of all, you have to change that tmp inside your loop into tmp1 because there isn't such a variable as tmp declared. edit: well, never mind
Then try running your programme, putting in any amount of white-space (space, tab or new-line) separated numbers, and then any non-digital character you like. May be a T for example, or ThoAppelsin, it won't matter. Programme won't get beyond the first character, in fact, not even beyond the first character. After that, you shall see that the numbers have been properly added together.
Since you're confused about a non-existent infinite-loop, my second guess is that you might be actually hoping it to get a single line of space-delimited numbers, and have the sum printed; and misinterpret your programme as "in infinite loop" while it merely expects further input from you, just like it does at the very beginning.
You won't get a 0 from non-redirected scanf("%d", &var);, unless you feed it with something that doesn't match to the format string to cause abnormal termination. If there's nothing left in the input stream to consume, it will just wait for more input. But say you give an 'a' to it, then all it can do is to give up and return zero, because it couldn't do a single assignment.
If you really are hoping to have a single line of numbers, then the minimal change I could offer would be something like this:
int main(void)
{
int tmp1 = 1;
char tmp2 = 0;
int total = 0;
printf("Enter numbers for a sum: ");
scanf("%d%c", &tmp1, &tmp2);
while(tmp2 == ' '){
total+=tmp1;
scanf("%d%c", &tmp1, &tmp2);
}
printf("total is %d", total);
return 0;
}
Of course, this approach has many vulnerabilities. However, if user is to input strictly a sequence like:
3 66 2 10 6
// mind the new-line
It will work fine. But if I'm allowed to change more than minimal, this is how I would do it:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int main(void)
{
int LastNumber = 0;
int UpcomingCharacter = 0;
int Total = 0;
printf("Enter numbers for a sum: ");
while(scanf("%d%*[ \t]", &LastNumber) == 1)
{
Total += LastNumber;
UpcomingCharacter = getchar( );
if (!isdigit(UpcomingCharacter)) // eliminates a possible EOF return as well
break;
if (ungetch(UpcomingCharacter, stdin) != UpcomingCharacter)
{
fprintf(stderr, "%d: unexpected error with ungetch\n", __LINE__);
return EXIT_FAILURE;
}
}
printf("total is %d", Total);
return EXIT_SUCCESS;
}
Which should work fine on any whitespace-delimited sequence of numbers, excluding the new-lines of course.
I'm having trouble making this exercise for C-programming. I need to use the getchar()-method instead of the scanf(). When I use the scanf, everything works perfect when I type for instance 7. However when I use the getchar() and type 7, I will get the ASCII-code of 7, not the int 7. How do I fix this?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
printf("Voer een getal in:\n");
fflush(stdout);
i = getchar();
//scanf("%d", &i);
if (i > -1000 && i < +1000) {
printf("het ingevoerde getal is: %d\n", i);
} else {
printf("foutieve invoer\n");
}
return EXIT_SUCCESS;
}
This is the correct behavior of getchar. While scanf's %d format specifier converts a sequence of digits to a decimal number, with getchar you need to do it yourself.
In order to do that, you need to know three things:
When the sequence of digits ends,
How to convert an ASCII code of a digit to a number, and
How to combine multiple digits into a single number.
Here are the answers:
You can decide to end the character input when the value returned by getchar is not a digit. You can use the isdigit function for that (include <ctype.h> header to use it).
You can convert a single digit character to its corresponding numeric value by subtracting the code of zero (i.e. '0') from the value returned by getchar
You can combine multiple digits into a number by starting the partial result at zero, and then multiplying it by ten, and adding the value of the next digit to it.
int num = 0;
for (;;) {
int ch = getchar();
if (!isdigit(ch)) break;
num = 10 * num + (ch - '0');
}
This is the problem:Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.
Input:
1
2
88
42
99
My first code doesn't work:
while( scanf("%d\n", &n) != 42 ){
printf("%d\n",n);
}
second code, with for loop, works but there is a test case where there is no number 42 so it returns TLE, how do I check for end of input?
for(i=1;i>0;i++){
scanf("%d\n",&n);
if(n!=42 ){ /* end of input??? */
printf("%d\n",n);
}
else {
break;
}
}
And why doesn't while loop work like it should?
scanf returns the number of characters scanned, not the result.
So, write while loop as follows:
scanf("%d", &n);
while( n != 42 ){
printf("%d\n",n);
scanf("%d", &n);
}
Always good to avoid magic numbers. Define a constant.
Check the result of scanf() (#Joachim Pileborg)
To check if the input is valid , test if scanf() result is 1 (1 format specifier correctly scanned).
To check for end of input, test if scanf() result is EOF.
while loop failure is well explained by #dbasic. Roughly, scanf() reports the number of fields scanned, not the value scanned.
There is a lot to scanf(). If up to it, read the scanf() section of the C spec. Where do I find the current C or C++ standard documents?
const int Answer_to_Life_the_Universe_and_Everything = 42;
int n;
int cnt;
// Use 2d to limit to 2 digits
while ((cnt = scanf("%2d\n",&n)) == 1) {
if(n != Answer_to_Life_the_Universe_and_Everything) { /* end of input? */
printf("%d\n",n);
}
else {
break;
}
}
if (cnt != EOF) Handle_UnexpectedInput(); // example someone type in "junk"