I have the next function and i want to print some parameters separated by a comma, my problem is that the console didn't show anything when "parametro[i] = linea[i]" in the FOR iteration.
Example:
Parametro 1: []
void funcionSeparadora (string linea){
int numParametros = 1;
string parametro;
for (int unsigned i=0;i<linea.length();i++){
if (linea[i] == ','){
cout <<"Parámetro "<<numParametros<<": "<<"["<< parametro <<"]"<< '\n';
numParametros++;
}
else (parametro[i] = linea[i]);
}
}
Mostly the way you handle the filling of parametro was wrong. Fixed version:
void funcionSeparadora(string linea) {
int numParametros = 1;
string parametro;
for (int unsigned i = 0; i<linea.length(); i++) {
if (linea[i] == ',') {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << '\n';
numParametros++;
parametro.clear();
}
else {
parametro += linea[i];
}
}
if (!parametro.empty()) {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << '\n';
}
}
Points you missed
Use curly brackets in else condition
Use size_t instead of unsigned in in for loop
initialize the parametro variable with necessary length
Try this
#include <iostream>
#include <string>
using namespace std;
void funcionSeparadora(string linea) {
int numParametros = 1;
string parametro(linea.length(),' ');
for (size_t i = 0; i < linea.length(); i++) {
if (linea[i] == ',') {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << endl;
numParametros++;
}
else {
parametro[i] = linea[i];
}
}
}
int main()
{
funcionSeparadora("what is this,");
system("pause");
return 0;
}
Related
I have been struggling with comparing two strings which I read from files, "one" & "two" both have the same words (e.g. salt) but it doesn't return "Equal". I have also used == but it made no difference.
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
int main (){
string en[100];
string line;
int i=0;
ifstream fileEn ("hey.txt");
if (fileEn.is_open()){
while (!fileEn.eof()){
getline(fileEn,line);
en[i]=line;
i++;
}
}
fileEn.close();
string fa[100];
string line1;
i=0;
ifstream fileFa ("hey1.txt");
if (fileFa.is_open()){
while (!fileFa.eof()){
getline(fileFa,line1);
fa[i]=line1;
i++;
}
}
fileFa.close();
ifstream Matn("matn.txt");
string matn[100];
if(Matn.is_open()){
for(int i = 0; i < 100; ++i){
Matn >> matn[i];
}
}
Matn.close();
string one = en[0];
string two = matn[0];
cout << one << " " << two;
if(one.compare(two) == 0){
cout << "Equal";
}
}
I suggest adding some debugging output to your program:
while (!fileEn.eof()){
getline(fileEn,line);
// Debugging output
std::cout << "en[" << i << "] = '" << line << "'" << std::endl;
en[i]=line;
i++;
}
and
for(int i = 0; i < 100; ++i){
Matn >> matn[i];
// Debugging output
std::cout << "matn[" << i << "] = '" << matn[i] << "'" << std::endl;
}
Hopefully you can see what the problem is by looking at the output.
In addition, please note that use of while (!fileEn.eof()){ ... } is not correct. See Why is iostream::eof inside a loop condition considered wrong?.
I suggest changing that loop to:
while (getline(fileEn,line)) {
// Debugging output
std::cout << "en[" << i << "] = '" << line << "'" << std::endl;
en[i]=line;
i++;
}
Similarly, don't assume that Matn >> matn[i] is successful. I suggest changing that loop to:
for(int i = 0; i < 100; ++i) {
std::string s;
if ( !(Matn >> s) )
{
// Read was not successful. Stop the loop.
break;
}
matn[i] = s;
// Debugging output
std::cout << "matn[" << i << "] = '" << matn[i] << "'" << std::endl;
}
I am writing the code which counts the lines in the document and split it into equal pats if the line more than 100. To split I am using string.substr(i, i+adding+ addCount). If i have to slit in three parts: First and third split part is OK, Second part has not only its part but also third part words in it. It looks something like this:
linesize: 331
divider3
0 Output I 110
1 EXPRESSION: Mrs. Bennet and her daughters then departed, and Elizabeth returned instantly to Jane, leaving her own and her
0 I
110I 110 0
was here OST
110 Output I 220
2 (error) EXPRESSION: relations’ behaviour to the remarks of the two ladies and Mr. Darcy; the latter of whom, however, could not be prevailed on to join in their censure of her, in spite of all Miss Bingley’s witticisms on fine eyes
110 I
220I 110 0
was here OST
220 Output I 416
3 EXPRESSION: be prevailed on to join in their censure of her, in spite of all Miss Bingley’s witticisms on fine eyes.
220 I
416I 110 86
was here OST
#include <iostream>
#include <deque>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <future>
#include <map>
#include <fstream>
#include <vector>
using namespace std;
atomic<bool> isReady{false};
mutex mtx;
condition_variable condvar;
map<string, int> mapper;
string line;
vector<string> block;
size_t line_index = 0;
int block_size = 100;
int limit_chars = 100;
int c = 0;
deque<vector<string>> dq;
void Producer() {
std::cout << " Producer " << std::endl;
fstream fl("/home/ostap/CLionProjects/WordsCount2/file.txt"); //full path to the file
if (!fl.is_open()) {
cout << "error reading from file" << endl;
}
else {
cout << "SUCCESS!!!" << endl;
while (getline(fl, line) && line_index < block_size) {
if (line.find_first_not_of(' ') != string::npos) { // Checks whether it is a non-space.
// There's a non-space.
cout<< "linesize: " << line.length() << endl;
if (line.length() / limit_chars > 1.4) {
int divider = (int) (line.length() / limit_chars);
int adding = (int) line.length()/divider;
//попробуй поміняти на while все через addCount
int addCount = 0;
int i = 0;
cout <<"divider" << divider<<endl;
while ( i < line.length()){
while (line[i + adding + addCount] != ' ') {addCount+=1;}
cout << i << " Output I " << i + adding + addCount << endl;
cout << "EXPRESSION: " << line.substr(i, i + adding + addCount) << endl; //to del
block.push_back(line.substr(i, i + adding + addCount));
cout << i << " I" << endl;
i = i + adding + addCount;
cout << i << "I" <<" " <<adding <<" "<< addCount <<endl;
++line_index;
addCount = 0;
cout << "was here OST" << endl;
}
}
else {
++line_index;;
block.push_back(line);
cout << "Line: " << line << endl;
}
if (line_index >= block_size) {
c++;
cout << c << endl;
{
lock_guard<mutex> guard(mtx);
//cout << "Producing message: " << x << " th" << endl;
dq.push_back(block);
}
line_index = 0;
block.clear();
}
condvar.notify_one();
}
cout << "Producer completed" << endl;
isReady = true;
// for (unsigned i = 0; i < block.size(); ++i) cout << ' ' << block[i];
// cout << '\n';
//this_thread::sleep_for(chrono::seconds(1));
}
}
}
void Consumer() {
while (true) {
unique_lock<mutex> lk(mtx);
if (!dq.empty()) {
vector<string> & i = dq.front();
dq.pop_front();
lk.unlock();
cout << "Consuming: " << i.data() << " th" << endl;
} else {
if(isReady){
break;
}
else {
condvar.wait(lk);
cout << "There are no messages remained from producer" << endl;
}
}
cout << "\nConsumer is done" << endl;
}
}
int main() {
//cout << "Hello, World!" << endl;
auto t1 = async(launch::async, Producer);
auto t2 = async(launch::async, Consumer);
//auto t3 = async(launch::async, Consumer);
t1.get();
t2.get();
//t3.get();
return -1;
I am implementing class of wizards in this code but I have a serious problem with finding relation in wizards family tree. I am using a back tracking method to find all relation between two nodes but memory will start to being messed up in the middle of the task and I have no idea what should I do.
Here you can see implementation of this class using C++.
#include "Wizard.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
Wizard::Wizard(string first_name, string surname, string occupation, string organization, string wand)
: first_name(first_name),surname(surname), occupation(occupation), organization(organization), wand(wand)
{
this->married=0;
this->wand="Dragon Hearstring";
this->occupation="Auror";
this->organization="Dumbledore Army";
};
void Wizard::set_first_name(string _name){
this->first_name = _name;
}
void Wizard::set_surname(string _surname){
this->surname = _surname;
}
void Wizard::set_occupation(string _occupation){
this->occupation = _occupation;
}
void Wizard::set_organization(string _organization){
this->organization = _organization;
}
void Wizard::set_wand(string _wand){
this->wand = _wand;
}
string Wizard::get_name(){
string name;
name = first_name + " " + surname;
return name;
}
string Wizard::get_occupation(){
return occupation;
}
string Wizard::get_organization(){
return organization;
}
string Wizard::get_wand(){
return wand;
}
void Wizard::print_parents(){
cerr << "Parents: ";
for (int i=0; i<parents.size(); i++){
cout << parents[i]->get_name();
if ( i!= parents.size() -1){
cout << " & ";
}
}
cout << endl;
}
void Wizard::print_siblings(){
cerr <<"Siblings: ";
for (int i=0; i<siblings.size(); i++){
cout << siblings[i]->get_name();
if ( i < siblings.size() -1){
cout << " & ";
}
}
cout << endl;
}
void Wizard::print_spouse(){
cerr <<"Spouse: ";
if (married==1)
cout << spouse->get_name();
cout << endl;
}
void Wizard::print_children(){
cerr <<"Children: ";
for (int i=0; i<children.size(); i++){
cout << children[i]->get_name();
if ( i < children.size() - 1){
cout << " & ";
}
}
cout << endl;
}
void Wizard::operator*(Wizard& _spouse){
this->married=1;
_spouse.married=1;
cout << this->get_name() << " and " << _spouse.get_name() << endl;
this->spouse = &_spouse;
_spouse.spouse = this;
_spouse.print_spouse();
vector< Wizard* > these_two;
these_two.push_back(this);
these_two.push_back(&_spouse);
for (int i=0; i<this->children.size(); i++)
children[i]->parents = these_two;
for (int i=0; i<_spouse.children.size(); i++)
children[i]->parents = these_two;
}
void Wizard::operator+(Wizard& _child){
if (!search_in_vector(this->children,&_child))
this->children.push_back(&_child);
if (!search_in_vector(this->spouse->children,&_child))
this->spouse->children.push_back(&_child);
vector< Wizard* > these_two;
these_two.push_back(this);
these_two.push_back(this->spouse);
_child.parents=these_two;
_child.surname = this->surname;
for (int i=0; i<this->children.size(); i++){
if(!search_in_vector(_child.siblings,children[i]) && (children[i]!=&_child)){
_child.siblings.push_back(children[i]);
children[i]->siblings.push_back(&_child);
}
}
}
void Wizard::print_relation_with(Wizard& john_doe){
vector<string> path2;
vector< vector< string > > path1;
vector<Wizard*> nodes_in_the_way;
nodes_in_the_way.push_back(this);
if (this->get_name() == john_doe.get_name()){
cout << this->get_name() << " is " << john_doe.get_name() << endl;
return;
}
this- >search_for_relation(*this,john_doe,path1,path2,nodes_in_the_way);
if (path1.size() == 0){
cout << "no relation" << endl;
return;
}
path2=path1[0];
for (int i=1;i<path1.size();i++){
if (path1[i].size() < path2.size())
path2=path1[i];
}
cout << this->get_name() << " is ";
for (int i=0; i<path2.size(); i++)
cout << path2[i] << " of ";
cout << john_doe.get_name() << endl;
}
void Wizard::search_for_relation(Wizard& a,Wizard& b,vector< vector<string> > &path1,vector<string> &path2,vector< Wizard* > &nodes_in_the_way){
cerr << "////////////" << endl;
cerr << "IM INSIDE " << a.get_name() << " , SEARCHING FOR " << b.get_name() << " - " << path2.size() << endl;
cout << "PATH: ";
for (int i=0;i<nodes_in_the_way.size();i++)
cout << nodes_in_the_way[i]->get_name() << " ";
cout << endl;
a.print_spouse();
a.print_children();
a.print_parents();
if (a.get_name() == b.get_name() && path2.size()==0){
return;
}
if (a.get_name() == b.get_name() ){
path1.push_back(path2);
return;
}
if (a.married){
if (!search_in_vector(nodes_in_the_way,a.spouse)){
path2.push_back("spouse");
nodes_in_the_way.push_back(a.spouse);
search_for_relation(* (a.spouse),b,path1,path2,nodes_in_the_way);
path2.pop_back();
nodes_in_the_way.pop_back();
}
}
// parents
for (int i=0;i<a.parents.size();i++){
if (!search_in_vector(nodes_in_the_way,a.parents[i])){
path2.push_back("child");
nodes_in_the_way.push_back(a.parents[i]);
search_for_relation(* (a.parents[i]),b,path1,path2,nodes_in_the_way);
path2.pop_back();
nodes_in_the_way.pop_back();
}
}
// children
for (int i=0;i<a.children.size();i++){
if (!search_in_vector(nodes_in_the_way,a.children[i])){
path2.push_back("parent");
nodes_in_the_way.push_back(a.children[i]);
search_for_relation(* (a.children[i]),b,path1,path2,nodes_in_the_way);
path2.pop_back();
nodes_in_the_way.pop_back();
}
}
}
///////////// NON-METHOD FUNCITONS ///////////////
bool search_in_vector(vector< Wizard* > a,Wizard* b){
for (int i=0; i<a.size(); i++)
if (a[i]->get_name() == b->get_name())
return true;
return false;
}
So that was the code.
Here you can see the output after some back_tracking:
Here you see that Harry's information has been messed up during last recursion and the executable file can't print his parents.
Please let me know that I'm doing wrong! Thanks!
The issue that I am having is that with the code below, each plOvr for all of the class objects is the same. This causes them to have the same stats for everything. Also, I have an array with names that should be printed but it is skipping the first value.
using namespace std;
class Player
{
public:
int plOvr;
float plSpg, plSps;
string werk;
void setPlayeName(string);
string plName;
void setPlyrVal()
{
srand (time(NULL));
plOvr = rand()% 29 + 70;
plSps = plOvr / 10;
plSpg = plSps / 2;
}
};
void Player::setPlayeName(string werk)
{
plName = werk;
}
int main()
{
Player plyr1,plyr2,plyr3,plyr4,plyr5;
string firstTime;
string name[5] = {"Eric Gelinas","John Merill", "Jaromir Jagr", "Travis Zajac","Reid Boucher"};
bool firstOp;
cout << "Is this the first time this program has run?" << endl;
cin >> firstTime;
if (firstTime == "Yes" || firstTime == "yes")
{
firstOp == firstOp;
plyr1.setPlyrVal();
plyr1.setPlayeName(name[1]);
plyr2.setPlyrVal();
plyr2.setPlayeName(name[2]);
plyr3.setPlyrVal();
plyr3.setPlayeName(name[3]);
plyr4.setPlyrVal();
plyr4.setPlayeName(name[4]);
plyr5.setPlyrVal();
plyr5.setPlayeName(name[5]);
ofstream playerSaveData;
playerSaveData.open ("savedata.txt");
playerSaveData << plyr1.plName << "," << plyr1.plOvr << "," << plyr1.plSpg << "," << plyr1.plSps << "\n";
playerSaveData << plyr2.plName << "," << plyr2.plOvr << "," << plyr2.plSpg << "," << plyr2.plSps << "\n";
playerSaveData << plyr3.plName << "," << plyr3.plOvr << "," << plyr3.plSpg << "," << plyr3.plSps << "\n";
playerSaveData << plyr4.plName << "," << plyr4.plOvr << "," << plyr4.plSpg << "," << plyr4.plSps << "\n";
playerSaveData << plyr5.plName << "," << plyr5.plOvr << "," << plyr5.plSpg << "," << plyr5.plSps << "\n";
playerSaveData.close();
cout << "done.\n";
}
else
{
firstOp == !firstOp;
}
return 0;
}
You may use std::uniform_int_distribution<int> and an engine as std::mt19937 from <random>.
The engine (as srand) has to be initialized with seed only once.
Your program rewritten:
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
#include <random>
class Player
{
public:
void setPlayeName(const std::string& name) { plName = name; }
void setPlyrVal(std::mt19937& rand_engine)
{
std::uniform_int_distribution<int> distr(70, 98);
plOvr = distr(rand_engine);
plSps = plOvr / 10;
plSpg = plSps / 2;
}
public:
int plOvr;
float plSpg, plSps;
std::string werk;
std::string plName;
};
int main()
{
std::mt19937 rand_engine(time(nullptr));
Player plyrs[5];
const std::string names[5] = {"Eric Gelinas","John Merill", "Jaromir Jagr", "Travis Zajac","Reid Boucher"};
std::cout << "Is this the first time this program has run?" << std::endl;
std::string firstTime;
std::cin >> firstTime;
if (firstTime == "Yes" || firstTime == "yes") {
for (int i = 0; i != 5; ++i) {
plyrs[i].setPlyrVal(rand_engine);
plyrs[i].setPlayeName(names[i]);
}
std::ofstream playerSaveData;
playerSaveData.open ("savedata.txt");
for (const auto& plyr : plyrs) {
playerSaveData << plyr.plName << "," << plyr.plOvr << "," << plyr.plSpg << "," << plyr.plSps << "\n";
}
std::cout << "done." << std::endl;
}
return 0;
}
Live example
You should call srand() only once in the whole program, instead of calling it before each rand().
I was trying to count the number of characters in a string class but for some reason the program is skipping over my function completely. This is just the test code from the main program, it still was giving me the same results. How come the counter function is skipped over?
#include <iostream>
#include <string>
using namespace std;
void prompt(string& dna)
{
cout << "Input: ";
getline(cin, dna);
}
void counter(const string DNA,
int* a_count, int* t_count, int* c_count, int* g_count)
{
for (int i = 0; i < DNA.size(); i++)
{
if (DNA.at(i) == 'a')
{
*a_count++;
}
else if (DNA.at(i) == 't')
{
*t_count++;
}
else if (DNA.at(i) == 'c')
{
*c_count++;
}
else if (DNA.at(i) == 'g')
{
*g_count++;
}
}
}
int main()
{
string dna;
int a = 0;
int t = 0;
int c = 0;
int g = 0;
prompt(dna);
if (! dna.empty())
{
cout << "Before:\n"
<< "A: " << a << endl
<< "T: " << t << endl
<< "C: " << c << endl
<< "G: " << g << endl;
counter(dna, &a, &t, &c, &g);
cout << "\n\nAfter:\n"
<< "A: " << a << endl
<< "T: " << t << endl
<< "C: " << c << endl
<< "G: " << g << endl;
}
system("pause");
return 0;
}
You're applying operator ++ the wrong way. It should be:
if (DNA.at(i) == 'a')
{
(*a_count)++;
}
else if (DNA.at(i) == 't')
{
(*t_count)++;
}
else if (DNA.at(i) == 'c')
{
(*c_count)++;
}
else if (DNA.at(i) == 'g')
{
(*g_count)++;
}
You've got a priority problem between the ++ and * operators. You are incrementing the pointer address, not the value. (*a_count)++; would be correct.
You may find it easier to use reference parameters for the counts instead, since you don't actually need to do any pointer arithetic. ie:
void counter(const string DNA, int& a_count, int& t_count, int& c_count, int& g_count)
And, yes a switch statement would be neater.