Option to print output to screen or given file name (c++) - c++

I would like option 2 to pass the output to a typed file name. However, the program is creating the file but not passing the output to the file. I think just using ostream is fine here, but don't know how to go about it.
void displayTable(int n, char op) {
int printOption;
string outputFileName;
ofstream createOutputFile;
while (true) { //option for print screen or print to file
cout << "Select: \n1) Print on Screen \n2) Print to a file name \nSelection: ";
cin >> printOption;
if (printOption == 1)
break;
else if (printOption == 2){
cout << "Type in the name for the output file." << endl;
cin >> outputFileName;
createOutputFile.open(outputFileName);
break;
}
else
cout << "Please enter a valid number." << endl;
}
int max = getMaxSize(n, op);
cout << setw(max) << op << "|";
for (int i = 1; i <= n; ++i) {
cout << setw(max) << i;
}
cout << endl;
for (int i = 0; i < max; ++i) {
cout << "-";
}
cout << "+";
for (int i = 0; i < n * max; ++i) {
cout << "-";
}
cout << endl;
for (int i = 1; i <= n; ++i) {
cout << setw(max) << i << "|";
for (int j = 1; j <= n; ++j) {
cout << setw(max) << getValue(i, j, op);
}
cout << endl;
}
cout << endl;
createOutputFile.close();
}

You are not printing anything to createOutputFile, everything is being printed to cout instead. That is why to don't see anything in the file, and everything in the console.
The easiest way to solve your issue is to redirect cout to createOutputFile's output buffer, eg:
auto cout_buff = cout.rdbuf();
...
createOutputFile.open(outputFileName);
cout.rdbuf(createOutputFile.rdbuf())
// all cout outputs will now go to the file...
...
cout.rdbuf(cout_buff); // restore when finished...
Otherwise, move your print logic to a separate function that takes an ostream& as a parameter:
void doMyLogic(ostream &os)
{
// print to os as needed...
}
...
if (printOption == 1) {
doMyLogic(cout);
break;
}
if (printOption == 2) {
...
ofstream createOutputFile(outputFileName);
doMyLogic(createOutputFile);
break;
}
...

Related

I want this c++ program to find the the words starting with user entereed letter and print them using a new function

I want this c++ program to find the the words starting with user entereed letter and print them using a new function.but the thins is that it only finds 1st letter for the second time it runs ina loop and then , i dont know what happens ... I am a beginner please help me!
uncomment the line that are necessary
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void getUserInput(string *filename, string *find)
{
cout << "file name : ";
cin >> *filename;
cout << "required character : ";
cin >> *find;
}
string* processFile(string fileName, string word, int *t, int *w, string found[])
{
fstream file;
int countIn = 0,
totaal = 0;
int *count = &countIn;
int *total = &totaal;
int i = 0;
string find; // the max length of the file should not exceed this value is if does please change it here.
file.open(fileName, ios::in);
if (file.is_open())
{
while (!file.eof())
{
file >> find;
totaal++;
if (word == find)
{
char a[100];
int s = find.size();
for (int j = 0; i < find.size(); j++)
{
string(1, find[i]);
}
found[i] = find;
i++;
countIn++;
}
}
}
else
cout << "!!!!invalid file name!!!!\n";
file.close();
//for (int i = 0, j = 0; i < totaal; i++)
//{
//
// cout << find[i] << '\t' << find[i][0] << endl;
//
// if (word == find[i][0])
// {
// cout << "i is " << i << endl;
// cout << "j is " << j << endl;
// cout << "Calculated i and j\n";
// found[j] = find[i];
// cout << "found[j] " << found[j] << "\nfind[i] " << find[i] << endl;
// j++;
// countIn++;
// cout << "Inside if\n";
// }
// cout << "outsidenside if\n";
//}
*t = *total;
*w = *count;
//cout << countIn << endl << totaal << endl;
//cout << *count << endl << *total<<endl;
return found;
}
void displayOutput(int total, int count, string wordlist[])
{
cout << "Total words in the file: " << total;
if (count != 0)
{
cout << "\nTotal " << count << " related words found in the file\n";
for (int i = 0; i < count; i++)
cout << i + 1 << "\t" << wordlist[i] << endl;
}
else
cout << "No matching case found\n";
}
int main()
{
string nameoffile;
string wordtofind;
string *ptr1 = &nameoffile;
string *ptr2 = &wordtofind;
string foundwords[] = { "" };
int occur = 0,
totalWords = 0;
int *occ = &occur;// occurence of the certain word
int *tot = &totalWords;// total wods in the file
getUserInput(ptr1, ptr2);
processFile(nameoffile, wordtofind, occ, tot, foundwords); //calling the processing function
displayOutput(occur, totalWords, foundwords);
return 0;
}

C++ adding extra, unwanted characters to a string

I am having a bug that I cannot find a fix for through google searching. I am attempting to make a text based version of the game Mastermind. I am using a string the is set from an array of chars as the criteria for a while loop. When the string is equal to "****" the game is supposed to tell the player that they won and exit, but for some reason a ^A is being added on to the end of the string that is being checked, even though it is not in the char array.
Here is the function that sets the char array and returns a string from that array:
string check(int guess[4], int num[4]) {
char hints[4];
cout << " ";
for (int i = 0; i < 4; i++) {
if (guess[i] == num[i]) {
hints[i] = '*';
cout << "*";
}
else {
for (int x = 0; x < 4; x++) {
if (guess[i] == num[x]) {
cout << "+";
}
}
}
if (guess[i] != num[i]) {
hints[i] = ' ';
}
}
string hint(hints);
cout << endl;
cout << hint << endl;
return hint;
}
And here is the function checking the value of the string:
while (hints.compare("****") != 0) {
if (guessCount == 5) {
break;
}
cout << "Guess?: ";
cin >> guess;
intToArray(guess, guessArr);
hints = check(guessArr, nums);
cout << hints << endl;
guessCount++;
}
if (hints.compare("****") == 0) {
cout << "You win! The number was: ";
for (int i = 0; i < 4; i++) {
cout << nums[i];
}
}
You haven't null-terminated the hints array, so you are getting extra garbage that is lying around on the stack in your string.
You could let the hint string know how long it is when you are constructing it.
string hint(hints, 4);
cout << endl;
cout << hint << endl;

vector iterator + offset out of range, at the end of while loop it gives the error

while (deckSize > 2)
{
one_Card = card_deck.back();
card_deck.pop_back();
two_Card = card_deck.back();
card_deck.pop_back();
three_Card = card_deck.back();
card_deck.pop_back();
oneCard_Name = card_name(one_Card);
twoCard_Name = card_name(two_Card);
threeCard_Name = card_name(three_Card);
oneCard_Suit = card_suit(one_Card);
twoCard_Suit = card_suit(two_Card);
threeCard_Suit = card_suit(three_Card);
oneCard_Rank = card_rank(one_Card);
twoCard_Rank = card_rank(two_Card);
threeCard_Rank = card_rank(three_Card);
bool between1 = (oneCard_Rank < threeCard_Rank && threeCard_Rank < twoCard_Rank);
bool between2 = (twoCard_Rank < threeCard_Rank && threeCard_Rank < oneCard_Rank);
cout << "Here are your two cards: " << endl;
cout << setw(10) << oneCard_Name << " of " << oneCard_Suit << setw(20) << twoCard_Name << " of " << twoCard_Suit << endl;
cout << "Do you think the next card will lie between these? (y/n): ";
cin >> user_input;
cout << endl << endl;
cout << "Here is your next card: " << endl;
cout << setw(10) << threeCard_Name << " of " << threeCard_Suit << endl << endl << endl;
count++;
if(user_input == "y" || user_input == "yes" || user_input == "Yes" || user_input == "Y")
{
if(between1 || between2)
{
cout << "You win!" << endl;
win++;
}
else
{
cout << "You lose!" << endl;
lose++;
}
}
else
{
if(between1 || between2)
{
cout << "You lose!" << endl;
lose++;
}
else
{
cout << "You win!" << endl;
win++;
}
}
}
cout << "You have played this game " << count << " times and you have won: " << win << " and lost " << lose << endl;
return 0;
}
These are the two subprograms that shuffle and initialize the deck
void initDeck(vector<int> &card_deck)
{
int i;
for(i = 0; i <= 51; i++)
{
card_deck[i] = i;
}
}
void shuffleDeck(vector<int> & card_deck)
{
int n;
for(n = 51; n >= 0; n--)
{
int i = randomize();
int temp = card_deck[i];
int temp2= card_deck[n];
card_deck[n] = temp;
card_deck[i] = temp2;
}
}
After when I run the program it allows me to run it, but when I reach to the number less than the condition in the while loop it just gives me an error, and does not finish the program. I had this error earlier and fixed it, so I have a basic understanding of what the error means. From my knowledge it is trying to collect numbers past the vector length. However this time I don't see my error at all.
deckSize is not being set/updated anywhere. It should rather be card_deck.size()
You should use push_back and emplace for the type vector like this:
void initDeck(vector<int> &card_deck){
int i;
for(i = 0; i <= 51; i++)
{
card_deck.push_back(i);
}
}
Take a see to this link
Try this:
void initDeck(vector<int> &card_deck)
{
int i;
for(i = 0; i <= 51; i++)
{
card_deck.push_back(i);
}
}
void shuffleDeck(vector<int> & card_deck)
{
int n;
for(n = 51; n >= 0; n--)
{
int i = randomize();
int temp = card_deck[i];
int temp2= card_deck[n];
card_deck[n] = temp;
card_deck[i] = temp2;
}
}
For generating random number see this and this. Or you can find other solution that is more reliable.

read text file then add character to list?

So I'm trying to complete this part of a program where I have to read a text file from Stdin and add it to the 'word list' wl. I get how to read from a text file but I don't know how to go about adding 'words' to a list, if that makes sense. So here's what I got:
string getWord(){
string word;
while (cin >> word){
getline(cin, word);
}
return word;
}
void fillWordList(string source[], int &sourceLength){
ifstream in.file;
sourceLength = 50;
source[sourceLength]; ///this is the part I'm having trouble on
Source is an array that determines how many words are read from the text and length is the amount printed on screen.
Any ideas on what I should begin with?
EDIT: Here's the program I'm writing the implementation for:
#include <iostream>
#include <string>
#include <vector>
#include "ngrams.h"
void help(char * cmd) {
cout << "Usage: " << cmd << " [OPTIONS] < INPUTFILE" << endl;
cout << "Options:" << endl;
cout << " --seed RANDOMSEED" << endl;
cout << " --ngram NGRAMCOUNT" << endl;
cout << " --out OUTPUTWORDCOUNT" << endl;
}
string source[250000];
vector<string> ngram;
int main(int argc, char* argv[]) {
int n, outputN, sl;
n = 3;
outputN = 100;
for (int i = 0; i < argc; i++) {
if (string(argv[i]) == "--seed") {
srand(atoi(argv[i+1]));
} else if (string(argv[i]) == "--ngram") {
n = 1 + atoi(argv[i+1]);
} else if (string(argv[i]) == "--out") {
outputN = atoi(argv[i+1]);
} else if (string(argv[i]) == "--help") {
help(argv[0]);
return 0; }
}
fillWordList(source,sl);
cout << sl << " words found." << endl;
cout << "First word: " << source[0] << endl;
cout << "Last word: " << source[sl-1] << endl;
for (int i = 0; i < n; i++) {
ngram.push_back(source[i]);
}
cout << "Initial ngram: ";
put(ngram);
cout << endl;
for (int i = 0; i < outputN; i++) {
if (i % 10 == 0) {
cout << endl;
}
//put(ngram);
//cout << endl;
cout << ngram[0] << " ";
findAndShift(ngram, source, sl);
} }
I'm supposed to use this as a reference but it dosen't help me too much.
Declaring raw array requires the size of the array to be a compile-time constant. Use std::vector or at least std::array instead. And pass source by reference if you want to fill it.

When I read from a file in C++ it, displays the numbers more times then it should

I am coding a program that allows the user to name a file and open or create that file. Then they are able to read the info from that file in different ways or write more info into the file. The problem is that when I choose an option to read the file it first reads it fine then when I try to read it a different way it has two sets of numbers, as if it is reading the file twice.
I am unable to pin point the problem to any one function, and it is hard the explain the problem so I am posting the whole program. if you could help that would be great. Thank you in advance.
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(), f1(), f2(), f3(), f4(), f5(), f6(), f7();
string file;
const int NUM_DATA = 50;
double data[NUM_DATA], temp;
int num = 0;
int main()
{
int choice;
do
{
system ("cls");
cout << " ** MENU ** \n\n";
cout << "Current Data File: " << file << "\n\n";
cout << "(1) Select/Create data file (.txt file extension will be added automatically)\n";
cout << "(2) Display all the numbers, total and average\n";
cout << "(3) Display all the numbers from smallest to the largest\n";
cout << "(4) Select a number and display how many times it shows up\n";
cout << "(5) Display the largest number\n";
cout << "(6) Append random number(s)\n";
cout << "(7) Exit the program\n\n";
do
{
cout << "Choice: ";
cin >> choice;
cout << endl;
}
while (choice < 1 || choice > 7);
switch (choice)
{
case 1: f1();
break;
case 2: f2();
break;
case 3: f3();
break;
case 4: f4();
break;
case 5: f5();
break;
case 6: f6();
break;
}
}
while (choice != 7);
return 0;
}
// Select file
int f1()
{
cout << "Name of data file: ";
cin >> file;
file = file + ".txt";
ifstream fileI;
fileI.open(file.c_str());
if(!fileI)
{
cout << "\nFile not found, creating file. \n\n";
ofstream fileO;
fileO.open(file.c_str());
fileO.close();
}
else
{
cout << "\nFile successfully read. \n\n";
fileI.close();
}
system("pause");
return 0;
}
// Display all the numbers, the total and the average
int f2()
{
f7();
ifstream fileI;
fileI.open(file);
double total = 0;
double average;
for (int count = 0; count < num; count++)
{
total += data[count];
cout << data[count] << endl;
}
average = total / num;
cout << "Total: " << total << endl;
cout << "Avearage: " << average << "\n\n";
fileI.close();
system("pause");
cin.ignore();
return 0;
}
// Display all the numbers from smallest to largest
int f3()
{
f7();
ifstream fileI;
fileI.open(file);
for(int i = 0; i < num; i++)
{
for(int j = 0; j < num; j++)
{
if(data[i] < data[j])
{
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
for (int count = 0; count < num; count++)
{
cout << data[count] << "\n\n";
}
fileI.close();
system("pause");
return 0;
}
// Display how many times a number shows up
int f4()
{
f7();
ifstream fileI;
fileI.open(file);
int numb, times = 0;
cout << "Search number: ";
cin >> numb;
cout << endl;
for (int count = 0; count < num; count++)
{
if (numb == data[count])
{
times ++;
}
}
cout << numb << " ocurrs " << times << " times." << "\n\n";
fileI.close();
system("pause");
return 0;
}
// Display the largest number
int f5()
{
f7();
ifstream fileI;
fileI.open(file);
int large = data[0];
for (int count = 0; count < num; count++)
{
if (large < data[count])
{
large = data[count];
}
}
cout << "Larget number: " << large << "\n\n";
fileI.close();
system("pause");
return 0;
}
// Append one or more random numbers
int f6()
{
ofstream fileO;
fileO.open(file, ios::app);
int rndm, numbs;
srand(time(NULL));
cout << "Add how many numbers: ";
cin >> rndm;
cout << endl;
for (int count = num + 1; count <= num + rndm ; count++)
{
numbs = (rand()%50+1);
fileO << numbs << endl;
}
cout << "Data succesfully written.\n\n";
fileO.close();
system("pause");
return 0;
}
//Array function
int f7()
{
ifstream fileI;
fileI.open(file);
fileI >> temp;
while (num < NUM_DATA && !fileI.eof())
{
data[num] = temp;
++num;
fileI >> temp;
}
fileI.close();
return num;
}
It's because, in f7(), you use num from it's last known value, rather than resetting it.
That means you're simply tacking another copy of the file on to the end of the array each time.
And, please, if you value the sanity of the people who may have to maintain your code, don't use function names like fN(), they're supposed to be readable :-)
Interestingly enough, this only affects the functions that use the array. I notice that your function which gives you the total and average reads the file itself, despite calling f7() to read it into the array. You may want to choose one method and stick with it.