No Instance of overloaded function vector of structs - c++

I creating a project from college where I have to recreate the Scrabble Junior game to a console Game, but I've got a problem and i question in my code.
Firstly, I've got an error in my code saying :
"no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=Board::Word, _Alloc=std::allocator<Board::Word>]" matches the argument list
argument types are: (Board::Word)
object type is: std::vector<Board::Word, std::allocator<Board::Word>>
The struct Word is this one:
struct Word {
int row;
int column;
char orientation;
int tilesadded = 0; //starts at 0
int wordlength;
bool completed = false;
int currentletterpositiontoAdd[2]; //array to hold the coordenates of the next tile to be added
std::string name;
};
This struct basically stores every word and it's position in the board
And then I have also a vector storing every word struct: std::vector <Word> words;
The code that builds this struct is the following (because I get from a file every word and position to the board):
void Board::GetBoard()
{
std::ifstream file;
std::string filename, input;
std::cout << "----------------------------------------------------------------------------------------" << std::endl << std::endl;
std::cout << "What is the directory of the board file? (.txt is added for you) -> ";
while (std::getline(std::cin, filename))
{
file.open(filename + ".txt");
if (!file.is_open())
{
std::cin.clear();
file.clear();
RED;
std::cerr << "Error reading file." << std::endl;
WHITE;
std::cout << "What is the directory of the board file? (.txt is added for you) -> ";
}
else
break;
}
while (std::getline(file, input))
{
if ((int)input[0] == 49 || (int)input[0] == 50)
{ //this means that its the first line of the file and the first character is either 1 or 2
boardSize = stoi(input.substr(0, 2));
}
else
{
std::string nametoCat;
Word word;
word.row = input[0] - 'A' + 1; //calculation of the position on the board using ascii code ex: input[0] = C so: 'C' -'A' + 1 = 3 row -> 3
word.column = input[1] - 'a' + 1; //calculation of the position on the board using ascii code ex: input[1] = e so: 'e' -'a' + 1 = 5 column -> 5
word.orientation = input[3];
word.currentletterpositiontoAdd[0] = word.row;
word.currentletterpositiontoAdd[1] = word.column;
for (int x = 5; x < 1000000000; x++)
{ //for loop to check the name ending and build a string with the name
if (input[x] == '\0')
break;
else
nametoCat += input[x];
}
word.name = nametoCat;
word.wordlength = word.name.size(); //storing the word length to use later to check if word is completed in board
words.push_back(word);
}
}
}
The file looks like this:
15 x 15
Ak H EGGS
Bg H BUZZ
Ca H MUSIC
Cm H ARM
...
And secondly, I would like to make the code look more "clean" and understandable and remove that 1000000000 from: for (int x = 5; x < 1000000000; x++) and do it another way, but i can't find a solution. Because this 1000000000 looks like a magic number and not a number that would always work, for example, wouldn't work with a word of size 1000000001 (unlikely but possible).
Thank you.

Related

How to fix endless periods?

As an assignment we were supposed to simply copy the code from our C++ book by D.S. Malik. This one is called "Text Processing". I've copied it exactly and read over the book a few more times trying to figure out the issue.
It's supposed to take the infile and copy&paste the text in the infile and then count the letters and list how many times a letter appears within the text. It pastes the text; however, whatever the last character is in the text it simply repeats that character infinitely. For me it is the period at the end of the text that it simply repeats repeatedly.
I'll show the text for the input below just before the code I've written.
infile text
The first device known to carry out calculation was the abacus.
The abacus was invented in Asia but was used in ancient Babylon,
Chine, and throughout Europe until the late middle ages. The aba-
cus uses a system of sliding beads in a rack for addition and sub-
traction. In 1642, the French philosopher and mathematician Blaise
Pascal invented the calculating device called the Pascaline. It
had eight movable dials on wheels and could calculate sums up to
eight figures long. Both the abacus and Pascaline could perform
only addition and subtraction operations. Later in the 17th cen-
tury, Gottfried von Leibniz invented a device that was able to add,
subtract, multiply, and divide.
What should be in the outfile
Today we live in an era where information is processed almost at the
speed of light. Through computers, the technological revolution is
drastically changing the way we live and communicate with one
another. Terms such as "the Internet," which were unfamiliar just
a few years ago, are very common today. With the help of computers you
can send letters to, and receive letters from, loved ones within
seconds. You no longer need to send a reĀ“sumeĀ“ by mail to apply for a
job; in many cases you can simply submit your job application via
the Internet. You can watch how stocks perform in real time, and
instantly buy and sell them. Students regularly "surf" the Internet
and use computers to design their classroom projects. They also use
powerful word-processing software to complete their term papers.
Many people maintain and balance their checkbooks on computers.
The number of lines = 15
A count = 53
B count = 7
C count = 30
D count = 19
E count = 81
F count = 11
G count = 10
H count = 29
I count = 41
J count = 4
K count = 3
L count = 31
M count = 26
N count = 50
O count = 59
P count = 21
Q count = 0
R count = 45
S count = 48
T count = 62
U count = 24
V count = 7
W count = 15
X count = 0
Y count = 20
Z count = 0
Code
#include <iostream>
#include <fstream>
#include <cctype>
using namespace std;
void initialize(int& lc, int list[]);
void copyText(ifstream& intext, ofstream& outtext, char& ch, int list[]);
void characterCount(char ch, int list[]);
void writeTotal(ofstream& outtext, int lc, int list[]);
int main()
{
//Step 1; Declare variables
int lineCount;
int letterCount[26];
char ch;
ifstream infile;
ofstream outfile;
infile.open("textin.txt"); //Step 2
if (!infile) //Step 3
{
cout << "Cannot open the input file."
<< endl;
return 1;
}
outfile.open("textout.out"); //Step 4
initialize(lineCount, letterCount); //Step 5
infile.get(ch); //Step 6
while (infile) //Step 7
{
copyText(infile, outfile, ch, letterCount); //Step 7.1
lineCount++; //Step 7.2
infile.get(ch); //Step 7.3
}
writeTotal(outfile, lineCount, letterCount); //Step 8
infile.close(); //Step 9
outfile.close(); //Step 9
return 0;
}
void initialize(int& lc, int list[])
{
lc = 0;
for (int j = 0; j < 26; j++)
list[j] = 0;
} //end initialize
void copyText(ifstream& intext, ofstream& outtext, char& ch, int list[])
{
while (ch != '\n') //process the entire line
{
outtext << ch; //output the character
characterCount(ch, list); //call the function character count
intext.get(ch); //read the next character
}
outtext << ch; //output the newline character
} //end copyText
void characterCount(char ch, int list[])
{
int index;
ch = toupper(ch); //Step a
index = static_cast<int>(ch) - static_cast<int>('A'); //Step b
if (0 <= index && index < 26) //Step c
list[index]++;
}//end characterCount
void writeTotal(ofstream& outtext, int lc, int list[])
{
outtext << endl << endl;
outtext << "The number of lines = " << lc << endl;
for (int index = 0; index < 26; index++)
outtext << static_cast<char>(index + static_cast<int>('A')) << " count = " << list[index] << endl;
} //end writeTotal

Why am I getting this error breaking my program? C++

I have a program for my c++ class that for some reason keeps breaking when I get to a certain point in my program.
Here is the header file of my
// This class has overloaded constructors.
#ifndef INVENTORYITEM_H
#define INVENTORYITEM_H
#include <string>
using namespace std;
class InventoryItem
{
private:
string description; // The item description
double cost; // The item cost
int units; // Number of units on hand
int inventoryItemNumber; //Used to sort items from first entered to last
public:
// Constructor #1
InventoryItem()
{ // Initialize description, cost, and units.
description = "";
cost = 0.0;
units = 0; }
// Constructor #2
InventoryItem(string desc)
{ // Assign the value to description.
description = desc;
// Initialize cost and units.
cost = 0.0;
units = 0; }
// Constructor #3
InventoryItem(string desc, double c, int u)
{ // Assign values to description, cost, and units.
description = desc;
cost = c;
units = u; }
// Mutator functions
void setDescription(string d)
{ description = d; }
void setCost(double c)
{ cost = c; }
void setUnits(int u)
{ units = u; }
// Accessor functions
string getDescription() const
{ return description; }
double getCost() const
{ return cost; }
int getUnits() const
{ return units; }
};
#endif
And this is my cpp file containing my main:
#include "InventoryItem.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main(){
InventoryItem item[1000];
string parsingArray[1000];
char command;
ifstream inFile;
string inFileName;
//The typecasting variables from string to int,string,double,int
//other possible integers ROUND 2
int itemNumber;
string description;
double cost;
int units;
//possible variables:
int count = 0;
int jTracker = 0;
string parsingArray2[1000];
while(true){
cout << "Command: ";
cin >> command; cin.ignore(80, '\n');
if (command == 'a') {
//Add parts: increase the units value for an existing inventory item.
}
else if (command == 'h') {
//Prints Help Text
cout << "Supported commands: \n"
<< " a Add parts.\n"
<< " h print Help text.\n"
<< " i Input inventory data from a file.\n"
<< " p Print invetory list.\n"
<< " n New invetory Item.\n"
<< " o Output invetory data to a file.\n"
<< " q quit (end the program).\n"
<< " r Remove Parts.\n"
<< endl;
}
else if (command == 'i') {
//Input inventory data from a file.
do{
cout << "Enter name of input file: ";
getline(cin, inFileName);
inFile.open(inFileName);
if (inFile.fail())
{
cout << "Failed to open file: " << inFileName << "\n\n";
}
}while(inFile.fail());
//write each line to string
for (int i = 0; inFile; i++) {
getline(inFile, parsingArray[i], '\n');
count++;//count will be needed for counting iterations of for loop for InventoryItem object data field completion
}
for (int k = 0; k < count; k++)
{
int newLine = 0;
int num = 0;
int oldDelimiter = 0, newDelimiter = 0;
int variable = 0;
for (int j = jTracker; num < variable; j++) {//jTracker continues to grow through multiple outer "k" loops.
newDelimiter = parsingArray[k].find("|", oldDelimiter); //newDelimiter becomes the further pipe delimiter in the line.
parsingArray2[j] = parsingArray[k].substr(oldDelimiter, ((newDelimiter)-oldDelimiter));//the pipe delimited strings are isolated in input2[]
oldDelimiter = newDelimiter + 1;//oldDelimiter is set to the next pipe delimiter.
variable = parsingArray[k].length();
//The following alters variables as needed for the next loop
num = newDelimiter;
jTracker = (j + 1);
newLine = j;
}
}
for(int y = 0; y < count; y++)
{
int itemNumber = stoi(parsingArray2[0+(4*y)]);
string description = parsingArray2[1+(4*y)];
double costs = stof(parsingArray2[2+(4*y)]);
int unit = stoi(parsingArray2[3+(4*y)]);
item[itemNumber].setDescription(description);
item[itemNumber].setCost(costs);
item[itemNumber].setUnits(unit);
}
cout << count << " records loaded to array.\n";
}
else if (command == 'p') {
}
else if (command == 'j') {
}
else if (command == 'o') {
}
else if (command == 'q') {
// Quit.
cout << "Exit." << endl;
system("pause");
return 0;
}
else if (command == 'r') {
}
else {
// Invalid user input, re-prompted.
cout << "Invalid command.\n";
}
}
}
The assignment was to create a program that does all the actions described in the help menu. I started with "i" which is to input text files' information into an array of InventoryItem onjects, containing description of item, cost of item and total number of item units. Also, inventoryitem # should be included, but the array spot held by the object is the same as the item number, so a variable isn't needed.
I try running the program, it runs. I type in "i" as my command. It asks for a file to input, I use the file "plumbing.txt". Plumbing.txt contains the following pipe-delimited text:
0|Pump|39.00|20
1|Gasket|1.50|29
2|Water Level Gauge|12.99|30
3|Faucet Repair Kit|4.89|8
4|Teflon Thread Seal Tape (50 ft roll)|3.30|12
5|shutoff valve|6.50|10
Once i hit enter after typing in "plumbing.txt", the program programs.
It looks like this:
"command: i
Enter file name for input: plumbing.txt"
And then the program breaks.
I narrowed down the part of the code to what actually causes the program to break and its something in this part of the code:
for(int y = 0; y < count; y++)
{
int itemNumber = stoi(parsingArray2[0+(4*y)]);
string description = parsingArray2[1+(4*y)];
double costs = stof(parsingArray2[2+(4*y)]);
int unit = stoi(parsingArray2[3+(4*y)]);
item[itemNumber].setDescription(description);
item[itemNumber].setCost(costs);
item[itemNumber].setUnits(unit);
}
Please help me figure out why my program keeps breaking. I cannot figure it out. I'm trying to read the input as strings from the file, parse the strings into individual pieces of data. Convert from string to integer or double using stoi or stof and enter the info into the array of objects. Thank you for reading and any help you can offer.
There are two issues with your code involving the use of for loops when it is better to use while. The first issue involves the block of code:
for (int i = 0; inFile; i++) {
getline(inFile, parsingArray[i], '\n');
count++;//count will be needed for counting iterations of for loop for InventoryItem object data field completion
}
Here, count is incremented even after we have reached the end of the file. As a result, count will be one more than the number of lines in the file. We can use a while loop instead:
while (getline(inFile, parsingArray[count], '\n'))
++count;
Here, getline will set the end-of-file flag for the inFile ifstream when the last line is read so that the while loop exits. With count initialized to zero before this while loop, the resulting count will correctly reflect the number of lines in the file.
The second issue involves the block of code:
for (int j = jTracker; num < variable; j++) {//jTracker continues to grow through multiple outer "k" loops.
newDelimiter = parsingArray[k].find("|", oldDelimiter); //newDelimiter becomes the further pipe delimiter in the line.
parsingArray2[j] = parsingArray[k].substr(oldDelimiter, ((newDelimiter)-oldDelimiter));//the pipe delimited strings are isolated in input2[]
oldDelimiter = newDelimiter + 1;//oldDelimiter is set to the next pipe delimiter.
variable = parsingArray[k].length();
//The following alters variables as needed for the next loop
num = newDelimiter;
jTracker = (j + 1);
newLine = j;
}
As pointed out by others, num and variable are both set to zero before this for loop so that the condition num < variable is never met. Therefore, the code within the for loop is never executed. Again, a while loop here will do:
while ((newDelimiter = parsingArray[k].find("|", oldDelimiter)) != std::string::npos) {
parsingArray2[j] = parsingArray[k].substr(oldDelimiter, ((newDelimiter)-oldDelimiter)); //the pipe delimited strings are isolated in input2[]
oldDelimiter = newDelimiter + 1; //oldDelimiter is set to the next pipe delimiter.
++j; // increment j
}
// get the last token and increment j
parsingArray2[j] = parsingArray[k].substr(oldDelimiter, std::string::npos); //the pipe delimited strings are isolated in input2[]
++j;
Here, find will return std::string::npos if there are no more delimiters (i.e., "|") to find. With j initialized to zero before the outer k for loop, this while loop will parse all tokens delimited by "|" except for the last one. Therefore, after the while loop, we extract the last substring using std::string::npos to denote that we want all characters from oldDelimiter until the end of the string. Note that the variables newLine, num, variable, and jTracker are all not needed.
In fact, we can combine the two while loops to get:
std::string line; // don't need parsingArray any more
int j = 0; // initialize j before looping over file
while (std::getline(inFile, line, '\n')) {
int oldDelimiter = 0, newDelimiter = 0;
while ((newDelimiter = line.find("|", oldDelimiter)) != std::string::npos) {
parsingArray2[j] = line.substr(oldDelimiter, ((newDelimiter)-oldDelimiter)); //the pipe delimited strings are isolated in input2[]
oldDelimiter = newDelimiter + 1; //oldDelimiter is set to the next pipe delimiter.
++j; // increment j
}
// get the last token and increment j
parsingArray2[j] = line.substr(oldDelimiter, std::string::npos); //the pipe delimited strings are isolated in input2[]
++j;
// increment count
++count;
}
which eliminates the need for the outer k for loop. Note also that the array parsingArray is no longer needed as there is no longer a need to store intermediate results accumulated from one loop to be iterated over and used in a subsequent loop.
Additional notes to consider:
Use std::vector instead of fixed size arrays for std::string and InventoryItem.
Declare variables "locally" for reasons discussed in this link.
In the subsequent for loop that sets the items, there is an assumption that the file contains exactly four tokens for each line (and that the tokens are exactly the item number (integer number), description (character string), cost (real number), and unit (integer number) in that order). You should carefully consider what will happen if the file does not satisfy this requirement (i.e., input data error), and how your program should handle all error cases. Maybe the code within that loop can be incorporated within the nested while loops so that errors can be detected and properly handled as the file is being parsed?

How to convert a string of integer numbers into an array in c++?

The problem:
A function which gets degrees and factors as inputs and returns a equation as output.
The issue:
I did not know how to read an array of numbers in form of a string in c++ back then in 2016 when I was a super junior. I also did not know how to search good enough!
Update:
I answered my question and you can test this in this link: http://cpp.sh/42dwz
Answer details:
Main part of the code will be like this:
int main()
{
Poly mypoly("2 -4 3", "1 5 1");
return 0;
}
Inputs are 2 -4 3 and 1 5 1.
Output should be (2X) + (-4X5) + (3X)
Class Poly has a built-in feature to print the result
To make it easier we should convert degrees and factors from a single string into an array of strings.
This means that a string like 2 -4 3 changes into [2, -4, 3] which makes it easy to iterate over items and create equation sentences
This action is called splitting a string into an array by a delimiter which I found here for c++ https://stackoverflow.com/a/16030594/5864034
Rest of the code is just looping over the array of degrees and factors to create sentences(which is pretty easy just check the answer link http://cpp.sh/42dwz)
The code:
// Example program
#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
using namespace std;
template <size_t N>
void splitString(string (&arr)[N], string str)
{
int n = 0;
istringstream iss(str);
for (auto it = istream_iterator<string>(iss); it != istream_iterator<string>() && n < N; ++it, ++n)
arr[n] = *it;
}
class Poly {
public:
string degree[10];
string factor[10];
Poly(string input_degree, string input_factor) {
splitString(degree, input_degree);
splitString(factor, input_factor);
for (int i = 0; i < 10; i++){
int this_degree = stoi(degree[i]);
int this_factor = stoi(factor[i]);
string this_sentence = "";
if(this_degree != 1 && this_degree != 0 ){
this_sentence = this_sentence + degree[i];
if(this_factor != 0){
if(this_factor != 1){
this_sentence = this_sentence + "X" + factor[i];
}else{
this_sentence = this_sentence + "X";
}
}
}
if(this_sentence != ""){
cout << "(" << this_sentence << ")";
}
if(stoi(degree[i+1]) != 0 && stoi(degree[i+1]) != 1){
cout << " + ";
}
}
}
};
int main()
{
Poly mypoly("2 -4 3", "1 5 1");
return 0;
}
The process of reading a string and extracting information from it into some sort of structure is called parsing. There are many ways to do this, and which way is appropriate depends on exactly what you want to do, how quickly it needs to run, how much memory you've got available and various other things.
You can write a simple loop which steps over each character and decides what to do based on some variables that store current state - so you might have a flag that says you're in the middle of a number, you see another digit so you add that digit to another variable which is collecting the digits of the current number. When the current number completes (perhaps you find a character which is a space), you can take what's in the accumulator variable and parse that into a number using the standard library.
Or you can make use of standard library features more fully. For your example, you'll find that std::istringstream can do what you want, out of the box, just by telling it to extract ints from it repeatedly until the end of the stream. I'd suggest searching for a good C++ input stream tutorial - anything that applies to reading from standard input using std::cin will be relevant, as like std::istringstream, cin is an input stream and so has the same interface.
Or you could use a full-blown parsing library such as boost::spirit - total overkill for your scenario, but if you ever need to do something like parsing a structured configuration file or an entire programming language, that kind of tool is very useful.
So for the community rules and to make it clear i want to answer my question.
#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
using namespace std;
template <size_t N>
void splitString(string (&arr)[N], string str)
{
int n = 0;
istringstream iss(str);
for (auto it = istream_iterator<string>(iss); it != istream_iterator<string>() && n < N; ++it, ++n)
arr[n] = *it;
}
class Poly {
public:
string degree[10];
string factor[10];
Poly(string input_degree, string input_factor) {
splitString(degree, input_degree);
splitString(factor, input_factor);
for (int i = 0; i < 10; i++){
int this_degree = stoi(degree[i]);
int this_factor = stoi(factor[i]);
string this_sentence = "";
if(this_degree != 1 && this_degree != 0 ){
this_sentence = this_sentence + degree[i];
if(this_factor != 0){
if(this_factor != 1){
this_sentence = this_sentence + "X" + factor[i];
}else{
this_sentence = this_sentence + "X";
}
}
}
if(this_sentence != ""){
cout << "(" << this_sentence << ")";
}
if(stoi(degree[i+1]) != 0 && stoi(degree[i+1]) != 1){
cout << " + ";
}
}
}
};
int main()
{
Poly mypoly("2 1 -4", "1 3 5");
return 0;
}

C++: Reading lines of integers from cin

As I'm familiarizing myself with the I/O aspect of C++, I'm trying to write a program to read some lines of integers from std::cin. Say the input looks like this:
1 2 3
4 5 6
7 8 9
10 11 12
How can I read the above lines into a 2D vector?
vector<vector<int>> nums;
/*
... some code here and nums will look like the following:
nums = {
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
}
*/
I've also tried to read the above lines of integers to a 1D vector, but I'm having some issues dealing with the '\n' character. My code is:
string rawInput;
vector<int> temp;
while(getline(cin, rawInput, ' ') ){
int num = atoi( rawInput.c_str() );
temp.push_back(num);
}
And the final result I got by printing out all the elements in the "temp" vector is:
1 2 3 5 6 8 9 11 12 // 4, 7, 10 went missing
Any help is appreciated. Thank you.
First use getline to grab an entire line, then you can use a istringstream to create a stream of ints just for that line.
At that point it's just a matter of creating each subvector of ints using the vector constructor that takes two iterators. An istream_iterator<int> on your istringstream gets this done:
std::vector<std::vector<int>> nums;
std::string line;
while (std::getline(std::cin, line)) {
std::istringstream ss(line);
nums.emplace_back(std::istream_iterator<int>{ss}, std::istream_iterator<int>{});
}
What is happening is since you are using only ' '(space) as deliminator, the input happens to be
1
2
3\n4 //<------ Newline also comes with the input
...
So, you are passing 3\n4, 6\n7 etc to atoi it returns 3,6 etc(atoi parses the input till first non-digit input) and the 4,7 is lost.
To achieve want you want you can use getline with istringstream (keeping the default deliminator as newline)
string rawInput;
vector<vector<int>> temp;
while(getline(cin, rawInput) ){
istringstream bufferInput(rawInput);
temp.push_back(vector<int>{std::istream_iterator<int>{bufferInput}, std::istream_iterator<int>{}});
}
you can use stringstream
string rawInput;
vector<int> temp;
stringstream ss;
while(getline(cin,rawInput)){
ss<<rawInput;
vector<int> temp;
int x;
while(ss>>x){
temp.push_back(x);
}
num.push_back(temp)
}
I recently wrote an answer to another question but with a few adaptations it achieves exactly what you are looking for (I hope):
#ifndef _IOSTREAM_H
#include <iostream>
#endif
#ifndef _STRING_H
#include <string>
#endif
#ifndef _VECTOR_H
#include <vector>
#endif
using namespace std;
enum XYZ { X = 0, Y = 1, Z = 2 };
struct Vector {
float x, y, z;
Vector(float _x=0, float _y=0, float _z=0) {
x = _x;
y = _y;
z = _z;
}
float& operator[](size_t index) {
if (index == XYZ::X) return x;
if (index == XYZ::Y) return y;
if (index == XYZ::Z) return z;
throw new exception;
}
};
#define min(a, b) (((a) < (b)) ? (a) : (b))
bool isCharNumeric(char c) {
const char* numbers = "0123456789";
for (size_t index = 0; index < strlen(numbers); index++)
if (c == numbers[index]) return true; return false;
}
vector<Vector> parseNumbers(string str_in) {
str_in += " "; //safe, no out of bounds
vector<Vector> results = {};
char currentChar;
char skipChar = ' ';
bool found_period = false;
size_t count_len = 0;
Vector vector_buffer(0,0,0);
XYZ current_axis = (XYZ)0;
for (size_t index = 0; index < str_in.length(); index++) {
currentChar = str_in[index];
if (currentChar == skipChar || currentChar == '\n' || currentChar == '\t')
continue;
else if (isCharNumeric(currentChar)) {
string word = ""; //word buffer
size_t word_len = min(min(str_in.find_first_of(' ', index + 1) - (index), str_in.find_first_of('\n', index + 1) - (index)), str_in.find_first_of('\t', index + 1) - (index)); //whatever char comes first; newline, tab or space
//append chars of following word checking if it is still valid number char
if (word_len > 0) {
size_t count_word_len = 0;
for (count_word_len = 0; count_word_len < word_len; count_word_len++)
if (isCharNumeric(str_in[index + count_word_len])) {
word += str_in[index + count_word_len];
}
else if (str_in[index + count_word_len] == '.' && isCharNumeric(str_in[index + count_word_len + 1])) {
//Floating-point numbers
word += '.';
found_period = true;
continue;
}
else {
word = "";
continue;
}
vector_buffer[current_axis] = stof(word);
if (current_axis == XYZ::Z) {
current_axis = XYZ::X;
results.push_back(vector_buffer);
}
else {
current_axis = (XYZ)(current_axis + 1);
}
index += count_word_len;
word = "";
continue;
}
}
}
return results;
}
Example implementation:
int main(int argc, char** argv) {
string user_input;
cin >> user_input;
vector<Vector> numbers = parseNumbers(user_input);
for each (Vector v in numbers) {
cout << "X=" << v.X << "\n";
cout << "Y=" << v.Y << "\n";
cout << "Z=" << v.Z << "\n\n";
}
}
Suprisingly none of the answers use the istream stream operator:
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
When stream is empty eofbit is set, so run a while loop on that.
Works great for all types, and can be overloaded for custom types (such as 2D texture).

If Statement not working, input unrecognised (C++)

My program runs without issues, compiles no errors.
The aim of my if statement is to choose if letters are shifted left/right which I have tried to achieve with an if statement leading to 2 functions, however no matter the input from cin >> z; it will always utilize CipherR. Can anyone help me figure this out?
//Start of Document
#include <WinUser.h> //Gives access to windows form library
#include "StdAfx.h" //Standard prefix for vb to save
#include <iostream> //Enables I/O stream cin/cout
#include <string> //Ensures that string data can be assigned
#include <Windows.h> //Gives access to windows library Included libraries, above <winuser.h>
using namespace std;
//Variables
char cipherR(char);
char cipherL(char);
int y;
const string LEFT = "1";
const string RIGHT = "0";
//Main Code
int main()
{
string input; //Declares string variable for temp storage
//MessageBox
int WinUserMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); //defines MessageBox parameters
const int message = MessageBox(NULL, L"Is your location secure?", L"Warning", MB_YESNOCANCEL); //sets up listener for messagebox response
//Switch Response
switch (message) //Initialise case study
{
case IDYES: //Runs this if Yes is selected
//cipher code block
do {
cout << "Enter text to be ciphered/deciphered." << endl;
cout << "Enter blank line to quit." << endl;
getline(cin, input); //Prompts for User Input, stores into temporary var
string output = ""; //Checks for blank input
cout << "Shift Left(1) or Right(0)? \n";
string z; //L or R definer
std::cin >> z;
cout << "Enter number to shift\n";
cin >> y;
if (z == LEFT)
{
for (int x = 0; x < input.length(); x++) // Loops until string.length is reached.
{
output += cipherR(input[x]);
}
} //Adds the value of expression to the value of a variable and assigns the result to the variable.
else if (z == RIGHT)
{
for (int x = 0; x < input.length(); x++) // Loops until string.length is reached.
{
output += cipherL(input[x]); //Adds the value of expression to the value of a variable and assigns the result to the variable.
}
};
cout << output << endl; // If input is blank will end process
} while (!input.length() == 0); //Loops while input.length is NOT equal to 0
break;
//alternate message responses
case IDNO: //Runs this if No is selected
MessageBox(NULL, L"Agents are converging on your location now.", L"Run!", NULL);
return 0;
break;
case IDCANCEL: //Runs this if cancel is selected
MessageBox(NULL, L"Why open this is you're gonna back out?", L"Alert", NULL);
return 0;
break;
}
}
//functions
char cipherR(char c) //function caesar, called into main
{
if (isalpha(c)) //checks if is part of the alphabet
{
c = toupper(c); //ignores casing of input for universal input
c = (((c - 65) + y) % 26) + 65; //performs caesar cipher with algebraic equation
return c; //returns encrypted data
}
if (!isalpha(c)) //if is not alphabetic will make blank
{
return 0; //returns blank
}
// if c isn't alpha, just send it back
}
char cipherL(char c) //function caesar, called into main
{
cout << "This Is left";
if (isalpha(c)) //checks if is part of the alphabet
{
c = toupper(c); //ignores casing of input for universal input
c = (((c - 65) - y) % 26) + 65; //performs caesar cipher with algebraic equation
return c; //returns encrypted data
}
if (!isalpha(c)) //if is not alphabetic will make blank
{
return 0; //returns blank
}
// if c isn't alpha, just send it back
}
//end of sheet
I believe you have your functions swaped. In
if (z == LEFT)
{
for (int x = 0; x < input.length(); x++) // Loops until string.length is reached.
{
output += cipherR(input[x]);
}
} //Adds the value of expression to the value of a variable and assigns the result to the variable.
else if (z == RIGHT)
{
for (int x = 0; x < input.length(); x++) // Loops until string.length is reached.
{
output += cipherL(input[x]); //Adds the value of expression to the value of a variable and assigns the result to the variable.
}
};
When you go into the "left" if statement you are calling cipherR() when you should be calling cipherL(). You also need to fix "right" as you are calling cipherL(). Fixed version:
if (z == LEFT)
{
for (int x = 0; x < input.length(); x++) // Loops until string.length is reached.
{
output += cipherL(input[x]);
// ^ L here
}
} //Adds the value of expression to the value of a variable and assigns the result to the variable.
else if (z == RIGHT)
{
for (int x = 0; x < input.length(); x++) // Loops until string.length is reached.
{
output += cipherR(input[x]); //Adds the value of expression to the value of a variable and assigns the result to the variable.
// ^ R here
}
};
It looks like you think -1 % 26 is 25.
It's not - it's either 1 or -1, depending on the implementation.
In your implementation, it's apparently positive since you get the same result for both shifts.
You can't use the modulus for the left shift.
Instead, use repeated addition:
c = c - y;
while (c < 'A')
{
c += 26;
}
You also want to look over which function you're calling for each case, as you have them switched around.