Using char for small integer value instead of using INT [duplicate] - c++

This question already has answers here:
Standard Input for Unsigned Character
(2 answers)
Closed 6 years ago.
I am working on some codes using c++.
Type char is one byte in my machine and int type is four bytes.
Since my input value is under 100, I used char type instead of integer type in order to make my process in an efficient way as shown in below codes.
int do_main(int argc, const char *argv[]) {
int TC;
cin >> TC;
while (TC--) {
unsigned char num;
char code[7];
for (int i = 0; i < 7; ++i) code[i] = 0;
cin >> num;
int idx = 0;
while (1) {
code[7-1-idx++] = num % 2;
num /= 2;
if (num < 2) break;
}
code[7 - 1 - idx] = num;
for (int i = 0; i < 7; ++i) cout << code[i] << endl;
}
return 0;
}
As you can see above codes, the 10 digit value is transformed into 2 bit type. However, my problem is that the value was not what I expected. it showed some strange character not 1 or zero.
I thought that it was due to the types. Therefore I modified the char into int and ran the codes again. I confirmed that the codes[i] showed the corrected value that I expected.
To summary.. my question is that what is wrong with the usage of char instead of int?
I know that char is aimed at storage of character but for some small integer value (up to 1 byte), we can use char instead of int type.

It is because std::cout's operator<<(char) is overloaded such that it will display ascii character corresponding to the digit. Instead of changing type from char to int, you can do like this
for (int i = 0; i < 7; ++i)
cout << static_cast<int>(code[i]) << endl;
See this.

Related

what does int numbers[n+2]; statement do?

#include<iostream>
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
int main() {
int n;
std::cout << "Enter a Number";
std::cin >> n;
int result = fastFibonacci(n);
std::cout << result << "\n";
return 0;
}
in this code when i enter input 0 or 1 get correct answer. But the problem is that when i replace int numbers[n+2]; with the commented part it start giving me wrong answer when input is 0 or 1. why? anyone please explain me.
In this function
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
there is used a variable length array with n + 2 elements declared in this line
int numbers[n+2]; // int numbers[n].
Variable length arrays is not a standard C++ feature. It can be implemented as own language extension of a C++ compiler.
Using the variable length array makes the function very unsafe because there can occur a stack overflow.
As within the function there is explicitly used two elements of the array
numbers[0] = 0;
numbers[1] = 1;
then the array shall have at least two elements even when the parameter has a value less than 2.
To calculate the n-th Fibonacci number there is no need to declare an array of such a size.
Apart from this the function argument shall have an unsigned integer type. Otherwise the function can invoke undefined behavior if the user passes a negative number.
Also for big values of n there can be an integer overflow for the type int.
The function can be implemented in various ways.
Here is one of possible its implementations.
#include <iostream>
#include <functional>
unsigned long long fibonacci( unsigned int n )
{
unsigned long long a[] = { 0, 1 };
while ( n-- )
{
a[1] += std::exchange( a[0], a[1] );
}
return a[0];
}
int main()
{
const unsigned int N = 10;
for ( unsigned int i = 0; i < N; i++ )
{
std::cout << i << ": " << fibonacci( i ) << '\n';
}
return 0;
}
The program output is
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
int numbers[n+2]; is the declaration of an array of ints with space for n + 2 ints, this is a variable lenght array and is not part of C++ standard, though some compilers allow it it's not somenthing you should use.
If you need a variable lenght array use std::vector.
With int numbers[n+2]; if n is equal to 0 you still have space for 2 ints, if you have int numbers[n]; the array will have space for 0 ints, so the code will fail because you are trying to access memory that does not exist with numbers[0] and numbers[1].
There are several good ways to implement the Fibonacci sequence, in the site you can find many questions regarding this matter in several programming languages, here is one of them Fibonacci series in C++
Edit
So I've seen your comments about using a vector, for making the sequence you wouldn't need the vector just two variables to store the two numbers to add, to store the sequence in a vactor, you can do somenthing like:
#include <iostream>
#include <vector>
#include <iomanip>
//passing the vector by reference
void fastFibonacci(unsigned long long n, std::vector<unsigned long long>& sequence) {
unsigned long long first = 0;
unsigned long long second = 1;
sequence.push_back(first); //add first values to the vector
sequence.push_back(second); //add first values to the vector
for (unsigned long long i = 0, value = 0; i < n && value <= LLONG_MAX ; ++i) {
value = first + second;
first = second;
second = value;
sequence.push_back(value); //adding values to the vector
}
}
int main() {
unsigned long long limit; //number of values in the sequence
int num = 1;
std::vector<unsigned long long> sequence; //container for the sequence
std::cout << "Enter upper limit: ";
std::cin >> limit;
fastFibonacci(limit, sequence);
//print the sequence in a range based loop formatted with <iomanip> library
for(auto& i : sequence){
std::cout << std::setw(4) << std::left << num++ << " " << i << std::endl;
}
return 0;
}
If you want to print just one of the numbers in the sequence, just use, for instance:
std::cout << sequence[10];
Instead of the whole vector.
The code you post in the comment to the other answer won't work because the access to the vector is out of bounds in numbers[i] = numbers[i - 1] + numbers[i - 2];, if for instance i = 5, your vector only has 2 nodes but you are accessing the 6th node numbers[5].

How do I print the elements of a char array?

I have to convert a decimal value into a string that shows the binary value, e.g. given 8, I need to print a string "1000". I have the conversion from decimal to binary, but when I print the values directly form the char array, I get little question marks instead of numbers. I know it has something to do with the way char arrays read values, but I can't figure out how to correct the issue.
void dec2Bin(int value, char binaryString[]) {
int remainder = 0;
int binDigit = 0;
int i = 0;
while (value != 0) {
binDigit = value % 2;
value /= 2;
binaryString[i] = char(binDigit);
i++;
}
for (int k = i - 1; k > 0; k--) {
cout << binaryString[k];
}
}
int main()
{
cout << "Enter a decimal number: ";
int num;
cin >> num;
char binaryString[20] = "";
dec2Bin(num, binaryString);
return 0;
}
When you do
binaryString[i] = char(binDigit);
you are assigning the decimal value 0 or 1 to binaryString[i]. That's okay, a char is basically nothing more than a small integer.
The problems comes when you want to print the value, as the only overloaded << operator to handle char treats the characters as a character, and in most encodings the values 0 and 1 are not printable.
There are two solutions:
Either you convert the character you want to print into a larger integer which won't be treated as a character:
cout << static_cast<int>(binaryString[k]);
Or you make the array contain actual printable characters instead:
binaryString[i] = binDigit + '0';

difference between string size() function and strlen in this particular case

I recently did this question
Specification:
Input Format The first line contains the number of test cases, T. Next,
T lines follow each containing a long string S.
Output Format For each long string S, display the number of times SUVO
and SUVOJIT appears in it.
I wrote the following code for this :
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int suvo = 0;
int suvojit = 0;
string s;
cin >> s;
for (int i = 0; i <= s.size() - 7; i++) {
if (s.substr(i, 7) == "SUVOJIT")
suvojit++;
}
for (int i = 0; i <= s.size() - 4; i++) {
if (s.substr(i, 4) == "SUVO")
suvo++;
}
cout << "SUVO = " << suvo - suvojit << ", SUVOJIT = " << suvojit << "\n";
}
return 0;
}
The code about gave out of bounds exception for substr() function for this test case:
15
RSUVOYDSUVOJITNSUVOUSUVOJITESUVOSUVOSGSUVOKSUVOJIT
SUVOJITWSUVOSUVOJITTSUVOCKSUVOJITNSUVOSUVOJITSUVOJITSUVOSUVOSUVOJITTSUVOJ
SUVOSUVOSUVOJITASUVOJITGCEBISUVOJITKJSUVORSUVOQCGVHRQLFSUVOOHPFNJTNSUVOJITKSSUVO
SUVOJITSUVOJITJGKSUVOJITISUVOJITKJLUSUVOJITUBSUVOX
MMHBSUVOFSUVOFMSUVOJITUMSUVOJITPSVYBYPMCSUVOJIT
OASUVOSUVOJITSUVOSTDYYJSUVOJITSUVOJITSUVO
RLSUVOCPSUVOJITYSUVOSUVOOGSUVOOESUVOJITMSUVO
WVLFFSUVOJITSUVOVSUVORLESUVOJITPSUVOJITSUVO
RSUVOSUVOJITQWSUVOUMASUVOSUVOJITXNNRRUNUSUVOJIT
HYLSSUVOSUVOSUVOJITPOSUVOJIT
DGMUCSSSUVOJITMJSUVOHSUVOCWTGSUVOJIT
OBNSSUVOYSUVOSUVOJITSUVOJITRHFDSUVODSUVOJITEGSUVOSUVOSUVOJITSUVOSUVOJITSSUVOSUVOSUVOSSUVOJIT
AG
NSUVOJITSUVOSUVOJIT
CGJGDSUVOEASUVOJITSGSUVO
However, when instead of using the s.size() function, I converted the string into a char constant and took the length of it using strlen, then the code caused no error and everything went smoothly.
So, my question is... Why did this happen?
This is my working code with the change:
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int suvo = 0;
int suvojit = 0;
string s;
cin >> s;
int le = strlen(&s[0]);
for (int i = 0; i <= le - 7; i++) {
if (s.substr(i, 7) == "SUVOJIT")
suvojit++;
}
for (int i = 0; i <= le - 4; i++) {
if (s.substr(i, 4) == "SUVO")
suvo++;
}
cout << "SUVO = " << suvo - suvojit << ", SUVOJIT = " << suvojit << "\n";
}
return 0;
}
In one case, you use size_t, in the other case you use int.
If the length is for example 6 characters, then s.size () - 7 is not -1, but one huge number and everything goes wrong. But if you write int len = strlen (...), then len - 7 is indeed -1 and everything is fine.
When I see a number subtracted from size_t, that's an immediate red flag. Write "i + 7 ≤ s.size()", not "i ≤ s.size() - 7".
First of all, in my testing your second leads to a problem as well:
Second, especially with older compilers (well, libraries, really) this can be horrendously inefficient, creating a huge number of temporary strings that you only use to compare with another string1.
So, let's consider how the job should be done instead. std::string has a member named find for situations like this. It returns the position of one string inside another, or std::string::npos if there is none. It allows you to specify a starting position at which to begin searching, when you don't want to start from the beginning.
We also, of course, have two instances of essentially identical code, once to search for SUVO, the other to search for SUVOJIT. The code would be much better off with the search code moved into a function, so we only have the search code in one place.
int count_pos(std::string const &haystack, std::string const &needle) {
size_t pos = 0;
int ret = 0;
while ((pos = haystack.find(needle, pos)) != std::string::npos) {
++ret;
++pos;
}
return ret;
}
Note that this also eliminates quite a bit more messy "stuff" like having to compute the maximum possible position at which at match could take place.
1. Why does compiler/library age matter? Older libraries often used a COW string that dynamically allocated storage for every string. More recent ones typically include what's called a "short string optimization", where storage for a short string is allocated inside the string object itself, avoiding the dynamic allocation.

Int to char c++ [duplicate]

This question already has answers here:
Char to int conversion in C
(10 answers)
Convert an int to ASCII character
(11 answers)
Closed 6 years ago.
Can somebody explain me how the following tochar function works? As an experiment I added the following to tochar:
cout<<'0' + value
When run, I got a result of:
51 50 49 52
My code is:
static int tochar(int value)
{
return '0' + value;//This is the part i don't understand
}
int main()
{
char c[20];
int n = 4123;
int count = 0;
int number = log10(n)+1; //number of digits
for (int i = number; i >= 1; i--)
{
c[i] = tochar(n % 10);
n = n / 10;
count++;
}
for (int i = 1; i <=count; i++)
cout<<c[i];
system("pause");
}
You should change your function to
static char tochar(int value)
{
return '0' + value;//This is the part i don't understand
}
This function converts a single digit int to the character representing the digit. It assumes that 0-9 digits are consecutive in the char map, and works by computing the difference between the given argument and the '0' character.

C++ Atoi function gives error [duplicate]

This question already has answers here:
Convert single char to int
(3 answers)
Closed 3 years ago.
I have a string which has 5 characters. I want to convert each single character to int and then multiply them with each other. This is the code :
int main()
{
int x;
string str = "12345";
int a[5];
for(int i = 0; i < 5; i++)
{
a[i] = atoi(str[i]);
}
x = a[0]*a[1]*a[2]*a[3]*a[4];
cout<<x<<endl;
}
It gives this error for the line with atoi :
invalid conversion from 'char' to 'const char*' [-fpermissive]|
How can I fix this? Thanks.
You can use:
a[i] = str[i] - '0';
Does a char to digit conversion by ASCII character positions.
The proper way to do this is std::accumulate instead of rolling your own:
std::accumulate(std::begin(str), std::end(str), 1, [](int total, char c) {
return total * (c - '0'); //could also decide what to do with non-digits
});
Here's a live sample for your viewing pleasure. It's worth noting that the standard guarantees that the digit characters will always be contiguous, so subtracting '0' from any of '0' to '9' will always give you the numerical value.
std::atoi takes a const char*(a null terminated sequence of characters)
Try to change like
a[i]= str[i]-'0';
You are supplying with a single char hence the compiler is complaining
str[i] is char not char *
Use following :-
int x;
std::string str = "12345";
int a[5];
for(int i = 0; i < 5; i++)
{
a[i] = str[i] -'0' ; // simply subtract 48 from char
}
x = a[0]*a[1]*a[2]*a[3]*a[4];
std::cout<<x<<std::endl;
look at this way
string str = "12345";
int value = atoistr.c_str());
// then do calculation an value in a loop
int temp=1;
while(value){
temp *= (value%10);
value/=10;
}