It's a bit weird to me that the code after a for loop doesn't execute but the compiler doesn't raise any warning:
#include <iostream>
#include <iterator>
bool isVowel(char ch)
{
char vowels[]{"aeiouAEIOU"};
char *p = std::find(std::begin(vowels), std::end(vowels), ch);
if (p != std::end(vowels))
{
std::cout << ch << " is a vowel" << '\n';
return true;
}
else
{
std::cout << ch << " is not a vowel" << '\n';
return false;
}
}
int main()
{
char name[]{"MollieU"};
int numVowels{0};
std::cout << name << '\n';
int length{std::size(name)};
for (char* ptr{name}; ptr < (name + length); ++ptr)
{
if (isVowel(*ptr))
++numVowels;
}
std::cout << name << " has " << numVowels << " vowels." << '\n';
return 0;
}
It has outputs like:
MollieU
M is not a vowel
o is a vowel
l is not a vowel
l is not a vowel
i is a vowel
e is a vowel
U is a vowel
But std::cout << name << " has " << numVowels << " vowels." << '\n'; is never run. Whatever code I put after the loop is never run. I am not sure if return 0 is run or not, but the file is compiled successfully. I am using g++ -std=c++2a on osx.
Try to use the following:
int length { std::size(name) - 1 };
Related
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 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;
}
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.
I have again a strage C++ thing on the following:
l is an incomming line (string.c_str()) > becomes line
pos is the position from where to start searching
s is a string (string.c_str()) to look for > becomes command
It all works fine until command is "-1". In this case the string "-1" is not found although line is containing it.
Am I missing something ovious?
Code:
bool Converter::commandAvailable(const char* l, int pos, const char* s) {
string line = l;
string command = s;
int x = line.find(command, pos);
if (x != -1) {
return true;
}
return false;
}
Thanks in advance!
This should help you find the problem:
bool Converter::commandAvailable(const char* l, int pos, const char* s)
{
string line = l;
string command = s;
std::cout << "INPUT" << std::endl;
std::cout << "LINE: " << line << std::endl;
std::cout << "CMD: " << command << std::endl;
std::cout << "START: " << pos << std::endl << std::endl;
std::size_t x = line.find(command, pos);
std::cout << "OUTPUT: " << x << std::endl;
if (x != std::string::npos)
{
return true;
}
return false;
}