Making a console progress bar? (Windows) - c++

So I have a function (or rather, I'll turn it into a function later) to make a random % progress in a console window; like this:
#include <iostream>
#include <time.h>
#include <cmath>
#include <windows.h>
using namespace std;
int main()
{
srand(time(0));
int x = 0;
for(int i = 0; i<100; i++){
int r = rand() % 1000;
x++;
cout << "\r" << x << "% completed." << flush;
if(i < 43){
Sleep(r/6);
}else if(i > 43 && i < 74){
Sleep(r/8);
}else if(i < 98){
Sleep(r/5);
}else if(i > 97 && i != 99){
Sleep(2000);
}
}
cout << endl << endl << "Operation completed successfully.\n" << flush;
return 0;
}
The thing is, I want the output to be like this:
1% completed
|
(later...)
25% completed
|||||||||||||||||||||||||
How can I do that?
Thanks in advance!

Printing character '\r' is useful. It puts the cursor at the beginning of the line.
Since you can not access to previous line anymore, you can have something like this:
25% completed: ||||||||||||||||||
After each iteration:
int X;
...
std::cout << "\r" << percent << "% completed: ";
std::cout << std::string(X, '|');
std::cout.flush();
Also, you can use: Portable text based console manipulator

I think this looks better:
#include <iostream>
#include <iomanip>
#include <time.h>
#include <cmath>
#include <windows.h>
#include <string>
using namespace std;
string printProg(int);
int main()
{
srand(time(0));
int x = 0;
cout << "Working ..." << endl;
for(int i = 0; i<100; i++){
int r = rand() % 1000;
x++;
cout << "\r" << setw(-20) << printProg(x) << " " << x << "% completed." << flush;
if(i < 43){
Sleep(r/6);
}else if(i > 43 && i < 74){
Sleep(r/8);
}else if(i < 98){
Sleep(r/5);
}else if(i > 97 && i != 99){
Sleep(1000);
}
}
cout << endl << endl << "Operation completed successfully.\n" << flush;
return 0;
}
string printProg(int x){
string s;
s="[";
for (int i=1;i<=(100/2);i++){
if (i<=(x/2) || x==100)
s+="=";
else if (i==(x/2))
s+=">";
else
s+=" ";
}
s+="]";
return s;
}

Use graphics.h or use more advanced WinBGI library. Download it and place the library files and the graphics.h file in appropriate locations in your project. Then just use the function named gotoxy(int x, int y) where x and y are in character places(not pixels) Consider your console window in the 4th quadrant of a Cartesian 2D axes system. But x and y starts typically from 1 upto n(depending on the size of the console window). You just have to clear the screen each time progress happens like this
system("cls");
as cls is the command for this in case of windows. Otherwise for linux/Mac use
system("clear");
Now this function is in stdlib.h header. After that you can easily update the progress bar and write anywhere in it.
But the progress bar you are using is discontinuous. There is more efficient way is to use
# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█'):
"""
Call in a loop to create terminal progress bar
#params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = '\r')
# Print New Line on Complete
if iteration == total:
print()
#
# Sample Usage
#
from time import sleep
# A List of Items
items = list(range(0, 57))
l = len(items)
# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
for i, item in enumerate(items):
# Do stuff...
sleep(0.1)
# Update Progress Bar
printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
# Sample Output
Progress: |█████████████████████████████████████████████-----| 90.0% Complete

Related

String not displaying all characters in c++ [duplicate]

This question already has answers here:
Print leading zeros with C++ output operator?
(6 answers)
Closed 2 years ago.
I want cout to output an int with leading zeros, so the value 1 would be printed as 001 and the value 25 printed as 025. How can I do this?
With the following,
#include <iomanip>
#include <iostream>
int main()
{
std::cout << std::setfill('0') << std::setw(5) << 25;
}
the output will be
00025
setfill is set to the space character (' ') by default. setw sets the width of the field to be printed, and that's it.
If you are interested in knowing how the to format output streams in general, I wrote an answer for another question, hope it is useful:
Formatting C++ Console Output.
Another way to achieve this is using old printf() function of C language
You can use this like
int dd = 1, mm = 9, yy = 1;
printf("%02d - %02d - %04d", mm, dd, yy);
This will print 09 - 01 - 0001 on the console.
You can also use another function sprintf() to write formatted output to a string like below:
int dd = 1, mm = 9, yy = 1;
char s[25];
sprintf(s, "%02d - %02d - %04d", mm, dd, yy);
cout << s;
Don't forget to include stdio.h header file in your program for both of these functions
Thing to be noted:
You can fill blank space either by 0 or by another char (not number).
If you do write something like %24d format specifier than this will not fill 2 in blank spaces. This will set pad to 24 and will fill blank spaces.
cout.fill('*');
cout << -12345 << endl; // print default value with no field width
cout << setw(10) << -12345 << endl; // print default with field width
cout << setw(10) << left << -12345 << endl; // print left justified
cout << setw(10) << right << -12345 << endl; // print right justified
cout << setw(10) << internal << -12345 << endl; // print internally justified
This produces the output:
-12345
****-12345
-12345****
****-12345
-****12345
In C++20 you'll be able to do:
std::cout << std::format("{:03}", 25); // prints 025
In the meantime you can use the {fmt} library, std::format is based on.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
cout.fill( '0' );
cout.width( 3 );
cout << value;
Another example to output date and time using zero as a fill character on instances of single digit values: 2017-06-04 18:13:02
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
int main()
{
time_t t = time(0); // Get time now
struct tm * now = localtime(&t);
cout.fill('0');
cout << (now->tm_year + 1900) << '-'
<< setw(2) << (now->tm_mon + 1) << '-'
<< setw(2) << now->tm_mday << ' '
<< setw(2) << now->tm_hour << ':'
<< setw(2) << now->tm_min << ':'
<< setw(2) << now->tm_sec
<< endl;
return 0;
}
I would use the following function. I don't like sprintf; it doesn't do what I want!!
#define hexchar(x) ((((x)&0x0F)>9)?((x)+'A'-10):((x)+'0'))
typedef signed long long Int64;
// Special printf for numbers only
// See formatting information below.
//
// Print the number "n" in the given "base"
// using exactly "numDigits".
// Print +/- if signed flag "isSigned" is TRUE.
// Use the character specified in "padchar" to pad extra characters.
//
// Examples:
// sprintfNum(pszBuffer, 6, 10, 6, TRUE, ' ', 1234); --> " +1234"
// sprintfNum(pszBuffer, 6, 10, 6, FALSE, '0', 1234); --> "001234"
// sprintfNum(pszBuffer, 6, 16, 6, FALSE, '.', 0x5AA5); --> "..5AA5"
void sprintfNum(char *pszBuffer, int size, char base, char numDigits, char isSigned, char padchar, Int64 n)
{
char *ptr = pszBuffer;
if (!pszBuffer)
{
return;
}
char *p, buf[32];
unsigned long long x;
unsigned char count;
// Prepare negative number
if (isSigned && (n < 0))
{
x = -n;
}
else
{
x = n;
}
// Set up small string buffer
count = (numDigits-1) - (isSigned?1:0);
p = buf + sizeof (buf);
*--p = '\0';
// Force calculation of first digit
// (to prevent zero from not printing at all!!!)
*--p = (char)hexchar(x%base);
x = x / base;
// Calculate remaining digits
while(count--)
{
if(x != 0)
{
// Calculate next digit
*--p = (char)hexchar(x%base);
x /= base;
}
else
{
// No more digits left, pad out to desired length
*--p = padchar;
}
}
// Apply signed notation if requested
if (isSigned)
{
if (n < 0)
{
*--p = '-';
}
else if (n > 0)
{
*--p = '+';
}
else
{
*--p = ' ';
}
}
// Print the string right-justified
count = numDigits;
while (count--)
{
*ptr++ = *p++;
}
return;
}

Finding a vertical word from a .txt file in C++

I am working on a small project and I am trying to put a set of letters (5 rows, 5 columns) from a .txt file into an array, then finding the vertical word "DOG." Not only do I have to find it, but I have to determine the position of the word also. I am having so much trouble getting it to complete this task.
1) It doesn't matter if I take the word DOG out or not. My code still says it finds the word.
2) It always displays the same position if I move the word DOG to another spot on the puzzle.
3) It just doesn't work...
Can any of you help?
Please keep in mind, this is my 2nd week of C++. I am currently taking an intro college course on this language so no hate. I am only trying to learn. I spent probably a total of 12 hours on this code.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
char puzzle[25];
ifstream fin;
fin.open("words.txt");
int rows {5};
int cols {5};
for (int i=0;i<rows*cols;i++) fin >> puzzle[i];
fin.close();
/***********
This is what I believe the array looks like and the values of each position.
* 0 1 2 3 4
* 5 6 7 8 9
* 10 11 D 13 14
* 15 16 O 18 19
* 20 21 G 23 24
************/
string s = "DOG";
cout << s.size() << endl;
int foundpos {-1};
for (int i=0; i<rows*cols; i++) {
if (puzzle[i]==s[0]) {
foundpos=i;
for (int j=5; j<s.size(); j+5) {
if (puzzle[i+j]!=s[j]) {
foundpos=-1;
break;
}
}
}
if (foundpos>0) {
cout << s << " was found at pos " << foundpos << endl;
cout << s << " found on row " << foundpos << endl;
cout << s << " found on column " << foundpos << endl;
break;
}
}
if (foundpos==-1) cout << s << " not found." << endl;
return 0;
}
===============================================================
Now here is the .txt file.
YRUVG
RTSDC
IFDYU
EPOWE
PWGHT
Your problem is here:
for (int j=5; j<s.size(); j+5) {
if (puzzle[i+j]!=s[j]) {
foundpos=-1;
break;
}
}
Your idea: when you get the first letter of given string, you try to check the next letter of same column is same with the next letter of given string. But, you ran the loop from 5, note that s.size() = 3, so your loop does NOT run. Then, the foundpos is not set to -1. That's why you always see 8 in print log.
Fix:
for (int j=1; j<s.size(); j++) {
if (puzzle[i+j*5]!=s[j]) {
foundpos=-1;
break;
}
}
There were a few other caveats that you would need to address that I was unable to include in the comments. Since you are reading all characters into a single array which you want to represent as a 2D array, you will need to index puzzle[i][j] as puzzle[i + j * STRIDE].
The primary approach is to loop over each character is puzzle checking whether the first character in your search term is the current character. If it is, you check:
Do enough character remain between i and rows*col for the rest of the search term to exist in a column? If not, you can conclude your string is not found;
If enough character remain, set a found = true flag and loop over the remaining characters in your search term (e.g. from j = 1 to term.size()) checking puzzle[i + j * STRIDE] != term[j] if a non-matching term is found, set found = false and break the term loop; and
finally check the found flog. If it has survived as found == true at this point, your search term has been found and you can simply output the indexes for the search term and return.
For example, putting it altogether in a short example, you could do:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype> /* for isspace() */
#define STRIDE 5 /* define const for stride */
int main (int argc, char **argv) {
char puzzle [STRIDE*STRIDE] = {0}, c; /* puzzle and char */
size_t psize = STRIDE*STRIDE, n = 0; /* puzzle size & char count */
std::string fname = argv[1], /* filename */
term = argc > 2 ? argv[2] : "DOG"; /* search term */
std::ifstream f; /* file stream */
if (argc < 2) { /* validate at least filename given as arg */
std::cerr << "error: insufficien input.\n"
<< "usage: " << argv[0] << "infile\n";
return 1;
}
f.open (argv[1]); /* open file */
if (!f.is_open()) { /* validate file open for reading */
perror (("error file open failed " + fname).c_str());
return 1;
}
while (n < psize && f >> c) /* read file into puzzle */
if (!isspace (c))
puzzle[n++] = c;
f.close(); /* close file */
if (n < psize) { /* validate psize characters read */
std::cerr << "error: only " << n << "characters read.\n";
return 1;
}
for (size_t i = 0; i < psize; i++) { /* loop over each char */
if (puzzle[i] == term[0]) { /* if matches 1st in term */
size_t tlen = term.size(), /* get term size */
found = 1; /* set found flag true */
if (i + (tlen - 1) * STRIDE >= psize) /* enough chars left? */
break;
for (size_t j = 1; j < tlen; j++) /* loop 1 to term len */
if (puzzle[i + j * STRIDE] != term[j]) { /* next !found? */
found = 0; /* set found flag false */
break; /* break loop */
}
if (found) { /* if found, output term & indexes, return */
std::cout << "found " << term << " at indexes " << i;
for (size_t j = 1; j < tlen; j++)
std::cout << ", " << i + j * STRIDE;
std::cout << '\n';
return 0;
}
}
}
/* only reachable if not found */
std::cout << "'" << term << "' not found.\n";
return 1;
}
Example Input File
$ cat dat/vertword.txt
YRUVG
RTSDC
IFDYU
EPOWE
PWGHT
Example Use/Output
$ ./bin/verticalfind dat/vertword.txt
found DOG at indexes 12, 17, 22
$ ./bin/verticalfind dat/vertword.txt RIEP
found RIEP at indexes 5, 10, 15, 20
$ ./bin/verticalfind dat/vertword.txt MOP
'MOP' not found.
Look things over and let me know if you have further questions.

Why does starting value affect outcome of Seeded Random?

Trying to figure out why the starting value affects the seeded random in this code. I would expect for it to find the match at the same location for 12 character or more match no matter of the starting value for the seed, but it seems as though I am getting different results depending on the starting value of the seed which to me makes no sense. Anyone who why I am getting these results as shown from 0, 1, 2, and 3 for starting values when all 4 should flag the same values as a match to 12 more more characters.
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **0** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
**Greater or Equal to = 12 ===== 923425024**
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **1** thru 1000000000
WARNING - Program Running Please Wait...
**Greater or Equal to = 12 ===== 204715678**
25% Complete
**Greater or Equal to = 12 ===== 346933630**
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **2** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **3** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Code:
#include <iostream>
#include <string>
int delay;
long long int counter1 = 0; // Add LL beyond 9 digits
long long int endcount = 0; // while loop end counter
long long int seed1 = 0;
int match2 = 0;
int ST = 0;
int flag = 0;
float progress = 0;
int step1 = 0;
int step2 = 0;
int step3 = 0;
int main()
{
system("color b0");
std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n";
std::cout << " Poor Key Finder Version 1.0\n";
std::cout << " Build 01/30/2016\n";
std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n";
std::cout << " Enter Starting Key Value\n";
std::cin >> counter1;
std::cout << " Enter Ending Key Value\n";
std::cin >> endcount;
std::cout << " Enter Duplicate Character Counter Value\n";
std::cin >> flag;
system("cls");
std::string str =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()_-+=?<>:\\/~.,;";
std::string str2=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()_-+=?<>:\\/~.,;";
system("#echo. Started on %date% at %time%>>LogKey.txt");
system("color f0");
std::cout << "Poor Key Finder - Search for " << flag
<< " or more matches \n";
std::cout << "Searching through Key Values of " << counter1 << " thru "<<endcount<<"\n\ n";
std::cout << " WARNING - Program Running Please Wait...\n\n";
while (counter1 <= endcount)
{
seed1 = counter1;
srand(seed1);
random_shuffle(str.begin(), str.end()); // Shuffle the string
ST = 0;
match2 = 0;
progress = ((100 * counter1) / endcount);
if (progress == 25)
{
step1++;
if (step1 == 1)
{
std::cout << "25% Complete\n";
}
else
{
}
}
else if (progress == 50)
{
step2++;
if (step2 == 1)
{
std::cout << "50% Complete\n";
}
else
{
}
}
else if (progress == 75)
{
step3++;
if (step3 == 1)
{
std::cout << "75% Complete\n";
}
else
{
}
}
else if (endcount == counter1)
{
std::cout << "100% Complete\n";
}
else
{
}
while (ST <= 85)
{
if (str[ST] == str2[ST])
{
match2++;
}
else
{
}
ST++;
}
if (match2 >= flag)
{
std::cout << "Greater or Equal to = " << flag << " ===== " << seed1
<< "\n";
}
else
{
}
counter1++;
}
std::cout << "Completed = " << endcount << "\n\n\n";
system("#echo. Ended on %date% at %time%>>LogKey.txt");
system("pause");
return 0;
}
I now understand what you are asking! The problem is because you shuffle str on each iteration without resetting it to its initial value each time, so it accumulates randomness from the previous iterations' shuffles.
In other words, you have two "seeds" -- one in the counter which you set each iteration using srand and one you do NOT reset, contained in str's shuffled character order.
To keep each iteration consistent, you need to reset str to the same base value before each shuffle.

Using CheckSum with C++ for 13 Digit ISBN

I am trying to calculate the final digit of a 13 digit ISBN using the first 12 digits using C++. I feel like my code should be correct but I have a feeling the formula I'm using may be wrong.
The formula is:
10 - (d0 + d1 * 3 + d2 + d3 * 3 + d4 + d5 * 3 + d6 + d7 * 3 + d8 + d9 * 3 + d10 + d11 * 3) % 10
Here's what I have:
#include <cstring>
#include <iostream>
int main() {
int weightedSum = 0;
int checksum = 0;
int i; //for loop decrement
int mul = 3;
const int LENGTH = 12;
char ISBNinput[LENGTH];
std::cout << "Enter first 12 digits of ISBN: "; //ask user for input
std::cin >> ISBNinput; //stores input into ISBNinput
std::cout << std::endl;
for (i = 0; i < strlen(ISBNinput); i++) {
weightedSum += (ISBNinput[i] % 12) * mul;
if (mul == 3) {
mul = 1;
} else {
mul = 3;
}
}//close for loop
checksum = weightedSum % 10; //calculates checksum from weightedSum
std::cout << checksum << std::endl; //prints checksum with new line for format
return 0;
}
For example:
978007063546 should return 3
and
978032133487 should return 9
Thank you for any help.
Here's how I go about this.
First, let's decide how we're going to test this. I'll assume that we've written the function, and that it gives the correct output. So I pick up a couple of books off my desk, and test that it works for them:
#include <iostream>
int main()
{
std::cout << "Book 1 - expect 3, got " << checksum("978032114653") << std::endl;
std::cout << "Book 2 - expect 0, got " << checksum("978020163361") << std::endl;
}
Of course, when we try to compile that, we get an error. So create the function, before main():
char checksum(const char *s)
{
return '1';
}
Now it compiles, but the result is always 1, but now we can start to fill in the body. Let's start with some smaller examples, that we can calculate by hand; add these at the beginning of main():
std::cout << "1 digit - expect 4, got " << checksum("6") << std::endl;
Now let's get this one working - this gives us conversion from character to digit and back, at least:
char checksum(const char *s)
{
int digit = *s - '0';
return '0' + 10 - digit;
}
Let's try 2 digits:
std::cout << "1 digit - expect 6, got " << checksum("11") << std::endl;
And now our test fails again. So add some more processing, to make this pass (and not break the single-digit test):
char checksum(const char *s)
{
int sum = 0;
int digit = *s - '0';
sum += digit;
++s;
if (*s) {
digit = *s - '0';
sum += 3 * digit;
}
return '0' + (10 - sum)%10;
}
We're probably ready to make this into a loop now. Once that's passed, we no longer need the short tests, and I have:
#include <iostream>
char checksum(const char *s)
{
int sum = 0;
for (int mul = 1; *s; ++s) {
int digit = *s - '0';
sum += mul * digit;
mul = 4 - mul;
}
return '0' + (1000 - sum)%10;
}
int test(const char *name, char expected, const char *input)
{
char actual = checksum(input);
if (actual == expected) {
std::cout << "PASS: " << name << ": "
<< input << " => " << actual
<< std::endl;
return 0;
} else {
std::cout << "FAIL: " << name << ": "
<< input << " => " << actual
<< " - expected " << expected
<< std::endl;
return 1;
}
}
int main()
{
int failures = 0;
failures += test("Book 1", '3', "978032114653");
failures += test("Book 2", '0', "978020163361");
return failures > 0;
}
I factored out the actual checking into a function here, so we can keep count of failures, and exit with the appropriate status, but everything else is as I described above.
You'll want to add a few more test cases - in particular, make sure the function correctly returns the extreme values 0 and 9 when it should.
There is one clear bug in your code: you are not allocating enough space in for ISBNinput. You should make it one character longer:
const int LENGTH = 13;
The reason for this is that that character-array strings are terminated with an extra null character. You might be lucky and the next byte in memory could sometimes happen to be a null byte, in which case the program would still work sometimes.
If you run the program with valgrind or a similar memory checker you are likely to see an error as the program access memory beyond what was allocated on the stack.
Also I think there is another bug. I think that mul should be initialized to 1.
By the way, this code is very fragile, depending on you entering no more than 12 characters, all of which are assumed to be digits. It might be OK as a quick hack for a proof-of-concept, but should not be used in any real program.

C++ Cascading Stream Insertion (HW Help)

I found this potential solution in previous stack question. My problem is that it's not outputting to the file.
The program terminates without errors and actually does what it's supposed to do as I have verified this with a cout.
The program takes in a 7-digit phone number. Then writes to a file all possible words that can be made with those 7 digits, respecting the letter-number association on a standard telephone.
Program uses two functions: main and wordGenerator and includes iostream, fstream, & cstdlib
main :
int main()
{
int phoneNumber[ 7 ] = { 0 }; // holds phone number
// prompt user to enter phone number
cout << "Enter a phone number (digits 2 through 9) " << "in the form: xxx-xxxx\n";
// loop 8 times: 7 digits plus hyphen;
// hyphen is not placed in phoneNumber
for ( int u = 0, v = 0; u < 8; u++ )
{
int i = cin.get();
// test if i is between 0 and 9
if ( i >= '0' && i <= '9' )
phoneNumber[ v++ ] = i - '0';
} // end for
wordGenerator( phoneNumber ); // form words from phone number
} // end main
wordGenerator :
void wordGenerator( const int * const n )
{
cout << "Some Word Forming Magic is going on!" << endl;
// set output stream and open output file
ofstream outFile("phone.dat");
// letters corresponding to each number
const char * phoneLetters[] = {"___", "___", "ABC", "DEF", "GHI", "JKL", "MNO", "PRS", "TUV", "WXY"};
// terminate if file could not be opened
if ( !outFile )
{
cerr << "File could not be opened! Program Terminating..." << endl;
exit(1);
}
int count = 0; // number of words found
// output all possible combinations
for ( int i1 = 0; i1 <= 2; i1++ )
{
for ( int i2 = 0; i2 <= 2; i2++ )
{
for ( int i3 = 0; i3 <= 2; i3++ )
{
for ( int i4 = 0; i4 <= 2; i4++ )
{
for ( int i5 = 0; i5 <= 2; i5++ )
{
for ( int i6 = 0; i6 <= 2; i6++ )
{
for ( int i7 = 0; i7 <= 2; i7++ )
{
/* I think the next 8 lines is what's not working! */
/* Write a series of cascaded stream insertion operations
to output a set of seven letters to outFile, followed by a space */
outFile
<< phoneLetters[n[0]][i1]
<< phoneLetters[n[1]][i2]
<< phoneLetters[n[2]][i3]
<< phoneLetters[n[3]][i4]
<< phoneLetters[n[4]][i5]
<< phoneLetters[n[5]][i6]
<< phoneLetters[n[6]][i7]
<< " ";
if ( ++count % 9 == 0 ) // form rows
outFile << '\n';
}
}
}
}
}
}
}
//alert user that wordGenerator has completed
cout << "Writing to file..." << endl;
// output phone number
outFile << "\nPhone number is ";
for ( int i = 0; i < 7; i++ )
{
if ( i == 3 )
outFile << '-';
outFile << n[ i ];
} // end for
//print results to screen
cout << count / 9 << " words were created from" << endl;
//close output file
outFile.close();
} // end function wordGenerator
Program runs fine. No errors, except nothing is written to the output file phone.dat
I'm so embarrassed to write this. It turns out that the code has been working all along. The output file is saved into /Users/userName/Library/Developer/Xcode/DerivedData and after running the program that directory disappears.
So in order to combat this you must go to XCode's Preferences, click on "Locations" and change the setting for "Derived Data" from "default" to "relative".
I hope this helps someone else in the future...