create matrix using character arrays in c++ - c++

I have 8 different arrays, and each array has 8 characters in it,
std::string str_v1 = v1.to_string();
char arr_v1[9] = {0};
std::copy(str_v1.begin(), str_v1.end(), arr_v1); // from str_v1 to str_v8
std::string str_v8 = v8.to_string();
char arr_v8[9] = {0};
std::copy(str_v8.begin(), str_v8.end(), arr_v8);
how to convert this into 8x8 matrix? I want to put these values column by column, like, each array is converted to one column of the matrix, like array1 to column1, array2 to column2, and so on, like array1 values will be placed like matrix[0][0], matrix[1][0], matrix[2][0] and so on..
I think, something like this needs to be done:
char matrix[8][8];
for( int y=0;y<8;y++)
{
matrix[y][0] = arr_v1[y];
matrix[y][1] = arr_v2[y];
matrix[y][2] = arr_v3[y];
matrix[y][3] = arr_v4[y];
matrix[y][4] = arr_v5[y];
matrix[y][5] = arr_v6[y];
matrix[y][6] = arr_v7[y];
matrix[y][7] = arr_v8[y];
}

for( int y=0;y<8;y++)
{
for( int z=0;z<8;z++)
{
switch(y)
{
case 0:
matrix[z][y] = arr_v1[z]; //Be pretty sure, possibly you are better than you believe
break; // I've placed y before z as y is the outer loop, hence it
case 1: // should be responsible for ROWS and z for COLUMNS
matrix[z][y] = arr_v2[z]; // Goes in matrix[0][1],[1][1],[2][1],[3][1]...[7][1]
break;
case 2:
matrix[z][y] = arr_v3[z]; // Goes in matrix[0][2],[1][2],[2][2],[3][2]...[7][2]
break;
case 3:
matrix[z][y] = arr_v4[z]; // Goes on
break;
case 4:
matrix[z][y] = arr_v5[z]; // And on
break;
case 5:
matrix[z][y] = arr_v6[z]; // And on
break;
case 6:
matrix[z][y] = arr_v7[z];
break;
case 7:
matrix[z][y] = arr_v8[z];
break;
}
} // Finally all 8 1x8 arrays stored into single 8x8 matrix
}
There you have it then your ways,each 1x8 coming as a COLUMN instead of a row as in previous one :)

char *matrix[9];
for (int i = 0; i < 9; ++i) {
matrix[i] = new char[9];
std::copy(your_ith_string.begin(), your_ith_string.end(), matrix[i]);
}
//Finish your work with the matrix
for (int i = 0; i < 9; ++i) {
delete[] matrix[i];
}

You yourself were quite correct :
for( int y=0;y<8;y++)
{
for( int z=0;z<8;z++)
{
switch(y)
{
case 0:
matrix[y][z] = arr_v1[z]; //Be pretty sure, possibly you are better than you believe
break; // I've placed y before z as y is the outer loop, hence it
case 1: // should be responsible for ROWS and z for COLUMNS
matrix[y][z] = arr_v2[z]; // Goes in matrix[1][0],[1][1],[1][2],[1][3]...[1][7]
break;
case 2:
matrix[y][z] = arr_v3[z]; // Goes in matrix[2][0],[2][1],[2][2],[2][3]...[2][7]
break;
case 3:
matrix[y][z] = arr_v4[z]; // Goes on
break;
case 4:
matrix[y][z] = arr_v5[z]; // And on
break;
case 5:
matrix[y][z] = arr_v6[z]; // And on
break;
case 6:
matrix[y][z] = arr_v7[z];
break;
case 7:
matrix[y][z] = arr_v8[z];
break;
}
} // Finally all 8 1x8 arrays stored into single 8x8 matrix
}
Hope this helps, if it doesn't just let me know, I'd be happy to help.

char matrix[8][8];
char *arr[8] = {arr_v1, arr_v2, arr_v3, arr_v4, arr_v5, arr_v6, arr_v7, arr_v8};
for( int y=0;y<8;y++) {
for (int i = 0; i < 8; ++i) {
matrix[y][i] = arr[i][y];
}
}

Related

How to convert char into int in a function?

poziomy= char;
pionowy= digit; ( no problems with this one)
So I need to convert char into a digit in function but obviusly I cannot do char=int, so I dont know how to pass on the converted char into digit properly.
I guees i can do two functions but maybe there is an easier way?
I thought of making a new variable poziomy_c but I dont know how to pass it to Ruch_gracza()
int Convert_digit (int cyfra)
{
switch (cyfra)
{
case 10: return 0;break;
case 9: return 1;break;
case 8: return 2;break;
case 7: return 3;break;
case 6: return 4;break;
case 5: return 5;break;
case 4: return 6;break;
case 3: return 7;break;
case 2: return 8;break;
case 1: return 9;break;
}
}
int Convert_letter (char literka)
{
switch (literka)
{
case 'A': return 0; break;
case 'B': return 1; break;
case 'C': return 2; break;
case 'D': return 3; break;
case 'E': return 4; break;
case 'F': return 5; break;
case 'G': return 6; break;
case 'H': return 7; break;
case 'I': return 8; break;
case 'J': return 9; break;
}
}
void Conwert(int &pionowy, char poziomy)
{
pionowy=Convert_digit(pionowy);
int poziomy_c;
poziomy_c=Convert_letter (poziomy);
}
void Ruch_gracza1 (int plansza[10][10])
{
int pionowy ;
char poziomy;
cout << "wprowadz wspolrzedne pola na ktorym lezy pion który chcesz ruszyc ( w pionie , potem w poziomie)" << endl;
cin >> pionowy >> poziomy;
Conwert (pionowy,poziomy);
cout << pionowy << endl;
cout << poziomy << endl;
}
You can use char arithmetic to make this a whole lot easier. Since 'A' to 'Z' will be contiguous in ASCII/Unicode, you can do literka - 'A' to get how far literka is from A (which is what your switch is doing):
int Convert_letter (char literka) {
if(!std::isalpha(literka)) { return literka; } // Not a letter
return std::toupper(literka) - 'A';
}
Or if you want a more robust solution to cover even less common character encodings:
int Convert_letter (char literka) {
if(!std::isalpha(literka)) { return literka; } // Not a letter
std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
return std::distance(std::begin(alphabet), std::find(std::begin(alphabet), std::end(alphabet), literka));;
}
Convert_digit will look similar (except with std::isdigit instead of std::isalpha).
You can do as
char c = 'B';
int digit = c - 'A';
return digit;
You need some knowledge about the ASCII table and data type in C++.
Simply, a char is an integer from -128 ... 127. If you declare a char variable name ch like this:
char ch = 'B';
C++ will understand that ch = 66 (look at ASCII table). So that we can do arithmetic operator with ch like an integer variable.
ch - 'A'; // result 1, because 'A' = 65
ch - 65; // same result with ch - 'A'
Finally, you can write your function like this:
int functionChar2Int(char x){
return x - 'A';
}

Unhandled exception thrown: read access violation. _Pnext was 0xC

I'm writing a program for class that basically runs page replacement algorithms 1000 times to show which has fewer average page faults. My problem is with an error I recieve from xmemory.
The code is reduced to areas where the error consistently occurs.
checkFrames() checks an array to see if it already contains the inputString[i].
frames1, frames2, etc. are arrays that the input is being assigned to according to the algorithm, each of size corresponding their number.
randomInputString() is just how it sounds.
constexpr auto INPUTNUM = 10;
list<int> framesLRU;
list<int>::iterator it;
int frames = 1;
void LRU()
{
for (int i = 0; i < INPUTNUM; i++)
{
bool inFrames = checkFrames(inputString[i]);
if (inFrames == true)
{
it = find(framesLRU.begin(), framesLRU.end(), frameRep);
framesLRU.erase(it);
framesLRU.push_back(frameRep);
}
else
{
int frameUpdate = framesLRU.front();
framesLRU.pop_front();
framesLRU.push_back(frameUpdate);
switch (frames)
{
case 1:
frames1[frameUpdate] = inputString[i];
break;
case 2:
frames2[frameUpdate] = inputString[i];
break;
case 3:
frames3[frameUpdate] = inputString[i];
break;
case 4:
frames4[frameUpdate] = inputString[i];
break;
case 5:
frames5[frameUpdate] = inputString[i];
break;
case 6:
frames6[frameUpdate] = inputString[i];
break;
case 7:
frames7[frameUpdate] = inputString[i];
break;
}
pageFaults++;
}
if ((i < frames) && (inputString[i] == 0))
pageFaults++;
}
}
int main()
{
srand(time(NULL));
for (int i = 0; i < 1000; i++)
{
randomInputString();
frames = 1;
do
{
runLRU(i);
frames++;
} while (frames <= 7);
}
printTable();
return 0;
}
The error always happens in the 59th iteration of i in the for loop in main, but within the do while loop it seems random as to when it occurs.
Although it does seem to be happening here:
it = find(framesLRU.begin(), framesLRU.end(), frameRep);
framesLRU.erase(it);
framesLRU.push_back(frameRep);
within the LRU() function. The iteration of i and the value of frames does not seem to be consistent for the error.
Edit: I figured out the problem. It was an error on my part with how I was assigning values in an array.

Card Game program in the process. Not sure why im getting a random number -858993460

Pretty much creating a card game for class. Not looking for straight up answers but a better understanding to learn the material of why im getting the problem i am. Thanks for any help i can get. Heres the problem:
Create a card game called flash card using struct data structure when each player draws three cards for random numbers (1-4) as Diamond, Spade, Clubs and Hearts respectively and another set of random numbers of card value 1-13. The cardScore is defined as highest (say cardScore =100 for three A s’ (cardValue 1), followed by three Jacks (cardValue 11) (say cardScore 90), followed by three Kings (cardValue 13)(say cardScore =80) and then three Queens (cardValue 12)(say cardScore = 70). Other than the above said combinations the cardScore is defined by the sum of the cardValue of each draw. The player which has the highest score after three draws win. Display the cards drawn by each player and the cardScore and the winner
#include "pch.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include <math.h>
using namespace std;
class Values
{
public:
string cardFace;
int cardValue;
int cardFaceRng;
int cardValueRng;
private:
};
//declaring functions
void setCardFaceRandom();
void setCardValueRandom();
void setCardFace();
void setCardValue();
int main()
{
Values v;
for (int i = 0; i < 3; i++)
{
v.cardFaceRng = rand() % 3 + 1;
v.cardValueRng = rand() % 14 + 1;
//setCardFaceRandom();
//setCardValueRandom();
setCardFace();
setCardValue();
cout << v.cardFace << " " << v.cardValue << endl;
}
system("pause");
return 0;
}
void setCardFace() {
Values v;
switch (v.cardFaceRng)
{
case 0:
v.cardFace = "Diamond";
break;
case 1:
v.cardFace = "Spade";
break;
case 2:
v.cardFace = "Club";
break;
case 3:
v.cardFace = "Hearts";
break;
}
cout << v.cardFace;
}
void setCardValue() {
Values v;
switch (v.cardValueRng)
{
case 0:
v.cardValue = 2;
break;
case 1:
v.cardValue = 3;
break;
case 2:
v.cardValue = 4;
break;
case 3:
v.cardValue = 5;
break;
case 4:
v.cardValue = 6;
break;
case 5:
v.cardValue = 7;
break;
case 6:
v.cardValue = 8;
break;
case 7:
v.cardValue = 9;
break;
case 8:
v.cardValue = 10;
break;
case 9:
v.cardValue = 11;
break;
case 10:
v.cardValue = 12;
break;
case 11:
v.cardValue = 13;
break;
case 12:
v.cardValue = 14;
break;
}
cout << v.cardValue;
}
void setCardFaceRandom()
{
Values v;
v.cardFaceRng = rand() % 3 + 1;
}
void setCardValueRandom()
{
Values v;
v.cardValueRng = rand() % 14 + 1;
}
Using only one of the functions as an example. All functions have the same problem:
void setCardFace() {
Values v;
switch (v.cardFaceRng)
This creates a new local variable in this function called v, and default-constructs it. Since the Values class does not have an explicit constructor, all class members are default-constructed, and for int members of this class, they're not initialized to anything. They're random garbage. So this v.cardFaceRng is random garbage, and from this point on, it's undefined behavior.
The v object in this function, setCardFace() has absolutely nothing to do with the v object you declared and initialized in your main(). All objects declared inside functions are local objects to that function, that only exist in that function, and are destroyed when the function returns; and different functions can have different local objects that have the same name, and are, otherwise, completely independent of each other.
In order for this setCardFace() class to use the object you declared and initialized in your main() -- as your obvious intent is here -- you need to explicitly pass it as a parameter to this function, and all other functions you declared -- and preferably pass it by reference.

c++ Roman Additive Form Conversion

I'm working in a program that converts from Roman to Decimal. I have to validate 2 things: One that the characters entered are M or D or C or L or X or V or I, in other words valid for processing.
Number two, I have to make sure that bigger characters value go first and if not to print and error message and have the user to try again (this is the part where I am stuck)
For instance, If I wanted to input 9 and I input IX it should display an error message because is not in Additive form. It should be VIIII. How can I code this so it compares characters to know whether bigger letter values are first and so on?
I keep getting incorrect validation.
Is there a way to assign a value to the letters in the string? I'm thinking in comparing them as int values which I know how to and from there validate input format.
void RomanNum::setRomanNumber() //get input and calculate decimal equivalent
{
//I 1, V 5, X 10, L 50, C 100, D 500, M 1000
int value = 0;
string input;
char current, next;
enum validationData { M, D, C, L, X, V, I };
bool validationCharacters = true;
//bool validationAdditiveForm = true;
getline(cin, input, '\n');
for (int i = 0; i < input.length(); i++) //calculate each Roman letter at a time
{
current = input[i];
next = current + 1;
if (current >= validationData(next))
{
switch (input[i])
{
case 'M':
value += 1000;
break;
case 'D':
value += 500;
break;
case 'C':
value += 100;
break;
case 'L':
value += 50;
break;
case 'X':
value += 10;
break;
case 'V':
value += 5;
break;
case 'I':
value += 1;
break;
default:
validationCharacters = false;
break;
}
}
else
{
cout << "\nInvalid order. Bigger values go first\n";
}
}
}
I would recommend a std::map<char, int> to hold the mapping between letetrs and values.
With the map, you can then convert the input string (a sequence of characters) to a sequence of values (std::vector<int>). From there on, it's just a single check to see if the vector is sorted, and a single function call to add up all values. (I'll leave finding the right function as homework)

int or char enum to int , not ASCII

I'm doing a poker game and have hit a wall. Any help would be great.
I have 12 card values. The values are chars either 2-9 or TJQKA (enumed below). I need to pass them to an int array such that their value is what gets passed (whether int value or enum value) instead of their ASCII.
for the example below, I want:
val[5] = {2,5,10,12,11}
instead of:
val[5] = {50,53,84,81,74}
enum cardvalues {T=10 , J , Q , K , A}
int val[5];
string value = "25TQJ";
for (int i = 0; i < 5; i++)
{
val[i] = value[i];
}
I would highly recommend using a map rather than an enum.
map<char,int> myCardMap;
myCardMap['T'] = 10;
...
val[i] = myCardMap[value[i]];
You'll need a conversion function:
int to_card(const char v)
{
switch(v)
{
case '2': return 2;
case '3': return 3:
// etc...
case 'T': return 10;
case 'J': return 11;
// etc...
}
Then in your loop:
val[i] = to_card(value[i]);
Make an std::map with ascii values in key and enum values in value
std::map<char, int> asciiMap;
asciiMap['T'] = 10;
asciiMap['J'] = 11;
//etc....
and then match the characters with the map
Generally you would need to convert the values from char to int. Here's the easiest way.
int convert_from_char(char c) {
if (c >= '2' && c <= '9') return (int)(c - '0');
else {
switch(c) {
case 'T': return (int)T;
case 'J': return (int)J;
case 'Q': return (int)Q;
case 'K': return (int)K;
case 'A': return (int)A;
default:
/* your program is borked. */
exit(1);
}
}
}
Then change your loop
for (int i = 0; i < 5; ++i)
val[i] = convert_from_char(value[i]);
I would suggest reconsidering using enums to represent cards, though. It will be easier in the long run just to make your own type, or use integers.
There is no way to directly convert from an enum symbol to the corresponding integer in C++ at runtime (obviously the compiler can do this at compile time). You may need to write a small helper function:
int card_value(char c) {
if (isdigit(c)) {
return c - '0';
} else {
switch (c) {
case 'T': return 10;
case 'J': return 11;
case 'Q': return 12;
case 'K': return 13;
case 'A': return 14;
default:
// whatever error handling here, such as:
return -1;
}
}
}
I suggest a switch:
switch (value[i]) {
case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
val[i] = atoi(value[i]);
break;
case 'T':
val[i] = 10;
break;
case 'J':
val[i] = 11;
break;
case 'Q':
val[i] = 12;
break;
case 'K':
val[i] = 13;
break;
case 'A':
val[i] = 14;
break;
default:
printf("Invalid character passed\n");
}
Create a function that will take a char argument (the ASCII card value, such as 'J') and return its numerical value. You might find the isdigit function and switch statement helpful.
If im understanding you correctly, you want to convert the string into card values (although for some reason you have the ace as 13 - id be tempted to say use 1 as the ace, although i can see you logic for it in a poker game).
Just using an enum wont help as at runtime you dont really have the information you need. An enum is a compile time concept mainly to assist the programmer and to handle checking.
There are many way to do what you want, you could have an array of index to char or a two entry array of char and value. For ease of alterations i would go with the following
typedef struct
{
char m_cCharacter;
int m_nValue;
} LOOKUP;
LOOKUP lookup_data[] = {
{ "2", 2 },
{ "3", 3 },
{ "4", 4 },
{ "5", 5 },
{ "6", 6 },
{ "7", 7 },
{ "8", 8 },
{ "9", 9 },
{ "T", 10 },
{ "J", 11 },
{ "Q", 12 },
{ "K", 13 },
{ "A", 14 }
};
int GetCharacter(char c)
{
int retval = -1; // Invalid
for(int i = 0; i < 13; i++)
{
if ( lookup_data[i].m_cCharacter == c )
{
retval = lookup_data[i].m_nValue;
break;
}
}
return retval;
}
for (int i = 0; i < 5; i++)
{
val[i] = GetCharacter(value[i]);
}
There are better ways with STL, and you should have more error checking and length of array detections, but hopefully you get the idea. You could use the enum in the lookup such as
{ "T", T },
If you preferred. Btw - i havent compiled this code so it probably wont build ;)
Try building a static array of size 256 such that the following gives the right answer:
for (int i = 0; i < 5; i++)
{
val[i] = AsciiToInt[value[i]];
}
That is,
AsciiToInt['2'] == 2
AsciiToint['T'] == 10,
AsciiToInt['J'] == 11
etc, but all invalid entries are zero.