How can I store the integer in a character array? - c++

#include <iostream>
using namespace std;
int main() {
char ch[19];
int c;
cin >>c;
ch[0]=c;
ch[1]='\0';
cout << ch;
}
what I want is to store the intger c at the location ch[0] but it stores the ascii value corresponding to that number like if.I put 97 then it stores a.
How can I put the character 9 in the character array ch?
Even if I typecast the variable c to char it doesn't help.

Standard streaming operators are overloaded on the type of their operands. By default, streaming into an int will read decimal digits, streaming into a char will read one character, streaming into a std::string will read a word, and so on.
So, if you want to read a single character (the digit 9), just stream into a char, which you already have at hand:
std::cin >> ch[0];

Related

Input number to variable with type char in C++

In C++, how can I input a number to unsigned char variable? In C, I can accept the input using %hhu format specifier:
unsigned char var_name;
scanf("%hhu", &var_name);
//lets say I inputted 27
printf("%hhu", var_name);
//the output is 27
How can I do that in C++? The code below is my attempt to do this in C++, but it does a wrong thing. How can I write equivalent code in C++?
unsigned char var_name;
std::cin >> var_name;
//Input 27 again
std::cout << var_name;
//The output is just 2, how can I make the '7' appear?
This happens because when reading an unsigned char from std::istream, a character is read. That's just what happens, that's how std::istream works. It also makes a lot of sense, because it's quite common to want to read a single character.
The trivial solution is to use a temp variable:
unsigned char var_name;
unsigned int tmp;
std::cin >> tmp; // input 27
// optionally add checking that tmp is small enough
var_name = tmp; // truncation of unsigned ints is well defined
std::cout << var_name; // should print 27
You are only getting a 2 when printing the variable because of cin.
The maximum size of an unsigned char in C++ is usually 8 bits, which is fine for any actual character, and any digit up to 255. However this number depends on the compiler and the system. The maximum value that can be stored is in the header, as UCHAR_MAX.
Your issue here is that you are using cin, which only ever reads the first 'character' of an input if it is storing that input as a char. There are several ways around this, including taking the input as an integer and then converting to a char, or making your program work with an integer.
Hope this helps :)
When var_name is of type unsigned char, then the line
std::cin >> var_name;
is similar to
std::scanf("%c", &var_name);
i.e. C++ will assume that you want to read a single character and write the character code into var_name.
If you instead want to read a number and write that number into var_name, then you cannot use the data type char or unsigned char when using operator >>, even if the data type is technically able to represent the desired range of values. Instead, you will first have to use a variable with a larger data type, such as unsigned short, for reading the number. Afterwards, you can assign it to another variable of type unsigned char:
unsigned char var_name;
unsigned short temp;
std::cin >> temp;
if ( std::cin )
{
var_name = static_cast<unsigned char>( temp );
std::cout << var_name << '\n';
}
else
{
//TODO: handle error
}
The static_cast is not necessary, but some compilers may emit a warning due to the truncation, which will probably be suppressed by the cast. Also, using the cast makes the code more readable, because it becomes obvious that the value is being truncated.
However, I generally do not recommend that you use operator >> for user input, because it will do strange things, such as
not always read one line of input at a time, and
accept garbage such as "6sdfj23jlj" as valid input for the number 6, although the input should probably be rejected in this case.
If you want to read a number from the user with proper input validation, I recommend that you take a look at my function get_int_from_user in this answer of mine to another question.

Put a non-numeric input into an integer variable

I’m having a bit of a problem in C++. When I wrote this:
int a = ‘:‘;
cout << a;
This printed out 58. It checks out with the ASCII table.
But if I write this:
int a;
cin >> a;
//i type in “:”
cout << a;
This will print out 0. It seems like if I put in any non-numeric input, a will be 0. I expected it to print out the equivalent ASCII number.
Can someone explain this for me? Thank you!
There are two things at work here.
First, ':' is a char, and although a char looks like a piece of text in your source code, it's really just a number (typically, an index into ASCII). This number can be assigned to other numeric types, such as int.
However, to deal with this oddity in a useful way, the IOStreams library treats char specially, for a numeric type. When you insert an int into a stream using formatted insertion (e.g. cout << 42), it automatically generates a string that looks like that number; but, when you insert a char into a stream using formatted extraction (e.g. cout << ';'), it does not do that.
Similarly, when you do formatted extraction, extracting into an int will interpret the user's input string as a number. Forgetting the char oddity, : in a more general sense is not a number, so your cin >> a does not succeed, as there is no string that looks like a number to interpret. (If a were a char, this "decoding" would again be disabled, and the task would succeed by simply copying the character from the user input.)
It can be confusing, but you're working in two separate data domains: user input as interpreted by IOStreams, and C++ data types. What is true for one, is not necessarily true for the other.
You're declaring a as an int, then the operator>> expects digits, but you give a punctuation, which makes extraction fails. As the result, since C++11, a is set to 0; before C++11 a won't be modified.
If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set. (until C++11)
If extraction fails, zero is written to value and failbit is set. (since C++11)
And
I expected it to print out the equivalent ASCII number.
No, even for valid digits, e.g. if you input 1, a will be set with value 1, but not its ASCII number, i.e. 49.
This will print out 0. It seems like if I put in any non-numeric input, a will be 0. I expected it to print out the equivalent ASCII number.
Since C++11 when extraction fails 0 will be automatically assigned.
However, there is a way where you can take a char input from std::cin and then print its ASCII value. It is called type-casting.
Here is an example:
#include <iostream>
int main()
{
char c;
std::cin >> c;
std::cout << int(c);
return 0;
}
Output:
:
58

Why does std cin work only when used with int variable?

I'm trying to use std::cin after a while.
Using uint8_t or unsigned char:
unsigned char data;
std::cin >> std::dec >> data;
Whatever std::dec is used or not, I get the first ASCII character I type.
If I type 12, data is 0x31 not 12. Why can't it parse number until 255 to be stored in a char?
int data;
std::cin >> std::dec >> data;
gives correctly data=12/0xC not 0x31
Why?
Using char[N] with std::hex
char data[128];
std::cin >> std::hex >> data;
Also gets the ASCII characters instead of the hexadecimal.
Writting 0x010203040506... data is 0xFFFFFFFFF...
Isn't std::cin>>std::hex able to parse the string I type into hexadecimal automatically?
In short:
cin >> charVar scans a single character from stdin
cin >> intVar scans characters from stdin until a non-numeric character is entered
Explaining your observation:
A char variable can store a single ASCII character.
When you type 12, only the character 1 is scanned.
The ASCII code of the character 1 is 0x31.
std::dec and std::hex affect the format of integers.
But as far as the streaming operators are concerned, char and its variants (including uint8_t aren't integers, they're single characters. They will always read a single character, and never parse an integer.
That's just how these functions are defined. There is no way around it. If you want an integer with a limited range, first read into an int (or other integer type that is not a char variant), and then range-check afterwards. You can, if you want, cast it to a small type afterwards, but you probably shouldn't. char types are awkward to work with numerically.
Similarly, reading into an array of char reads a string. (Also, never do that without using setw() to limit the length to fit in the buffer you have. Better yet, use std::string instead.) That's just how it's defined.

How to read a specific amount of characters from a text file

I tried to do it like this
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char b[2];
ifstream f("prad.txt");
f>>b ;
cout <<b;
return 0;
}
It should read 2 characters but it reads whole line. This worked on another language but doesn't work in C++ for some reason.
You can use read() to specify the number of characters to read:
char b[3] = "";
ifstream f("prad.txt");
f.read(b, sizeof(b) - 1); // Read one less that sizeof(b) to ensure null
cout << b; // terminated for use with cout.
This worked on another language but doesn't work in C++ for some
reason.
Some things change from language to language. In particular, in this case you've run afoul of the fact that in C++ pointers and arrays are scarcely different. That array gets passed to operator>> as a pointer to char, which is interpreted as a string pointer, so it does what it does to char buffers (to wit read until the width limit or end of line, whichever comes first). Your program ought to be crashing when that happens, since you're overflowing your buffer.
istream& get (char* s, streamsize n );
Extracts characters from the stream and stores them as a c-string into
the array beginning at s. Characters are extracted until either (n -
1) characters have been extracted or the delimiting character '\n' is
found. The extraction also stops if the end of file is reached in the
input sequence or if an error occurs during the input operation. If
the delimiting character is found, it is not extracted from the input
sequence and remains as the next character to be extracted. Use
getline if you want this character to be extracted (and discarded).
The ending null character that signals the end of a c-string is
automatically appended at the end of the content stored in s.

Parsing binary files in C++

I'm trying to read a binary format using C++
For some reason I'm able to parse only the first variable.
The header sequence is:
[2 byte integer][1 byte integer][1byte integer]
#include <iostream>
#include <fstream>
using namespace std;
struct HDR {
unsigned short int signature;
unsigned char version;
unsigned char tricnt;
} header;
int main(){
ifstream infile("1.mdl",ios::in | ios::binary);
if(!infile){
cout<<"Error\n";
return 1;
}
infile.read(reinterpret_cast<char *>(&header),sizeof(HDR));
cout<<"SIG "<<header.signature<<endl;
cout<<"VER "<<header.version<<endl;
cout<<"TRI "<<header.tricnt<<endl;
return 0;
}
For some reason I'm able to parse only the signature, the rest of the structure is empty.
Unless you have specific knowledge of the padding used by your implementation you should read into the members individually.
infile.read(reinterpret_cast<char *>(&header.signature), sizeof header.signature);
infile.read(reinterpret_cast<char *>(&header.version), sizeof header.version);
infile.read(reinterpret_cast<char *>(&header.tricnt), sizeof header.tricnt);
Of course, you are still relying on unsigned short being 2 bytes on your platform and the representation in the file having the same endianness as your machine but at least you aren't making assumptions about structure padding.
Naturally, when you're printing unsigned char the character represented will be printed. If you want to see the numeric value you should cast to a non-char integer type. ASCII 1 (start of header) and 3 (end of text) are control characters and not usually visible when printed.
cout<<"VER "<< static_cast<int>(header.version) <<endl;
cout<<"TRI "<< static_cast<int>(header.tricnt) <<endl;