Read file line by line using ifstream in CPP and Customize code to print number of frequency and percentage - c++

The genetic code is the set of rules used by living cells to translate information encoded within genetic material (DNA or mRNA sequences of nucleotide triplets, or codons) into proteins. The genetic code is highly similar among all organisms and can be expressed in a simple table with 64 entries.
A three-nucleotide codon in a nucleic acid sequence specifies a single amino acid. The vast majority of genes are encoded with a single scheme often referred to as the genetic code (refer to the codon table).
Attached to this assignment, you will find a text file named “mouse.dat” that contains the complete genome of a mouse. Write a program to read in the DNA sequence from the file, calculate the frequency of each codon in the codon table, and print out the result as a number and a percentage.
(a) Write a serial code for the solution "Normal Code by using C++ Language".
When I compiled the above code I got the below error message "Unable to open file mouse.dat: No such file or directory"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
std::vector<string> codons = { "ttt" }; // Better always initialize any variable or array or objects to zero or NULL or empty string.
codons.push_back("ttc"); // { "ttt", "ttc"
codons.push_back("tta"); // { "ttt", "ttc", "tta"
codons.push_back("ttg"); // { "ttt", "ttc", "tta", ...
codons.push_back("tct");
codons.push_back("tcc");
codons.push_back("tca");
codons.push_back("tcg");
codons.push_back("tat");
codons.push_back("tac");
codons.push_back("taa");
codons.push_back("tag");
codons.push_back("tgt");
codons.push_back("tgc");
codons.push_back("tga");
codons.push_back("tgg");
codons.push_back("ctt");
codons.push_back("ctc");
codons.push_back("cta");
codons.push_back("ctg");
codons.push_back("cct");
codons.push_back("ccc");
codons.push_back("cca");
codons.push_back("ccg");
codons.push_back("cat");
codons.push_back("cac");
codons.push_back("caa");
codons.push_back("cag");
codons.push_back("cgt");
codons.push_back("cgc");
codons.push_back("cga");
codons.push_back("cgg");
codons.push_back("att");
codons.push_back("atc");
codons.push_back("ata");
codons.push_back("atg");
codons.push_back("act");
codons.push_back("acc");
codons.push_back("aca");
codons.push_back("acg");
codons.push_back("aat");
codons.push_back("aac");
codons.push_back("aaa");
codons.push_back("aag");
codons.push_back("agt");
codons.push_back("agc");
codons.push_back("aga");
codons.push_back("agg");
codons.push_back("gtt");
codons.push_back("gtc");
codons.push_back("gta");
codons.push_back("gtg");
codons.push_back("gct");
codons.push_back("gcc");
codons.push_back("gca");
codons.push_back("gcg");
codons.push_back("gat");
codons.push_back("gac");
codons.push_back("gaa");
codons.push_back("gag");
codons.push_back("ggt");
codons.push_back("ggc");
codons.push_back("gga");
codons.push_back("ggg"); // // { "ttt", "ttc", "tta", ..., "ggg"}
// codons.size() is 64
vector<int> counts(64, 0);
string line = ""; // Always initialize.
// int numberOfLines=0; // warning: unused variable numberOfLines
char my_character = '\0'; // Always initialize.
for (int indx = 0; 64 > indx; indx++) // Better compare using "number comparison variable" way
{
string codon_req = codons[indx];
ifstream myfile("mouse.dat");
if (myfile.is_open())
{
int cnt = 0, ans = 0;
while (!myfile.eof())
{
myfile.get(my_character);
// If number of count "cnt" becomes 3 reinitialize that to zero.
// and increase "ans" count
if (3 == cnt)
{
ans++;
cnt = 0;
}
if ('\n' == my_character)
{
continue;
}
// Here comparison is not done sequential
// Search if first charater (example t at ttt) is present
// increase cnt
// Next time if it is not present
// compare until we find next letter t
// if found increase cnt at that time.
// Hence ans count is more greater than expected count on word ttt
// NOT SURE ON YOUR PROJECT REQUIREMENT.
if (my_character == (char)codon_req[cnt])
{
cnt++;
}
}
myfile.close();
counts[indx] = ans;
}
else
{
perror("Unable to open file mouse.dat");
exit(1);
}
}
for (int indx = 0; 64 > indx; indx++) //// Better compare using "number comparison variable" way
{
cout << "Before counts[indx] " << counts[indx] << "\n";
codons[indx] = codons[indx] + " " + to_string(counts[indx]);
cout << "After counts[indx] " << counts[indx] << "\n";
}
ofstream newFile("results.txt");
if (newFile.fail())
{
perror("Opening results.txt file failed");
exit(2);
}
else
{
for (int indx = 0; 64 > indx; indx++) /// Better compare using "number comparison variable" way
{
newFile << codons[indx] << '\n';
}
newFile.close();
}
return 0;
}
END

Related

C++ How to find the longest possible combination of decreasing numbers in an array

I am working on a problem in which I'm given a list of numbers representing the diameter of cake layers (for example: 9 12 10 7 4 6 11 5). With this list, I have to find the length of the longest combination of numbers that are equal to or decreasing (stacking cake layers from greatest diameter at the bottom to smallest at the top). You are allowed to skip over numbers, but you can't come back to them. I.e. with the previous list, the length of the longest combination would be 5 with the combination being (12,10,7,6,5).
I believe that the best way to solve this would be feeding the array into a tree and returning the height of the tree. This is currently the code I have, with a working tree implementation above the main
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string sizeInput, transfer; //Strings to hold input and transfer to array
int maxLayers = 0, numOfInputs = 0, numNodes = 0; //ints for holding the max height and the number of inputs by the user
int cakeSizes [30]; //Array holding sizes of the cakes input, no more than 30
cout << "Cake sizes: ";
getline(cin,sizeInput); //Gets input from user and puts into a stringstream
stringstream readInput(sizeInput);
while(readInput >> transfer)
{
cakeSizes[numOfInputs] = stoi(transfer); //Puts the numbers into the array and counts how many were placed
numOfInputs++;
}
for(int i=0; i<numOfInputs; i++) //Puts the array into a tree
{
Tree<int> cakeStack; //Creates tree to hold combination
initialize(cakeStack);
for(int j=i; j<numOfInputs; j++)
{
if(cakeSizes[j]<=cakeSizes[j-1])
{
insert(cakeStack, cakeSizes[j]);
}
}
if(height(cakeStack) > maxLayers) //Checks if the new combination tree's height is greater than the last
{
maxLayers = height(cakeStack);
}
destroy(cakeStack); //Destroys the tree from the previous combination in preparation for new one
}
cout << endl << "You can build a cake with " << maxLayers << " layers.";
}
This actually works for combinations that are always decreasing (like 5,4,2,1 and 8,3,2,1), but it fails when interrupting numbers are thrown in (like with 5,4,2,8,1). I'm almost certain that the problem lies here:
for(int j=i; j<numOfInputs; j++)
{
if(cakeSizes[j]<=cakeSizes[j-1])
{
insert(cakeStack, cakeSizes[j]);
}
}
But I'm unsure of how to implement it an a way that checks all combinations of the array (like skipping numbers that wouldn't give the longest combination), rather than running straight down the list unable to skip numbers.
The tree is definitely the way to go. You build the tree by inserting each value under the smallest node larger than it. Then when the tree is finished you iterate through it looking for the longest path.
What I did in the code below is I made a head node to store the sub trees and it needed a really large value so that all the inputs would fit under it. But then when I print the tree or look for a path I need to ignore that head node, so I have to keep track of the depth.
#include <iostream>
#include <vector>
#include <climits>
struct Tree {
Tree(int value) : value(value) {}
int value;
std::vector<Tree> children;
};
// Recursively check this level of the tree
void insert_node(Tree& node, int value)
{
// if the new value is bigger than where
// we are then stop descending
if (value > node.value)
return;
// if the new value fits under this
// parent then check all the children
bool inserted = false;
for (Tree& child : node.children)
// if we find a child large enough
// then insert ourselves inside
if (value < child.value)
{
insert_node(child, value);
inserted = true;
}
// if the new value fits under this parent but
// not under any of the children then put it here
if (!inserted)
node.children.push_back(value);
}
void print_tree(Tree node,
std::vector<bool> flags = std::vector<bool>(100, true),
bool last = false,
int depth = 0)
{
for (int i = 1; i < depth; ++i)
{
if (flags[i])
std::cout << "| ";
else
std::cout << " ";
}
// Don't print our fake head
if (depth > 0)
{
std::cout << "+- " << node.value << '\n';
if (last) flags[depth] = false;
}
int n = 0;
for (Tree child : node.children)
{
last = (n++ == node.children.size() - 1);
print_tree(child, flags, last, depth + 1);
}
flags[depth] = true;
}
void print_path(std::vector<int> path)
{
std::cout << "Path:";
for (int value : path)
std::cout << " " << value;
std::cout << "\n";
}
void print_paths(Tree node,
std::vector<int>& max_path,
std::vector<int> path = std::vector<int>(),
int depth = 0)
{
// Don't add our fake head
if (depth > 0)
path.push_back(node.value);
if (node.children.size() == 0)
{
print_path(path);
// check if this path is the longest one yet
if (max_path.size() < path.size())
max_path = path;
}
for (Tree child : node.children)
print_paths(child, max_path, path, depth + 1);
}
int main()
{
Tree head(INT_MAX);
std::vector<int> input = {9, 12, 10, 7, 4, 6, 11, 5};
// Build the tree
for (int value : input)
insert_node(head, value);
// Print the tree
std::cout << "Tree:\n";
print_tree(head);
std::cout << "\n";
// Print the paths and
// find the longest one
// and then print it too
std::vector<int> max_path;
print_paths(head, max_path);
std::cout << "\nLongest ";
print_path(max_path);
return 0;
}

Is there a way to run a statement when a condition in a loop is met at least once?

I am currently doing games on my free time and am currently working on a hangman game. However, I have stumbled upon a problem and I think I could solve it if there was a way to run a statement if a condition inside a loop is met at least once, and if the condition isn't met even once, it'll do another thing. Is it possible to do? Does anyone have any ideas?
I appreaciate any suggestions.
I tried doing something like this:
for (){
if (string [i] == letter that the player inputed){
// replace underscores with the letter guessed
// and also turn a bool statement true
}
else {
// turn the bool statement false
}
}
if (!bool variable){
// print that the letter guessed was not in the answer
// and substract one from the number of guesses available
}
However I noticed that it doesn't work because the loop will run and if the last letter that it checks is not in the answer, the bool will turn false, thus printing that the letter was not in the answer and substracting one from the score. (It's also my first time posting here, and I don't know if that's how I'm supposed to write a code, so I apologize beforehand if I'm not doing it correctly)
`
You should approach this problem from the different angle:
for( ... ) {
if( your condition is met ) {
do_whatever_you_have_to();
break; // <<--- exit the loop, so it's done only once
}
}
You don't have to put flag guessed off if the comparation fails
string s;
bool guessed = false;
char inputted_letter; // comes from somewhere
for (size_t i = 0; i < s.size(); ++i) {
if (s[i] == inputted_letter) {
// replace underscores with the letter guessed
guessed = true;
}
}
if (!guessed) {
// print that the letter guessed was not in the answer
// and substract one from the number of guesses available
}
You don't have to set false in the loop:
bool has_found = false;
for (auto& c : word_to_guess)
{
if (input_letter == c) {
// replace _ by current letter...
has_found = true;
}
}
if (!has_found){
// print that the letter guessed was not in the answer
// and substract one from the number of guesses available
}
But I suggest that your loop does only one thing at a time:
bool contains(const std::string& word_to_guess, char input_letter)
{
return std::any_of(word_to_guess.begin(),
word_to_guess.end(),
[&](char c){ return input_letter == c; })
/*
for (auto& c : word_to_guess)
{
if (input_letter == c) {
return true;
}
}
return false;
*/
}
if (contains(word_to_guess, input_letter)
{
// show current letter...
for (std::size_t i = 0; i != hangman_word.size(); ++i) {
if (word_to_guess[i] == input_letter) {
hangman_word[i] = word_to_guess[i];
}
}
} else {
// print that the letter guessed was not in the answer
// and substract one from the number of guesses available
}
Can you do what you are asking; possibly, however you stated you were making the game Hangman in C++ and I think you are going about this with the wrong approach, therefore, choosing or implementing the wrong algorithms. You are trying to traverse through two strings with possible different lengths from the back end which if it isn't done correctly can lead to issues, will tend to be hard to track especially if their comparisons determine loop conditions, exit or return statements.
I have implemented my version of "Hangman", now albeit the formatting isn't the prettiest, nor are the level dictionaries being generated from a large pool of random words. I express this in the comments of the code that these would generally be read in from a text file and saved into these structures. For simplicity's sake, I initialized them with random words directly in the code.
Take a look to see what I've done:
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <random>
class Game;
int main() {
using namespace util;
try {
Game game("Hangman");
game.start();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
class Game {
private:
std::string title_;
bool is_running_{ false };
std::string answer_;
std::string guessed_;
std::map<unsigned, std::vector<std::string>> dictionary_; // unsigned represents difficulty level of word
unsigned choosen_difficulty_;
std::string guessed_characters_{"\n"};
public:
Game(const std::string& title) : title_{ title }, choosen_difficulty_{ 0 } {
initialize();
start_over();
}
void start() {
is_running_ = true;
// the player has as many attempts as twice the length of hidden answer's word length.
int number_tries = answer_.size() * 2;
while (is_running_ || number_tries > 0) {
displayGuessedWord();
displayGuessedCharacters();
// ask the player to guess a character;
char guess;
// get a character and make sure it is a valid alphabet character
do {
std::cout << "Guess a character ";
std::cin >> guess;
// Note: I'm using ascii characters in this case
// but for demonstration purposes only!
if ((guess < 'a' && guess > 'z') ||
(guess < 'A' && guess > 'Z')) {
std::cout << "invalid entry ";
}
} while ( (guess < 'a' && guess > 'z') ||
(guess < 'A' && guess > 'Z') );
// test character and update guessed word and number of tries.
test_character(guess);
update_guessed_characters(guess);
number_tries--;
// failed condition
if (number_tries <= 0 && guessed_ != answer_) {
std::cout << "\nGame Over!\n";
is_running_ = try_again(number_tries);
// winning condition
} else if (number_tries > 0 && guessed_ == answer_) {
std::cout << "\nCongratulations!\n";
is_running_ = try_again(number_tries);
}
if (!is_running_) break;
}
}
private:
void displayGuessedWord() {
std::cout << '\n' << guessed_ << '\n';
}
void displayGuessedCharacters() {
std::cout << guessed_characters_ << '\n';
}
void initialize() {
// Normally this would be read in from a file upon game initialization
// but for demonstration purpose, I'll generate a few small vectors of strings
// and associate them to their difficulty level
// levels are based on 3 factors, the length of the word, the repetitive occurance
// of common characters, and the amount of less commonly used characters.
std::vector<std::string> level_1{ "ate", "cat", "dog", "coat", "coal", "does" };
std::vector<std::string> level_2{ "able", "believe", "balloon", "better", "funny", "happy" };
std::vector<std::string> level_3{ "ability", "carpenter", "dogmatic", "hilarious", "generosity", "hostility" };
// ... etc. I'll use just these here for simplicty where each vector has six entries, however,
// with random number generators, this can be done generically for any size
// or number of elements in each of the different vectors.
// create generate the map:
dictionary_[1] = level_1;
dictionary_[2] = level_2;
dictionary_[3] = level_3;
}
std::string getWordFromDictionary(unsigned difficulty, std::map<unsigned, std::vector<std::string>>& dict) {
auto level = dict[difficulty]; // extract the vector based on difficulty level
auto size = level.size(); // get the size of that vector
std::random_device dev; // create a random device
std::mt19937 rng(dev()); // create a pseudo random generator
// create a uniform int distribution type with the range from 0 to size-1
std::uniform_int_distribution<std::mt19937::result_type> dist(0, size - 1);
return level[dist(rng)]; // return a random string from this level.
}
void start_over() {
system("cls"); // Note: I'm running visual studio on Windows!
std::cout << "Welcome to " << title_ << '\n';
// We can use a random generator to pick a word from the given difficulty
// but first we need to get user input for the chosen level.
do {
std::cout << "Choose your difficulty [1-3]\n";
std::cin >> choosen_difficulty_;
if (choosen_difficulty_ < 1 || choosen_difficulty_ > 3) {
std::cout << "Invalid entry:\n";
}
} while (choosen_difficulty_ < 1 || choosen_difficulty_ > 3);
answer_ = getWordFromDictionary(choosen_difficulty_, dictionary_);
// clear and resize guessed word to be that of answer_ and add bunch of hypens.
guessed_.clear();
guessed_.resize(answer_.size(), '-');
// also reset the guessed_characters
guessed_characters_ = std::string("\n");
}
bool try_again(int& tries) {
std::cout << "Would you like to try again?\n";
char c;
std::cin >> c;
if (c == 'y' || c == 'Y') {
start_over();
// don't forget to update this so that the loop can repeat
tries = answer_.size() * 2;
return true;
}
else {
std::cout << "Thank you for playing " << title_ << '\n';
return false;
}
}
void test_character(const char c) {
// here is where you would use the standard library for taking the character
// passed into this function, updating the guessed_characters
// get all indexes
std::vector<unsigned> locations;
for (unsigned i = 0; i < answer_.size(); i++)
if (answer_[i] == c)
locations.push_back(i);
// now update the guessed word
if ( locations.size() > 0 )
for (size_t n = 0; n < locations.size(); n++)
guessed_[locations[n]] = c;
}
void update_guessed_characters(const char c) {
guessed_characters_.insert(0, &c); // just push to the front
}
};
If you noticed how I structured the game class above; I am using while and do-while loops in conjunction with for-loops and if-statements and a single boolean flag to determine the state of the game. The game state is also determined from the update to the guessed characters and guessed word. Then I compare that to the answer. Depending on certain conditions the loop will continue seeking input from the user or will exit.
I am not guaranteeing that this code is 100% bug-free for I didn't do any rigorous testing or checking corner cases or special cases but the code has run without error and I've tested all primary game state cases. It appears to be working fine.
I know that there could be many improvements and simplifications made if I had chosen to use some of the standard library functions for working with strings, but I wanted to illustrate the individual steps that are involved in the design or thinking process of making a game with states and their transitions. I could of also put the game class declaration into its own header file with its implementation in a cpp file, but I left that as a single class that is shown in main.cpp for easy copy and paste and compilation.
With this particular game, I did not use a switch and case statements, I just stuck with some while and do-while loops, a few for loops, and if statements since there are only a few game states and transitions to worry about. This implementation also demonstrates the algorithms that are involved and shows how they interconnect with each other. I hope this helps to give you a better understanding of the design process.
When making a game that has different states with a bit of complexity to it, you should start by making your state table first and list all of its transitions before you even write any code. Then you should list your starting, continuing, winning, failing and exiting states or cases. Then you need to draw up how you would transition from one state to another by their required conditions. This will help you in the long run!
Once you have the game state and its transitions laid out properly, then you can start to make your required functions for those states and begin to connect them together. After that is when you would write the internal of the functions or their implementation of what they would do.
Finally, after you have that down is where you want to do some debugging and unit and case testing and if everything appears to be okay, then it would be safe to improve your current algorithms or choosing better ones for peak or most efficient performance.

Boost::Regex Segfault (I think)

I'm having an issue with some C++ code that I'm running. Basically, it works fine with most inputs, but with certain inputs it segfaults after my main function returns. This has been... puzzling. I stopped the run at the segfault to get the stack trace, and it returned this:
#0 malloc_consolidate() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4151
#1 _int_free() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4057
#2 boost::re_detail::mem_block_cache::~mem_block_cache()() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0
#3 __cxa_finalize() at /build/eglibc-oGUzwX/eglibc-2.19/stdlib/cxa_finalize.c:56
#4 ??() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0
#5 ??() at
#6 _dl_fini() at /build/eglibc-oGUzwX/eglibc-2.19/elf/dl-fini.c:252
This made me think that I must be doing something wrong with boost regex, but I can't for the life of me figure it out. The way I'm using regex is that users can input a bunch of strings. Those strings could just be normal text, or they could be regular expressions. Because of this, I basically interact with all the inputs as regular expressions. But what if a user gave a string that was intended as plain text but had a character that could be interpreted differently as a regular expression? What I do is go through all plain text input strings and escape all those characters.
Here's the code that I'm working with. This is my main:
int
main(int argc, char * argv[])
{
// Process input arguments
// The desired input is numVertices (int), graph density (double between 0 and 1), halfLoss (double), total loss (double),
// position expanse (double, m), velocity expanse (double, m/s)
int num_vertices;
double graph_density ;
double half_loss;
double total_loss;
double position_expanse;
double velocity_expanse;
if (argc == 1)
{
num_vertices = 48;
graph_density = 1;
half_loss = 200000;
total_loss = 400000;
position_expanse = 400000;
velocity_expanse = 10000;
}
else
{
if (argc != 7)
{
std::cerr << "Need 6 input arguments" << std::endl;
return 1;
}
std::istringstream ss(argv[1]);
num_vertices;
if (!(ss >> num_vertices))
std::cerr << "First input must be an integer" << std::endl;
graph_density = read_double_input(argv[2]);
half_loss = read_double_input(argv[3]);
total_loss = read_double_input(argv[4]);
position_expanse = read_double_input(argv[5]);
velocity_expanse = read_double_input(argv[6]);
}
// Determine how many edges to create
int num_edges = (int) ( (graph_density * num_vertices * (num_vertices - 1)) + 0.5 );
// Create the edges
int edges_created = 0;
std::set<std::pair<int, int> > edge_set;
while (edge_set.size() < num_edges)
{
// Pick a random start vertex and end vertex
int start_vertex = rand() % num_vertices;
int end_vertex = rand() % num_vertices;
// Make sure the start and end vertices are not equal
while (start_vertex == end_vertex)
{
end_vertex = rand() % num_vertices;
}
// Insert the new edge into our set of edges
edge_set.insert(std::pair<int, int>(start_vertex, end_vertex));
}
// Create connection handler
ConnectionHandler conn_handler;
// Create lists for from and to vertices
std::vector<std::string> from_list;
std::vector<std::string> to_list;
// Add connections to from and to lists
for (std::set<std::pair<int, int> >::const_iterator edge_it = edge_set.begin(), end_it = edge_set.end(); edge_it != end_it; ++edge_it)
{
int start_vertex = edge_it->first;
int end_vertex = edge_it->second;
from_list.push_back("Radio" + int_to_string(start_vertex));
to_list.push_back("Radio" + int_to_string(end_vertex));
}
// Read the list into the connection handler
conn_handler.read_connection_list(true, from_list, to_list);
return 0;
}
This code has this ConnectionHandler object that I created. Here's the header for that:
#ifndef CLCSIM_CONNECTIONHANDLER_HPP_
#define CLCSIM_CONNECTIONHANDLER_HPP_
#include <models/network/NetworkTypes.hpp>
#include <generated/xsd/NetworkModelInterfaceConfig.hpp>
namespace clcsim
{
typedef std::map<std::string, std::set<std::string> > ConnectionFilter;
class ConnectionHandler
{
public:
ConnectionHandler();
~ConnectionHandler();
void read_connection_list(const bool is_white_list, const std::vector<std::string> &from_radios, const std::vector<std::string> &to_radios);
private:
ConnectionFilter filter_;
std::set<std::string> from_list_;
std::set<std::string> to_list_;
bool is_white_list_;
};
} // namespace clcsim
#endif // CLCSIM_CONNECTIONHANDLER_HPP_
And here's the source:
#include <models/network/ConnectionHandler.hpp>
#include <oasis/framework/exceptions/ConfigurationException.h>
#include <boost/regex.hpp>
namespace clcsim
{
ConnectionHandler::
ConnectionHandler()
{
}
ConnectionHandler::
~ConnectionHandler()
{
std::cout << "Destructing conn handler" << std::endl;
}
void
ConnectionHandler::
read_connection_list(
const bool is_white_list,
const std::vector<std::string> &from_radios,
const std::vector<std::string> &to_radios)
{
std::cout << "Reading the connection list" << std::endl;
// Make sure the size of both the input vectors are the same
std::size_t from_radio_size = from_radios.size();
std::size_t to_radio_size = to_radios.size();
if (from_radio_size != to_radio_size)
{
throw ofs::ConfigurationException("Error while initializing the "
"Network model: "
"Connections in from/to lists don't align"
);
}
// Create a regular expression/replacement to find all characters in a non-regular expression
// that would be interpreted as special characters in a regular expression. Replace them with
// escape characters
const boost::regex esc("[.$|()\\[\\]{}*+?\\\\]");
const std::string rep("\\\\&");
// Iterate through the specified connections
for (int i = 0; i < from_radio_size; ++i)
{
std::string from_string = boost::regex_replace(from_radios[i], esc, rep, boost::match_default | boost::format_sed);
std::string to_string = boost::regex_replace(to_radios[i], esc, rep, boost::match_default | boost::format_sed);
//std::cout << "From " << from_string << " to " << to_string << std::endl;
filter_[from_string].insert(to_string);
//filter_[from_radios.at(i)].insert(to_radios.at(i));
}
std::cout << "Got here" << std::endl;
}
} // namespace clcsim
Sorry for so much code.
I saw some similar threads related to segfaults with boost::regex. In those examples, the users had really simple code that just created a regex and matched it and ran into an error. It turned out the issue was related to the Boost versioning. I tried to see if I could replicate those sorts of errors, but those simple examples worked just fine for me. So... I'm pretty stumped. I'd really appreciate any help!
For the sake of removing this from the "Unanswered" list, I'm going to post the answer that was provided in the comments instead of here. The OP determined that the suggestion that Boost linked against eglibc was indeed conflicting with the rest of the code linked against glibc. As such, the OP found that upgrading his OS so that eglibc linked libraries were no longer in use fixed the problem.

C++: Deque Iterator Not Dereferenceable; can't find the rogue pop/top

I'm doing something very similar to what this user did:
Error: deque iterator not dereferenceable
I've been looking for an age but I just cannot see where I'm going wrong. The solution to the other poster was finding a place where he tried to pop or top from a deque with zero elements. I can't find where I'm doing that in my code.
EDIT: I suspect the issue is within SYAlg or OSProcess, if that helps.
// TestCalculator.cpp : main project file.
#include <string>
#include <iostream>
#include <locale>
#include <ctype.h>
#include <vector>
#include <deque>
using namespace System;
using namespace std;
//using std::string;
bool lastCharDigit = true;
string RawString; //Contains the raw equation the user types in.
deque<string> TokenEquation(1); //Contains the equation in tokenised infix form.
deque<string> RPNEquation; //Contains the equation in tokenised RPN form.
deque<string> OperatorStack; //Used as part of the Shunting Yard Algorithm
deque<string> SolverStack; //Used to solve the RPN Equation.
locale loc; //Used to verify digits.
//START FUNCTION DECLARATION
int main();
void tokeniser(string RawEquation);
void SYAlg();
void OSProcess(string newOperator);
void Solver();
//END FUNCTION DECLARATION
int main()
{
cout << "Please enter a valid infix notation equation, without parenthesis.\n";
cin >> RawString;
tokeniser(RawString);
cout << "\n";
system("pause");
return 0;
}
void tokeniser(string RawEquation)
{
int testCharPos = -1; // Initialise the index of the raw string
int tokenVectorPos = 0; // Initialise the token array position
int tokenVectorPrintPos = 0; // Initialise the print position
for (int eLength = RawEquation.length(); eLength != 0; eLength--) // For each character in the Raw string...
{
testCharPos++; // Increment the char we're testing
char testChar = RawEquation.at(testCharPos); // Establish the current test char
if (isdigit(testChar, loc)) //If the testchar is a digit
{
if (lastCharDigit) //If the last character was a digit
{
TokenEquation[tokenVectorPos] += testChar; //Append the tested char to the current token array pos
}
if (!lastCharDigit) //If the last character was not a digit
{
TokenEquation.push_back(string(1, testChar)); //Establish a new element with the testchar in it.
tokenVectorPos++;
}
lastCharDigit = true;
}
if (!isdigit(testChar, loc))//If the testchar is not a digit
{
TokenEquation.push_back(string(1, testChar)); //Establish a new element with the testchar in it.
tokenVectorPos++;
lastCharDigit = false;
}
}
cout << "The tokens of that equation are:\n\n"; //Outputs the tokens for testing purposes.
for (int tokenLength = TokenEquation.size(); tokenLength != 0; tokenLength--)
{
cout << " " << TokenEquation[tokenVectorPrintPos];
cout << "\n";
tokenVectorPrintPos++;
}
SYAlg(); //Call the SYAlg.
}
void SYAlg() //This function uses Shunting Yard Algorithm to convert the Infix tokens to RPN.
{
cout << TokenEquation.size();
for (int testtokenLength = TokenEquation.size(); testtokenLength != 0; testtokenLength--) //For each token in the tokenised deque
{
if (isdigit(TokenEquation.front().at(0), loc)) //Check if it's a number
{
RPNEquation.push_back(TokenEquation.front()); //Add the first raw token to the RPN Equation
TokenEquation.pop_front(); //Pop the token from the deque
}
if (!isdigit(TokenEquation.front().at(0), loc)) //If it's an operator
{
OSProcess(TokenEquation.front()); //Run the SYAlg operator stack procedure. NB This will pop the front of the TokenEquation for you.
}
}
cout << "The tokens of that equation are:\n\n"; //Outputs the tokens for testing purposes.
int RPNPrintPos = 0;
for (int tokenLength = RPNEquation.size(); tokenLength != 0; tokenLength--)
{
cout << " " << RPNEquation[RPNPrintPos];
cout << "\n";
RPNPrintPos++;
}
}
void OSProcess(string newOperator) //This function processes the Operator Stack
{
bool PushedNewOperator = false;
std::string newOpSTD = newOperator; //Creates an std::string version of the argument for easier comparison.
while (PushedNewOperator == false){ //As long as the new operator is still waiting to go to the stack
if (!OperatorStack.empty()) //If there's already an operator on the stack
{
if (newOpSTD == "/" || "*")
{
std::string OSBackSTD = OperatorStack.back(); //Create an STD version of the back of the OpStack for comparison.
if (OSBackSTD == "+" || "-")
{
OperatorStack.push_back(newOperator); //Add the tested operator to the stack
TokenEquation.pop_front(); //And pop it from the token equation
PushedNewOperator = true; //Set the flag variable to true so we stop looping
}
else
{
RPNEquation.push_back(OperatorStack.back()); //Add the top of the operator stack to the equation
OperatorStack.pop_back(); //Pop this back
}
}
else
{
RPNEquation.push_back(OperatorStack.back()); //Add the top of the operator stack to the equation
OperatorStack.pop_back(); //Pop this back
}
}
if (OperatorStack.empty())
{
OperatorStack.push_back(newOperator); //Add the tested operator to the stack
TokenEquation.pop_front(); //And pop it from the token equation
PushedNewOperator = true; //Set the flag variable to true so we stop looping
}
}
//For each operator on the stack, until the following statement returns false...
//Check if the precedence of newOperator is less than or equal to the top operator.
}
void Solver() //This function solves the RPNEquation
{
//Push each token to the solver stack
//If you push an operator, solve it against the stack
//When the RPN equation is empty and the solver stack only has one token in it, you have a solution
}
One major issue is with the multitude of lines which say if (newOpSTD == "/" || "*"), or something to that effect. These need to be changed to if (newOpSTD.compare("/") == 0 || newOpSTD.compare("*") == 0).
I think these checks failing means the while loop they're in turns into while(true).

How can I trace back the error

I was assigned to create an array check (to see if the array is increasing, decreasing, or neither [then exiting if neither]) and a recursive binary search for one of my assignments. I was able to do these things after some help from my peers, but I need help in finding what seems to be causing the error
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Aborted
when running the code. I Googled this error and this error seems to be vague or I just am not understanding. It compiles without errors, but I need help in what finding what I did wrong. It is able to run without the binarySearchR function and its associating code, as the array check on its own was the previous assignment. Below is the code, and I thank you so much in advance!
#include <iosteam>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
int checkArraySort (string *fileLines, int numberOfLines);
int binarySearchR (string *fileLines, string searchKey, int iMin, int iMax);
int main ()
{
int numberOfLines = 0;
string searchKey = 0;
cout << "Input search key: ";
cin >> searchKey;
ifstream fileIn;
fileIn.open("words_in.txt");
string line;
if (fileIn.eof()) /* Checks file to see if it is blank before proceeding */
{
exit (EXIT_SUCCESS);
}
else
{
while(!(fileIn.eof()))
{
fileIn >> line;
numberOfLines++;
}
fileIn.close(); /* closes fileIn, need to reopen to reset the line location */
fileIn.open("words_in.txt");
string *fileInLines;
fileInLines = new string[numberOfLines];
for (int i = 0; i < numberOfLines; i++)
{
fileIn >> line;
fileInLines[i] = line;
}
fileIn.close(); /* closes fileIn */
int resultingCheck = checkArraySort(fileInLines, numberOfLines);
if (resultingCheck == -1)
{
cout << "The array is sorted in descending order." << endl;
}
else if (resultingCheck == 1)
{
cout << "The array is sorted in ascending order." << endl;
}
else
{
cerr << "ERROR: Array not sorted!" << endl;
exit (EXIT_FAILURE);
}
int searchResult = binarySearchR (fileInLines, searchKey, 0, numberOfLines);
if (!searchResult == -1)
{
cout << "Key found at index " << searchResult << "." << endl;
}
else
{
cout << "Key not found at any index." << endl;
}
exit (EXIT_SUCCESS);
}
}
int checkArraySort (string *fileLines, int numberOfLines)
{
int result = 1; /* Ascending by default */
for (int i = 1; i < numberOfLines; i++) /* Checks if decending */
{
if (fileLines[i] < fileLines[i-1])
{
result = -1;
}
}
if (result == -1) /* Makes sure it is descending (or if it is neither) */
{
for (int i = 1; i < numberOfLines; i++)
{
if (fileLines[i] > fileLines[i-1])
{
result = 0;
}
}
}
return result;
}
int binarySearchR (string *fileLines, string searchKey, int iMin, int iMax)
{
// so, its gotta look at the center value and each times, it discards half of the remaining list.
if (iMax < iMin) /* If the minimum is greater than the maximum */
{
return -1;
}
else
{
int iMid = (iMin + iMax) / 2;
if (fileLines[iMid] > searchKey) /* If the key is in the lower subset */
{
return binarySearchR (fileLines, searchKey, iMin, iMid - 1);
}
else if (fileLines[iMid] < searchKey) /*If the key is in the upper subset */
{
return binarySearchR (fileLines, searchKey, iMin, iMid + 1);
}
else /*If anything else besides the two */
{
return iMid;
}
}
}
The easy way: add a bunch of cout s to see where you program goes and what the values are.
Pros
Easy to do
Cons
Requires a recompile each time you want to add more info
The hard way: Learn to use a debugger
Pros
Can inspect "on the fly"
Don't need to rebuild
Can use what you learn in every other C++ program
Cons
Requires a bit of research to learn how to do it.