Finding a vertical word from a .txt file in C++ - 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.

Related

C++ code - problems with сode execution time

there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}

Writing a Hash Table to File and Restoring From File in C++

I am working on an assignment for school using hash tables in a structure program. Part of the assignment is writing a hash table composed of 20 primary buckets and 10 overflow buckets, each with 3 slots composed of a key and data field to disk and then restoring from it. Here is what I have so far:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <string.h> // for strcpy()
using namespace std;
typedef char STR10[10+1];
typedef char STR20[20+1];
struct SLOT
{
STR10 key;
STR20 data;
};
struct BUCKET
{
SLOT entry[3];
int count;
BUCKET* overflow;
};
struct HASHTABLE
{
BUCKET pBkt[20];
BUCKET oBkt[10];
};
void WriteHTtoDisk (HASHTABLE ht, char *HashDisk);
void ReportHT (HASHTABLE ht, char * when);
int main()
{
int maxP = 20;
int maxO = 10;
int maxS = 3;
HASHTABLE ht;
STR10 mKey;
STR20 mData;
FILE * inFile;
inFile = fopen("DATAIN.dat","rb");
if (inFile == NULL)
{
cout << " DATAIN file access error ... \n";
cout << " Terminating application ... \n ";
cout << " Press any key ... \n ";
return -100;
}
char crLF;
while (!feof(inFile))
{
fscanf(inFile,"%10c%20c\n",mKey,mData);
mKey[10] = mData[20] = 0; // add string terminators
printf(" MyKey: %10s\n MyData: %20s\n",mKey,mData);
cin.ignore(80,'\n'), cin.get();
//InsertIntoHT (ht, mKey, mData);
}
fclose(inFile);
WriteHTtoDisk(ht, "hashTable.dat");
ReportHT (ht,"BEFORE");
return 0;
}
void WriteHTtoDisk (HASHTABLE ht, char *HashDisk)
{
FILE * HASHDISK = fopen(HashDisk, "rb");
int maxBkt = 30;
int maxSlot = 3;
for (int i = 0; i < maxBkt; i++)
{
for (int j = 0; j < maxSlot; j++)
{
fwrite(ht.pBkt[i].entry[j].key,11,sizeof(maxSlot),HASHDISK);
fwrite(ht.pBkt[i].entry[j].data,21,sizeof(maxSlot),HASHDISK);
}
}
}
void ReportHT (HASHTABLE ht, char * when)
{
int maxB = 30;
int maxS = 3;
cout << "Hash Table \n" << "Verification Report \n" << when << " Restoration" << endl;
for (int b = 0; b < maxB; b++)
{
cout << "Bucket " << (b+1) << endl;
if (b < 20)
{
for (int i = 0; i < maxS; i++)
{
cout << setw(3) << "Slot " << (i+1) << ": " << ht.pBkt[b].entry[i].key << setw(3) << ht.pBkt[b].entry[i].data << endl;
}
}
else
{
for (int i = 0; i < maxS; i++)
{
cout << setw(3) << "Slot " << (i+1) << ": " << ht.oBkt[b].entry[i].key << setw(3) << ht.oBkt[b].entry[i].data << endl;
}
}
}
}
The code compiles with no problems, but when I inspect the file, I find that it is all just gibberish and weird symbols. The data I am using was previously extracted from another file and I want to save it in the format in which it was inserted. I am sure the issue is with the lines with fwrite (I am not that experienced with C syntax as I am with C++).
The data was in the DATAIN.dat file like this:
TATUNG CO.EL PR. LONG BEACH CA
KAMERMAN LCIRRUS BEAVERTON, OR
QUADRAM COLOACH AV NORCROSS GE
AST RESEARALTON AV IRVINE CA
I am expecting the new file to look like this:
TATUNG CO.
EL PR. LONG BEACH CA
KAMERMAN L
CIRRUS BEAVERTON, OR
QUADRAM CO
LOACH AV NORCROSS GE
AST RESEAR
ALTON AV IRVINE CA
Any help would be greatly appreciated. Thank you.
It looks like your code doesn't initialize or even use the member count. When a hash bucket is empty, the count should indicate it. In C++ it's easy to implement: just add = 0 to its definition:
struct BUCKET
{
SLOT entry[3];
int count = 0;
BUCKET* overflow;
};
Also, when writing the bucket's data to a file, use the count and don't assume that all the entries in the bucket are filled.
for (int j = 0; j < ht.pBkt[i].count; j++)
...
Also, write only the required number of bytes. fwrite accepts two parameters: the size of the data elements to write and their number. Here, the size is 11 or 21, and the number is 1, because each fwrite call can only write one string to your file.
fwrite(ht.pBkt[i].entry[j].key,11,1,HASHDISK);
fwrite(ht.pBkt[i].entry[j].data,21,1,HASHDISK);
By the way, since you have a STR10 type, you can avoid magic numbers and write sizeof(STR10) instead of 11. This way, when you change the length of your string, your code will still work.

Issues with strings and char arrays in C++

I'm writing a registry generator as a part of a bigger program. I'm very new in C++, but good at other programming languages like PHP.
I'll start by providing the code of the problematic function:
void generacionAleatoria() {
string r_marca, r_nom, r_apellido;
char r_patente[6];
int num_rand;
registroAuto r_auto;
string nombres[8] = {
"Juan", "Pedro", "Roberto", "Miguel", "Guillermo", "Emilio", "Roque", "Gustavo"
} ;
string apellidos[8] = {
"Messi", "Maradona", "Gardel", "Heredia", "Pimpinela", "Nadal", "Mascherano", "Troilo"
};
string marcas[12] = {
"Volvo", "Renault", "Audi", "Ford", "Fiat", "Chevrolet", "Nissan", "Volkswagen", "Mercedes Benz", "Rolls Royce", "Delorean", "Aston Martin"
};
char letras_patentes[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char numeros_patentes[] = "0123456789";
for (int i = 0; i < cantidad_autos; i++) {
r_marca = marcas[rand() % (sizeof(marcas)/sizeof(marcas[0]) - 1)];
r_nom = nombres[rand() % (sizeof(nombres)/sizeof(nombres[0]) - 1)];
r_apellido = apellidos[rand() % (sizeof(apellidos)/sizeof(apellidos[0]) - 1)];
for(int m = 0; m < 3; ++m) {
r_patente[m] = letras_patentes[rand() % (sizeof(letras_patentes) - 1)];
}
for(int n = 3; n < 6; n++) {
r_patente[n] = numeros_patentes[rand() % (sizeof(numeros_patentes) - 1)];
}
strcpy(r_auto.patente,r_patente);
strcpy(r_auto.marca,r_marca.c_str());
strcpy(r_auto.apellido,r_apellido.c_str());
strcpy(r_auto.nom,r_nom.c_str());
fwrite(&r_auto,sizeof(registroAuto),1,archivo);
if (ver_variables_testeo) {
//cout << (i+1) << ") " << r_auto.patente<<endl;
cout << (i+1) << ") " << r_auto.marca << " - " << r_auto.patente << " - " << r_auto.nom << " " << r_auto.apellido << endl; //Para testear
}
}
}
This creates 100 structs of the following type:
struct registroAuto {
char marca[15];
char patente[6];
char nom[25];
char apellido[25];
};
In case you're wondering, this is meant to be a registry of Uber drivers and their cars: brand, license plate, name and surname. Well, it's not really a registry, it's college homework.
The problem is that when I print out the contents of my new struct, the license plate and the name will be together, as in:
100) Fiat - KWQ293Maria - Maria Gardel
You can see by the position of the hyphens, that the license plate is now "KWQ293Maria", even though it is an array of 6 chars!
A reminder of the cout command:
cout << (i+1) << ") " << r_auto.marca << " - " << r_auto.patente << " - " << r_auto.nom << " " << r_auto.apellido << endl;
I did some tests, but I don't know what to do with the results.
1: commenting out the strcopy of the name fixes the issue
strcpy(r_auto.patente,r_patente);
strcpy(r_auto.marca,r_marca.c_str());
strcpy(r_auto.apellido,r_apellido.c_str());
//strcpy(r_auto.nom,r_nom.c_str());
As you can see, this is the last of the 4 statements in my original code, so I don't know why it would affect r_auto.patente.
Can you please help me? I'm guessing there's a key concept of char array handling that I missed out on in class :-(
When using character arrays as strings they need to be terminated by a null character '\0'. So when you construct your number-plate you need to make the array 7 characters long.
struct registroAuto {
char marca[15];
char patente[7]; // 6 for numbers, 1 for terminator '\0'
char nom[25];
char apellido[25];
};
Same with your working variable:
char r_patente[7];
And you need to manually add the null-terminator when you create the number:
for(int m = 0; m < 3; ++m) {
r_patente[m] = letras_patentes[rand() % (sizeof(letras_patentes) - 1)];
}
for(int n = 3; n < 6; n++) {
r_patente[n] = numeros_patentes[rand() % (sizeof(numeros_patentes) - 1)];
}
r_patente[6] = '\0'; // add the null terminator

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...