Author Topic: 'char' rather than 'int' causing double loop  (Read 643 times)

0 Members and 1 Guest are viewing this topic.

Offline Drahgon

  • /dev/null
  • *
  • Posts: 14
  • Cookies: -10
    • View Profile
'char' rather than 'int' causing double loop
« on: December 10, 2015, 01:18:51 am »
The problem:


My Code:


The issue I have:
For some reason when I enter a number that conforms to >=10. It asks me to enter the number twice without taking an input for the first loop round. [See the console window below]. I know why it is, it is because I have set 'input' to 'char' instead of int. Why then is it looping when I reach 10? Memory issue? Random Glitch?



Offline archfox

  • /dev/null
  • *
  • Posts: 12
  • Cookies: 1
    • View Profile
Re: 'char' rather than 'int' causing double loop
« Reply #1 on: December 10, 2015, 04:29:58 pm »
What do you mean by looping? Do you expect it to terminate or what? If yes, then add:

if(count==10){
//your console outputs
return 0;
}

Btw, I as a tip: please, stick to one style, either go entirely for C++ or C  ;)

Argh... Was focing myslef not to write this, but this snippet doesn't fulfill the task requirements as well.
« Last Edit: December 10, 2015, 04:39:33 pm by archfox »

Offline LinkinCube

  • /dev/null
  • *
  • Posts: 15
  • Cookies: 1
    • View Profile
Re: 'char' rather than 'int' causing double loop
« Reply #2 on: December 10, 2015, 05:24:03 pm »
Why then is it looping when I reach 10? Memory issue? Random Glitch?

Because the char variable handles numbers as characters and not as numbers. The char variable can store exactly one byte, and a character also takes one byte.
The problem is, if you type the number 10, two characters are used. But the char variable has not enough space to store both of them. In this case the char variable would get the character 1. The 0 is just being written to the memory adress that comes after it. No matter what is stored there. (As far as I know. Please flame me if I'm wrong).

For some reason (I have no exact idea why .  .  .) that causes this looping glitch. Just use the int variable and you should be fine (As long as you don't use numbers that are bigger than 2147483647 because that would cause the same issue :P)

And, as Archfox already said, you should stick to one style. That makes the code easier to read.
« Last Edit: December 10, 2015, 05:31:05 pm by LinkinCube »
"There are no smart people. They are just not as stupid as the others."  - me

Offline ArkPhaze

  • Peasant
  • *
  • Posts: 136
  • Cookies: 20
  • null terminated
    • View Profile
Re: 'char' rather than 'int' causing double loop
« Reply #3 on: December 13, 2015, 05:47:45 am »
The loop happens because the first extraction for a char datatype takes the first digit of the multiple digits as input, and the second recognizes that there is data remaining in the stdin buffer, so it doesn't wait for the user to input anything and takes it automatically.

Ex: Input a char > '12'

The extraction takes '1', and when the next extraction from stdin takes place, the '2' is still left in the stream's buffer, therefore, there's no need to wait for the user to input any data because it can just take it from stdin. And because of the way scanf() and std::cin's operator>> work, it will only take data out of the stdin buffer if it can be properly represented in the datatype associated with the pointer passed to the function. If we enter a string when the function expects an int, the variable is never assigned a meaningful value, the function returns an indication of this, and the string is left in stdin.

A way to deal with that, along with a similar solution is as follows:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>

#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, const char *argv[])
{
  int num;
  int tries = 0;
  do
  {
    printf("Please enter a number other than %d: ", tries);

    while (scanf(" %d", &num) != 1)
    {
      while ((num = getchar()) != EOF && num != '\n');
      fputs("Invalid input, please try again: ", stderr);
    }

    /* after 10 iterations -- from a 0-based 'tries' count, the 11th
     * iteration will be 10, thus we should exit after our message */
    if (tries == 10)
    {
      fputs("Wow, you're more patient than I am, you win.", stdout);
      exit(0);
    }
  }
  while (num != tries++);
  printf("Hey! you weren't supposed to enter %d!\n", num);
  exit(0);
}


Same reason why you need a std::cin.get() after std::cin >> int_variable, or something else to get rid of the '\n' from the buffer because it's what gets appended when you confirm input with the enter key. With a string like "1234\n" as input, only the "1234" part can be represented as an int (1234), and the '\n' which remains is left in the input buffer. To avoid future conflict you should remove it somehow as soon as you can.

The way stream objects like std::cin work in C++ -- they maintain state flags that you should be checking for indication of success or failure whenever you deal with read/extraction operations like with the overloaded >> operator.
« Last Edit: December 13, 2015, 06:09:46 am by ArkPhaze »
sig=: ArkPhaze

[ J/ASM/.NET/C/C++ - Software Engineer ]