Variable type for both int and char

Apr 28, 2009 at 6:10pm
Hey,

I'm making a small program to practice Binary Search that let the user input a number to search for. BUT the user should also be able to enter a letter like x to exit the program instead of the number.

Now I'm a bit stuck. I can't use an integer because it needs to accept the letter. But I need to use the value of the inserted number to search in my integer array.

What's the best way to solve this?

Thanks :)
Apr 28, 2009 at 6:13pm
char is an integer type, so you can use a char in any situation where you can use an int. Of course, the size of a char is smaller than an int.
Apr 28, 2009 at 6:15pm
Hi jdd

But char isn't an option too as it can only contain one character - the numbers have 2 or even 3 :(
Apr 28, 2009 at 6:22pm
An unsigned char can be 0-255. It does not store an 8 bit character representing the single numerical digit, it stores the binary representation of the number.
Apr 28, 2009 at 6:28pm
But it doesn't work...

1
2
3
4
5
6
7
8
9
10
11
12
unsigned char selection;
cout << "Please enter the number where you're looking for or press x to exit the program: ";
		cin >> selection;

		if (selection == 'x')
		{
			cout << selection;
		}
		else
		{
			cout << selection << " Not x selected";
		}


This is just for testing - I can enter x, but if I enter 27 for example, it outputs 2 as it's a char type. What I need is something that can store both the numbers and the letter and I must be able to work with the numbers.

Any way I can do that?
Apr 28, 2009 at 6:43pm
you may read string or char*
Last edited on Apr 28, 2009 at 6:46pm
Apr 28, 2009 at 6:46pm
Can you explain that a little bit please? What do you exactly mean with "read string or char*"?
Apr 28, 2009 at 6:52pm
That's some pretty terrible advice.

A char is an integral type which can be used to store the numerical representation of a character (the same is true for all integral types, actually). You can input into a char and pretend it's a character, or pretend it's a number, but not both.

Bv202: Use std::getline() with std::string. Once you have the input, first check if it equals "x". If it doesn't, convert it to a number. atoi() will work for this.

EDIT: typo
Last edited on Apr 28, 2009 at 7:06pm
Apr 28, 2009 at 6:55pm
Thank you helios, I'll have a look at that way. It will be for tomorrow though, I don't have enough time left now to concentrate on this. I'll let you know if I managed to let it work tomorrow :)

Btw: It's Bv202, not Bx202 :P
Last edited on Apr 28, 2009 at 6:56pm
Apr 29, 2009 at 2:24pm
Hi,

What am I doing wrong now?

1
2
3
4
5
6
7
8
9
10
11
12
13
string selection;
cout << "Please enter the number where you're looking for or press x to exit the program: ";
		cin >> selection;

		if (selection = 'x')
		{
			quit = true;
		}
		else
		{
			selection = atoi(selection);
			cout << selection;
		}



selection = atoi(selection);
Something is wrong with this, but I don't know what. I've read this tutorial, but can't figur it out:
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
Last edited on Apr 29, 2009 at 2:28pm
Apr 29, 2009 at 2:30pm
Line 3: It's preferable to use std::getline().
Line 5: Assignment operator inside an if expression. 'x' should be "x".
Lines 11: atoi() takes a const char *. To get the C string from an std::string call std::string::c_str().
Apr 29, 2009 at 2:37pm
Hi again helios,

1) Why getline()? I've looked up the tutorial about it but don't understand why and how to use this.
2) I've changed that to 'x' because it gave me this error:
error C2451: conditional expression of type 'std::basic_string<_Elem,_Traits,_Ax>' is illegal
After changing "x" to 'x', the error is gone.
3) Ehh... can you show an example of that?


Thanks again :)

EDIT:
So getline() stores every character into an array or something? What's the point of that?
Last edited on Apr 29, 2009 at 2:39pm
Apr 29, 2009 at 2:39pm
You have to be very careful about the type of things.

The atoi() function takes a char*, but your variable is a char.

Also, on line 4 you are assigning a value to the variable, instead of testing equality with ==.

I recommend you use a std::string to get your input:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <string>
#include <cstdlib>  // for atoi(). see note below

using namespace std;

int main()
  {
  string user_input;
  int    selection;

  cout << "Please enter the number you are looking for\n"
          "Or press X to exit the program\n"
          "> "
       << flush;
  getline( cin, user_input );  // Safe and works for any input. Also, it behaves properly with the user.

  if (user_input == "x")  // Notice that we are comparing against a string literal now
    {
    quit = true;
    }
  else
    {
    selection = atoi( user_input.c_str() );  // And here, we pass a char* to atoi()
    cout << "You chose number " << selection << endl;
    }

  return 0;
  }

The atoi() function is real nice, but you should prefer stringstreams, if possible (you may not have learned that far yet though).
1
2
3
4
5
6
7
8
9
10
11
#include <string>
#include <sstream>
using namespace std;

int my_atoi( const string& number )
  {
  istringstream iss( number );
  int result;
  if (iss >> result) return result;
  return 0;
  }

Hope this helps.

[edit] argh... too slow.
Last edited on Apr 29, 2009 at 2:40pm
Apr 29, 2009 at 2:48pm
Okay, thank you very much; I'm starting to understand it :)
I'm skipping that part about the stringstreams... indeed I haven't learnt such things yet.

A few more questions...
1) I didn't include cstdlib, but it works fine. Why?
2) What is exactly the use of getline()? Is there anything wrong with cin >> varname; ?
3) Can you explain what this mean?
c_str()

From the tutorial:
Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.

But I don't really understand that :$

Thank again :)
Last edited on Apr 29, 2009 at 2:49pm
Apr 29, 2009 at 2:57pm
An std::string is, basically, a vector of chars. It contains a size variable and an array of chars.
C strings are simple arrays, so they don't have size. Instead, their end is determined by the first 0 from the start.
atoi() takes a pointer to a C string, so you can't pass it an std::string. Instead, you call std::string::c_str(), which returns a C string equivalent of the std::string.
Example: atoi(s.c_str())

Duoas probably has a reason to suggest you use std::stringstreams instead of atoi(), so you might want to listen to him. I myself don't see any difference between using atoi() or std::stringstream.
Apr 29, 2009 at 3:34pm
Okay, thanks for the explaination.

Why should I use getline() instead of cin >> varname;? Thanks
Apr 29, 2009 at 5:25pm
Atoi() is fine... it just doesn't handle errors very well -- and it is part of the C standard library. Why not do things the C++ way? You are already when using cin.

Users always expect to enter an answer, meaning that they will type their answer then press the Enter key to signal that they are done. This is called line-buffered input -- which is the default input method on a text terminal (or console window).

Hence, you should get input from the user one line at a time (into a string), and then parse it into whatever you are looking to get (such as a number). This lets you trap and handle errors much more easily, and leads to more robust programming practices.

Hope this helps.
Last edited on Apr 29, 2009 at 5:26pm
Apr 29, 2009 at 5:32pm
Ok, thanks again =)
Topic archived. No new replies allowed.