simple game, while loop and checking strings - c++

I am a beginner at c++ and I want to create simple game. You have vector of strings, then you check if line input matched the right answer.
I want to generate random number 1 ,2 or 3. Then check if line matches correct answer and count the points.
I am probably missing something basic, yet I dont know what.
Problems:
Input line get correctly read on only first iterations
somehow points (tocke) jumps to 45763 after finishing.
At beginning time (cas) is sometimes 2.
Code:
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <string>
int main() {
int runde;
int tocke;
int cas;
std::cout << "\n" << "Pravila igre:" << "\n" << "Za pravilen odgovor dobis 1 tocko, za napacnega zgubis 2!"<<
"\n" << "Stevilo zivljenj si izberes sama!"<< "\n" << "\n" ;
std::cout << "Izberi stevilo zivljenj!:" << "\n";
std::cin >> runde ;
std::vector<std::string> latin = {"carum carvi", "artemisia absiinthium","coriandrum sativum"};
std::vector<std::string> slovene = {"navadna kumina", "pravi pelin", "koriander"};
tocke << 0;
cas << 0;
do {
int ind;
cas << cas + 1;
std::cout << "Round " << cas <<"! Ladies and gentlemans, buckle your seatbelts!"<<"\n" << "\n" ;
ind = std::rand() % 3;
std::cout << "ime rastline: " << slovene[ind] << "\n";
std::cin.ignore();
std::string line;
getline(std::cin, line);
std::cout << "\n";
if (latin[ind] == line){
std::cout << "Pravlino! Tocka zate!" << "\n";
tocke << tocke + 1;
std::cout << "Tocke == " << tocke << "\n" << "Zivjenja == " << runde << "\n" << "Prezivete runde == " << cas << "\n"<< "\n";
}
else
{
std::cout << "Napaka! :D" << "\n";
std::cout << "Pravilen odgovor == " << latin[ind] << "\n";
-- runde ;
tocke << tocke - 2;
std::cout << "Tocke == " << tocke << "\n" << "Zivjenja == " << runde << "\n" << "Prezivete runde == " << cas << "\n"<< "\n";
}
}while(runde >= 0 );
std::cout << "\n"<<"Stevilo tock == " << tocke <<"\n" << "St. prezivetih rund == " << cas - 1
<< "\n" ;
}

You seem to have a misconception regarding operators. << is NOT assignment, use = instead. So tocke << 0; doesn't assign 0 to tocke, it does bitshifting (on an uninitialized variable), then discards the result. tocke stays uninitialized and this causes problems later.
Instead of this:
tocke << 0;
cas << 0;
Do this:
tocke = 0;
cas = 0;
Also instead of cas << cas + 1; do cas++ and instead of tocke << tocke - 2; do tocke -= 2;. To learn how the assignment operators work, you can read about them here. Last but not least, try to see if your compiler gives you any warnings, it should complain about using uninitialized values.

Related

Input File Reading Just Repeats First Data Line from 1 of 2 Files

I'm working on a project. The idea is that it has two input files, we'll call them TimeFile and FullFile.
TimeFile gives two timestamps in the format:
DD-MM-YY HH:MM:SS DD-MM-YY HH:MM:SS
And FullFile is in the format of a timestamp and some data:
YYYY-MM-DD HH:MM:SS Value Error Error
The idea is that the program reads the timestamps from TimeFile, then goes through all the lines in FullFile, and if it finds a timestamp from FullFile that lands between two from TimeFile, it copies the whole line into a new smaller data file. In essence, I want to go from one gigantic data file to a bunch of smaller data files divided up by time intervals.
Needless to say, it doesn't work. It does most of what I want, but the resulting smaller data files are always empty.
The strange part is why. It appears to read the timestamps from TimeFile just fine, but it screws up reading from FullFile and just reads the first line over and over again. I don't really have a solid idea why either, best I can determine is that they're reading the same way, but one works and the other doesn't.
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <complex>
#include <stdint.h>
#include <time.h>
#include <string.h>
int main(){
//Read Run-Times-File - Cycle 1
std::ifstream TimeFile;
TimeFile.open("jet_run_times.dat");
if(!TimeFile.good()){
std::cout << "TimeFile Didn't Work" << std::endl;
return 1;
}
//Read Full-File - Cycle 2
std::ifstream FullFile;
FullFile.open("jet_full.txt");
if(!FullFile.good()){
std::cout << "FullFile Didn't Work" << std::endl;
return 1;
}
std::cout << "Both Files Worked" << std::endl;
std::ofstream results;
//Initial Time - A ; Final Time - B ; Jet Pressure Time - C
int iday, ihour, imin, isec, fday, fhour, fmin, fsec, imon, fmon;
char dash, colon ;
std::string imonth, fmonth ;
//std::ostringstream temp;
int run = 0;
int year, month, day , hour, min;
double sec, value, neg, pos, AfterStart, BeforeEnd;
for(int i = 0 ; i < 192 ; i++) {
//Cycle 1
//Write jet_run_XXX.txt
run++;
std::ostringstream temp;
if(run <= 9) temp << "jet_run_00" << run << ".txt" ;
if( (run >= 10) && (run <= 99) ) temp << "jet_run_0" << run << ".txt" ;
if(run >= 100) temp << "jet_run_" << run << ".txt" ;
results.open(temp.str());
std::cout << temp.str() << " File Made" << std::endl;
TimeFile >> iday >> dash >> imonth >> ihour >> colon >> imin >> colon >> isec >> fday >> dash >> fmonth >> fhour >> colon >> fmin >> colon >> fsec;
/*
std::cout << "iday " << iday << std::endl;
std::cout << "dash " << dash << std::endl;
std::cout << "imonth " << imonth << std::endl;
std::cout << "ihour " << ihour << std::endl;
std::cout << "colon " << colon << std::endl;
std::cout << "imin " << imin << std::endl;
std::cout << "isec " << isec << std::endl;
std::cout << "fday " << fday << std::endl;
std::cout << "dash " << dash << std::endl;
std::cout << "fmonth " << fmonth << std::endl;
std::cout << "fhour " << fhour << std::endl;
std::cout << "colon " << colon << std::endl;
std::cout << "fmin " << fmin << std::endl;
std::cout << "fsec " << fsec << std::endl;
*/
if( imonth == "Apr-22") imon = 4;
if( fmonth == "Apr-22") fmon = 4;
if( imonth == "May-22") imon = 5;
if( fmonth == "May-22") fmon = 5;
/*
std::cout << "imon " << imon << std::endl;
std::cout << "fmon " << fmon << std::endl;
*/
//Cycle 2
for(int j = 0 ; j < 5833 ; j++){
FullFile >> year >> dash >> month >> dash >> day >> hour >> colon >> min >> colon >> sec >> value >> neg >> pos;
std::cout << j << std::endl;
/*
std::cout << "year " << year << std::endl;
std::cout << "dash " << dash << std::endl;
std::cout << "month " << month << std::endl;
std::cout << "dash " << dash << std::endl;
std::cout << "day " << day << std::endl;
std::cout << "hour " << hour << std::endl;
std::cout << "colon " << colon << std::endl;
std::cout << "min " << min << std::endl;
std::cout << "sec " << sec << std::endl;
std::cout << "value " << value << std::endl;
std::cout << "neg " << neg << std::endl;
std::cout << "pos " << pos << std::endl;
*/
//Set-Up the Check if A <= C <= B
AfterStart = (sec - isec) + (min - imin)*100 + (hour - ihour)*10000 + (day - iday)*1000000 + (month - imon)*100000000;
BeforeEnd = (fsec - sec) + (fmin - min)*100 + (fhour - hour)*10000 + (fday - day)*1000000 + (fmon - month)*100000000;
std::cout << "AfterStart " << AfterStart << std::endl;
std::cout << "BeforeEnd " << BeforeEnd << std::endl;
//If A <= C <= B, copy all of C to jet_run_XXX.txt
if ( (AfterStart >= 0.0) && (BeforeEnd >= 0.0) ){
results << year << dash << month << dash << day << " " << hour << colon << min << colon << sec << " " << value << " " << pos << " " << neg << '\n' << std::endl;
std::cout << "Got One!" << std::endl;
}
}
//End Cycle 2
results.close();
}
//End Cycle 1
return 0;
}
I'm stumped, any help would be appreciated.
Edit: Thinking it might help if I give a few lines of each of my data files to see if it's a formatting issue, so here's the first 3 lines of each:
TimeFile
03-Apr-22 22:42:19 03-Apr-22 22:56:13
03-Apr-22 22:58:25 03-Apr-22 23:15:14
03-Apr-22 23:17:23 03-Apr-22 23:35:32
FullFile
2022-04-13 12:39:37.500000000 70.00000 0.0 0.0
2022-04-13 12:43:52.500000000 70.00000 0.0 0.0
2022-04-13 12:48:07.500000000 70.00000 0.0 0.0
Edit2:- Important discovery. Running this code with that block uncommented out reproduces the data in the line but instead of 70 0 0 you get 1 0 43.1495 for the last three values. GetLine doesn't seem to do this but I'm having trouble understanding how to cut that open.
Not entirely sure what this means beyond that somehow that's not reading those values properly but when I try to account for a tab it's not an improvement.

How can I remove values from output statement given a condition? - c++

I'm a little confused as to how to go around this. I have some array variables with some information, and I want to print them out after some calculations. If the value is 0, then I want to print a " " instead. There are 3 arrays that need to get checked however, how would I change the output statement to cater for all 3 checks and print an empty string instead of the value?
for(int start = 1; start < 13; start++)
{
if(check[start] == 1)
{
cout << checkMonth(start) << ": " << setprecision(1) << fixed << averagespeed[start] << "(" << setprecision(1) << fixed << sdSpeed[start] << ")," << setprecision(1) << fixed << averagetemp[start] << "(" << setprecision(1) << fixed << sdTemp[start] << ")," << setprecision(1) << fixed << Solar[start] << '\n';
}
/*if(sumTemp[start] == 0 || sumTemp[start] == 0 || sumSpeed[start] == 0){
}*/
}
Example Output looks like this:
January,5.5(1.2),25.5(12.2),196.4
For example if Sum of Speed is 0, that means all values of speed were 0 or null. So it should change to this:
January,,25.5(12.2),196.4
A single line to std::cout doesn't need to be done in one statement. For example:
std::cout << "First";
std::cout << ", second"
std::cout << ", third\n"
Prints the following line:
First, second, third
Now we can use an if to conditionally print the middle part of the string:
std::cout << a;
if (b != 0) {
std::cout << ", " << b;
}
std::cout << ", " << c << '\n';

I need to have spaces between outputted _

I have just more or less finished my first C++ Project, it is a Hangman Game and so far everything works fine. The only Problem is that i need to have spaces between the underlines (_) that represent the hidden word. If anyone could help me on this i would really appreciate it.
// UNCOMMENT THE FOLLOWING LINE (REMOVE THE TWO SLASHES AT THE BEGINNING) TO RUN AUTOMATIC TESTS
#include "tests.h"
#include <iostream>
#include <string>
#include "hangman.h"
int main(){
using namespace std;
// display the hidden word
std::string word_to_guess = chooseWord();
int misses = 0;
std::string displayed_word = word_to_guess;
for(int i=0; i< displayed_word.length(); i++)
displayed_word[i] = '_';
int attempts = 6;
std::cout << "Attempts left:" << attempts << std::endl;
std::cout << "[ " << displayed_word << " ]" << std::endl;
//check for correct letter
while(1){
std::cout << "Your guess";
std::cout << ":";
char guess;
std::cin >> guess;
bool Correct = false;
for(int i=0; i< word_to_guess.length(); i++)
if (guess == word_to_guess[i]) {
displayed_word[i] = word_to_guess[i];
Correct = true;
}
if (!Correct)
attempts--;
if (!Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (!Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
if (Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
//check for win or lose
if (attempts==0)
std::cout << "The word was: " << word_to_guess << std::endl << "You lost!";
if (attempts==0)
return 0;
if (!word_to_guess.find(displayed_word))
std::cout << "You won!";
if (!word_to_guess.find(displayed_word))
return 0;
}
}
First, you can simplify this
if (!Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (!Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
if (Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
by this
std::cout << "Attempts left:" << attempts << std::endl;
std::cout << "[ " << displayed_word << " ]" << std::endl;
Now, about your question, I think a best solution is replacing
std::cout << "[ " << displayed_word << " ]" << std::endl;
by this
std::cout << "[";
for(int i = 0; i < displayed_word.length(); i++) {
if(i == 0 || displayed_word[i] == '_')
std::cout << " ";
std::cout << displayed_word[i];
if(i == displayed_word.length()-1 || (displayed_word[i] == '_' && displayed_word[i+1] != '_'))
std::cout << " ";
}
std::cout << "]" << std::endl;
Explaination:
We put spaces at the beginning and the end, and also around underscores, but we make sure to put only one space between two underscores.

String formatting (c++)

I tried to format output strings in my console application (like a table)
cout << "\n\n-----------------\n";
cout << setw(8) << left << "F\t|";
cout << setw(8) << left << "x\t|";
cout << "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "\t|";
cout.width(8);
cout.setf(ios::left);
cout << x << "\t|";
cout << "\n-----------------\n\n";
But as result my output looks like this
What's wrong with my upper string formatting?
I used the same code as you did and got the same output until I removed the \t at the end of the line. See the new code:
cout << "\n\n-----------------\n";
cout << setw(8) << left << "F\t|";
cout << setw(8) << left << "x\t|";
cout << "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "|";
cout.width(8);
cout.setf(ios::left);
cout << x << "|";
cout << "\n-----------------\n\n";
As already noted, it's the tabs that are causing the problem.
I would not stop at just removing the tabs though. As it stands right now, your code is highly repetitive and next to impossible to maintain. I'd do a (nearly) complete rewrite, with a couple of functions to cut down on the repetition. My first cut would probably look something like this:
// format a value in a field of specified width, followed by a separator
template <class T>
string field(T val, int w, char sep = '|') {
stringstream b;
b << setw(w) << left << fixed << setprecision(3) << val << sep;
return b.str();
}
// generate a separator for a specified number of fields,
// each of a specified width
string sep(int c, int w, char val = '-') {
string s(c * (w + 1), val);
return string("\n") + s + "\n";
}
int main() {
static const int w = 8;
double F = 1.234, x = 3.45;
string s = sep(2, w);
cout << "\n" << s;
cout << field("F", w) << field("x", w) << s;
cout << field(F, w) << field(x, w) << s;
}
Seems to me that this makes the code rather more readable and quite a bit more maintainable. For example, if we decided to display an a and b on the next line, it would seem fairly obvious to add something like:
cout << field(a, w) << field(b, w) << s;
...and we wouldn't have to look very hard to be pretty sure it was going to match up with the previous line. Likewise, if we wanted to change a column width, etc.
You may try:
cout << "\n\n-----------------\n";
cout << setw(8) << left << "F\t\t|"; // insert more tab here
cout << setw(8) << left << "x\t|";
cout << "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "\t|";
cout.width(8);
cout.setf(ios::left);
cout << x << "\t|";
cout << "\n-----------------\n\n";
The console screen looks suspiciously Windows like.
If you are using Windows, you can use the Win32 API to format output more precisely.
In particular, you can use SetConsoleCursorPosition.
COORD position = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, position);
std::cout<<"This will be printed starting at position x, y"<<std::endl;
Try this:
#include <iostream>
#include <iomanip>
#include <map>
#include <string>
using namespace std;
int main()
{
map< float, float > table =
{
{ 8232.0f, 89.0f },
{ 8232.1f, 89.0f },
{ 8232.2f, 89.0f },
{ 8232.3f, 89.0f },
{ 8232.4f, 89.0f },
{ 8232.5f, 89.0f },
{ 8232.6f, 89.0f },
{ 8232.7f, 89.0f },
{ 8232.8f, 89.0f },
};
const size_t CELL_WIDTH = 25;
const string CELL_LINE( CELL_WIDTH, '=' );
// print the header of table
cout << '|' << CELL_LINE << '|' << CELL_LINE << '|' << endl
<< '|'
<< left << setw( CELL_WIDTH ) << "F" << '|'
<< setw( CELL_WIDTH ) << "R" << "|\n|"
<< CELL_LINE << '|' << CELL_LINE << '|' << endl;
// print the body
// change cout precision
cout << fixed << setprecision( 3 );
for ( auto it : table )
cout << "| " << setw( CELL_WIDTH - 1 ) << it.first
<< "| " << setw( CELL_WIDTH - 1 ) << it.second
<< "|\n";
// print the footer
cout << '|' << CELL_LINE << '|' << CELL_LINE << '|' << endl;
return 0;
}
this is the result:

I want to print out some values from 2-d array C++

I want to input data from txt file.
the file contains 2-d array [5][5]
how can i print out the any value i want?
i don't want to print out the whole 5*5 data
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
double distance[5][5] ;
string line;
ifstream ratefile;
ratefile.open("a.txt");
ofstream file;
if (ratefile.is_open())
{
while (! ratefile.eof() )
{
getline (ratefile,line);
ratefile.getline(distance, 25, '*');
cout << "\nDistance [0][0]" << ": " << distance[0][0];
cout << "\nDistance [0][1]" << ": " << distance[0][1];
cout << "\nDistance [0][2]" << ": " << distance[0][2];
cout << "\nDistance [0][3]" << ": " << distance[0][3];
cout << "\nDistance [1][0]" << ": " << distance[1][0];
cout << "\nDistance [1][1]" << ": " << distance[1][1];
cout << "\nDistance [1][2]" << ": " << distance[1][2];
cout << "\nDistance [1][3]" << ": " << distance[1][3];
cout << endl;
cin.get();
return 0;
}
If you only want to output one value and the user should be able to choose a value, you can do something like this:
int x, y;
cin >> x;
cin >> y;
cout << "\nDistance [" << x << "][" << y << "]" << ": " << distance[x][y];
But you should check if the user enter valid numbers (0 <= x < 4 and 0 <= y < 4)
There is part of the code missing, but you are printing values you want. Simply remove the lines you don't want to print.
Of course you can also use variables:
int x = 2,y = 2;
cout << endl << "Distance [" << x << "][" << y << "] : " << distance[x][y];