Inputting numbers in char array - c++

In reference to this problem I need to input a 100 digit number in the program and perform operations on it. I figured I would use a char array to do it.
I wrote this code after trying for some time.
int main()
{
//int cases=10;
//while(cases--)
//{
int i;
char totalapples[102];
//char klaudia_apples[200] , natalia_apples[200];
for(i=0;totalapples[i]!='\0';i++)
{
cin>>totalapples[i];
}
//cin>>moreapples[200];
//cout<<moreapples[200];
while(i--)
{
cout<<totalapples[i];
}
//}
return 0;
}
When I run this, I get the following result:
Input : 1234657891234567981345698
Output : 987564321
Can anybody tell what is happening??

Your program invokes undefined behavior. Despite the fact the char array contains undefined values you attempt to read from it using
totalapples[i]!='\0'
in your for loop. Instead, read the whole string into a std::string:
string totalApplesStr;
cin >> totalApplesStr;
Now you can iterate over totalApplesStr:
for (char c : totalApplesStr) {
/* Do whatever you need to */
}
Or, if that isn't a logical error in your code, you can iterate from the end to the beginning:
for (auto it = totalApplesStr.rbegin(); it != totalApplesStr.rend(); ++it) {
/* Do whatever you need to */
}

Use std::string instead of a char array.
You may then use std::tranform to convert to a vector of int to do your big number computations.

You attempt to test values from an array that has not been initialized yet.
Although a char array is the least safe method you could use for this, you could fix it with an initializer:
char totalapples[102] = {0};
Also, your second loop will print the result backwards. Try incrementing to i, not decrementing from i.

You new initialize your counter/index. And there are many other improvement to be done, but your code was short
#define ARRAY_SIZE 102
int main {
char totalapples[ARRAY_SIZE];
unsigned int i = ARRAY_SIZE;
i = 0;
while (i < ARRAY_SIZE)
{
cin>>totalapples[i]; // range is 0..101
i++;
}
i = ARRAY_SIZE;
while (i > 0)
{
cout<<totalapples[i]; // range is 0..101
i--;
}
}

Related

Generate random char/digit

I`m trying to found fastest way to generate random digit/char array.
char *randomGet(int num) {
srand(time(NULL));
const char ab[37] = { "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ" };//Alphabet&Digit
char *targ = new char[num];
for (int i = 0; i < num; i++) {
strcat(targ, ab[rand() % 38]);
}
return targ;
}
So far I've come up with this, but it does not work (argument of type char is incompatible with parameter of type const char *).
Help me find the best solution to my problem. Ty.
strcat() takes a char* as input, but you are giving it a single char instead, thus the compiler error.
Also, the buffer that strcat() writes to must be null terminated, but your targ buffer is not null terminated initially, and you are not allocating enough space for a final null terminator anyway.
You don't need to use strcat() at all. Since you are looping anyway, just use the loop counter as the index where to write in the buffer:
Also, you are using the wrong integer value when modulo the return value of rand(). You are producing a random index that may go out of bounds of your ab[] array.
Try this instead:
char *randomGet(int num)
{
srand(time(NULL));
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ"; //Alphabet&Digit
char *targ = new char[num+1];
for (int i = 0; i < num; ++i) {
targ[i] = ab[rand() % 36];
}
targ[num] = '\0';
return targ;
}
I'd make two changes. First, make the internal source array static:
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
Note that this version does not specify the array size; the compiler will figure it out from the initializer.
Second, pass in a pointer to the target array:
void randomGet(char* targ, int num) {
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
for (int i = 0; i < num - 1; ++i)
targ[i] = ab[rand() % (sizeof ab - 1)];
targ[num - 1] = '\0';
}
This way, the caller decides how to allocate memory for the string.

Bug in C++ Code: setting one variable to zero causes unrelated variable to become zero

Why does the value of variable n2 get changed to 0 in the below code after the execution of the statement arr[26]={0}; ,(I realised this while debugging)
while memset(arr,0,sizeof(arr)); works perfectly.
#include<bits/stdc++.h>
using namespace std;
int main()
{
long int n1,n2;
int count=0,flag;
int arr[26] = {0};
cin>>n1>>n2;
string box1[n1];
string box2[n2];
for(int j=0;j<n1;j++)
cin>>box1[j];
for(int j=0;j<n2;j++)
cin>>box2[j];
count=0;
for(int i=0;i<n1;i++)
{
for(int j=0;j<n2;j++)
{
arr[26]={0}; // after the execution of this statement, n2 changes to 0.. WHY???
//memset(arr,0,sizeof(arr)); // If i use memset , things work correctly
cout<<n2<<endl; //n2 becomes zero
for(int k=0;k<box1[i].length();k++)
arr[box1[i][k]-'A']++;
for(int k=0;k<box2[j].length();k++)
arr[box2[j][k]-'A']++;
for(int k=0;k<26;k++)
{
if(arr[k]>=1)
continue;
else
{
flag=1;
break;
}
}
}
}
printf("%d",count);
return 0;
}
Can anyone explain what's wrong with :
arr[26] = {0};
You declare arr as:
int arr[26] = {0};
Which means valid indexes for it are 0-25, making 26 spots total. Then when you write to arr[26], you are actually writing outside of the array, and overwriting memory that your compiler assigned to n2.
If you want to be able to index to 26, you need to declare space for 27 ints:
int arr[27] = {0};
Also the code:
arr[26]={0}; // after the execution of this statement, n2 changes to 0.. WHY???
Only assigns to element 26 in the array. It does not zero out the entire array or anything like that. The way to zero the entire array at runtime is with arr = {0} or using the memset code you already have.

After padding a string with zeroes - it prints unspecified characters? (C++)

Basically, here, I'm trying to reverse an array, and convert the reversed int array into a string (I'm trying to write the equivalent of Java's BigInteger class in C++ - basically turning the input into big endian ordering, breaking down the operations, reversing the result back to little endian format, and returning the string).
And as you can see below, it outputs some strange characters (I think it's an out of range reference?) - but I'm not entirely sure what caused this output?
I would really appreciate if you could take a look at it:
Sample input
int a[] = {1, 2, 3};
int rA[3];
reverseIntArray(a, rA, 3);
string aString = intArrayToString(a, 3);
cout << aString << endl;
Console output
123\216\377
As you can see - it calculates the answer correctly, with the exception of the \277_\377.
I'll post the rest of the relevant functions:
reverseIntArray
void reverseIntArray(int array[], int reversedArray[], int arrayLength) {
for (int i = 0; i < arrayLength; i++) {
reversedArray[i] = array[arrayLength - 1 - i];
}
}
intArrayToString
string intArrayToString(int digits[], int length) {
// convert int array to char array
char digitsChar[length];
for (int i = 0; i < length; i++) {
digitsChar[i] = '0' + digits[i];
}
// convert char array to string
string intString(digitsChar);
return intString;
}
I'm quite sure this is a subtle issue to do with pointers, but I'm still relatively new to C++ (migrating from Java) and I've stared at this for hours but haven't come up with any ideas.
The std::string constructor you are using is assuming that the string you pass is properly terminated, which it isn't and that leads to undefined behavior as the std::string constructor goes beyond the end of the digitsChar array.
Three possible solutions:
Make room for another character in the digitsChar array and terminate it:
char digitsChar[size + 1];
for (...) { ... }
digitsChar[3] = '\0';
string intString(digitsChar);
Use another constructor where you pass the length of the character array:
string intString(digitsChar, length);
Append the characters directly to the string:
string intString;
for (int i = 0; i < length; i++) {
intString += '0' + digits[i];
}
There are of course other solutions as well, like for example using std::ostringstream.

using a string array in a function C++

this question should be easy and straight forward, but after searching online, I couldn't find an answer. might because the question is just too simple.
following code is from cplusplus.com. it's a function of making a string lowercase. I was intended to do something similar.
/* tolower example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i])
{
c=str[i];
putchar (tolower(c));
i++;
}
return 0;
}
and what I made is this:
void search(string A[], string B[], int k)
{
int temp;
for(int j = 0; j <= 4; j++)
{
for(int i = 0; i <= k; i++)
{
string str (A[i]);
int h = 0;
char lstr[] = B[j];
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
string key (B[j]);
.....
this part of the code is in a for loop. B[j] is a string array.
Visual Studio informed me that char lstr[] = B[j]; part is not right, the error message is:
Error: initialization with '{...}' expected for aggregate object.
I think the problem is that I didn't use the correct syntax of using a string array in a function. something should be done for B[j], in order to make it a char array. I couldn't figure it out.
is that something about pointer? sorry I haven't learn pointer yet.
does my question make sense for you? any help is greatly appreciated!!
If you're looking to make the letters in the string lowercase it's more readable to just work with strings all the way and use std::transform. For example,
// make sure to #include <algorithm>
// at the top
string lstr = B[j];
std::transform(lstr.begin(), lstr.end(), lstr.begin(), ::tolower);
This is much more natural and c++ idiomatic than working with char * directly and less error-prone.
You're trying to assign a char to char[]. You can get the effect you want with the following code:
....
int h = 0;
char* lstr = &B[j]; // point lstr to the address of j'th element of B.
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
.....
What this does is that lstr is now a pointer that points to the j'th character in B. Arrays are essentially pointers. When you do B[j], it's equivalent to writing char ch = *(B + j);, where B points to the address of the first character in the array of characters (otherwise known as string).
EDIT
After your edit, it now seems that you're trying to assign a std::string to a char. Here is the corrected solution.
....
int h = 0;
string& lstr = B[j]; // grab a reference to the j'th string in B.
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
.....
Here, lstr is essentially a reference to the j'th string in B and you can use it as a regular string just like how you're using string str(A[i]);, which makes a copy of the i'th string in A.
You're confusing character arrays and string objects here. A character array is an array of bytes of set size which is null terminated, while a string is an object which expands/contracts as is necessary and doesn't require the null terminator. You're attempting to assign a string object to a character array, which is unsupported. If you're working with string objects, and want to retrieve their equivalent character array, utilize the c_str() function:
const char* lstr = B[j].c_str()
Also, utilizing an array name of B and an index of j is hilarious.

Writing a loop to change the value in a int array with different names

My title is a bit confusing, but I'm trying to write a loop that will change the value in 81 arrays with different names. I want to either initiated the array with a value or an array of values. This is part of my sudoku solver code since I don't think I'm explaining it well.
int cell1[], cell2[9], cell3[9],cell4[9]......cell81[9]; // <-- this will make 81 cells with an array that can hold a possible of 9 candidates
cout << "User input: << endl; // lets use ...1.5...14....67..8...24...63.7..1.9.......3.1..9.52...72...8..26....35...4.9...
// as an example
Let's assume I store that input into a Char Array and I'm going to use a loop to decide whether to initiate the given value or '.' as an empty value.
For empty values, I'm looking to initialize the array with 1-9 values. I can do this easily with this code.
If( ( (int)charArray[ 0 ] - 48) > 0 ) { // type cast to int. Neg = initialize array with 1-9
// pos = initialize with original value
cell1[ 0 ] = (int)charArray[ 0 ] - 48;
} else {
cell1[ 9 ] = { 1,2,3,4,5,6,7,8,9};
}
I want to avoid writing this code 81 times for 81 cells ( Considered as writing junk code ). I can't figure out how to write the loop. I'm open to suggestions on how I can code this different using classes, functions, and etc. Thanks in advance.
Create the cell array as a 2-dimensional array, with 81 rows and 9 columns.
int cell[81][9];
Now you can loop through them using the syntax cell[r][c]. For instance,
for( i = 0; i < 81; ++i ) {
cell[i][0] = 1;
// ...
cell[i][8] = 9;
}
If you'd prefer to avoid 2-D arrays, you can declare the array as a 1-dimensional array, and just index into it appropriately.
int cell[81 * 9];
for( i = 0; i < 81; ++i ) {
cell[i + 0*81] = 1;
// ...
cell[i + 8*81] = 9;
}
int a1[9],a2[9],a3[9],a4[9],...
void init_array(int *ptr, const char *chr, int len, int start){
for(int i = start; i < len; i++){
if(chr[i] == '.')continue;
ptr[i] = chr[i]-'0';//converts character to integer.
}
}
int main(int argc, char **argv)
{
std::string str;
cin >> str;
init_array(a1,str.c_str(),9,0); init_array(a2,str.c_str(),9,9/*increment by 9*/);...
//..
return 0;
}
Write a function called init_array() that accepts an integer pointer and initializes the array for you. You can avoid duplicating the code this way.