0

I'm trying to make three dynamic arrays whose indexes are determined by the number of lines in a text file. I then need to make their index values modifiable. I was thinking that global arrays would be my best bet.

For some reason I keep receiving the following compiler error: secondLab.obj : error LNK2019: unresolved external symbol "void __cdecl arrayInput(...)

Question, how do I fix this and basically meet the goal of my program.

Here's my code:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <new>

using namespace std;

int INDEXES = 0;

string *names_Array = new string[INDEXES];
double *rates_Array = new double[INDEXES];
double *hours_Array = new double[INDEXES];

void subscript(ifstream&, int&, string&, double&, double&);
void arrayInput(istream&, string [], double [], double[],
     string&, double&, double&);

int main ()
{
    string names;
    double rates;
    double hours;

    string filename("employee sample file.txt");
    ifstream employeeInfo(filename.c_str());

    if (employeeInfo.fail())
    {
        cout << "Sorry, file was not successfully opened. "
             << "Please make sure your file exists and\n" 
             << "re-run the program." << endl;
    }   

    subscript(employeeInfo, INDEXES, names, rates, hours);

    arrayInput(employeeInfo, names_Array, rates_Array, hours_Array,
    names, rates, hours);

    cout << names_Array[0] << endl
         << names_Array[1] << endl
         << names_Array[2] << endl
         << names_Array[3] << endl
         << names_Array[4] << endl;

    delete[] names_Array;
    delete[] rates_Array;
    delete[] hours_Array;

    system("pause");
    return 0;
}

void subscript(ifstream& employeeInfo, int& INDEXES,
    string& names, double& rates, double& hours)
{
    while(!employeeInfo.eof())
    {   
        employeeInfo >> names >> rates >> hours;

        INDEXES++;
    }
}

void arrayInput(ifstream& employeeInfo, string names_Array[], 
    double rates_Array[], double hours_Array[], string& names, double& rates, double& hours)
{
    int i = 0;

    while(!employeeInfo.eof())
    {
        employeeInfo >> names >> rates >> hours;

        names_Array[i] = names;
        rates_Array[i] = rates;
        hours_Array[i] = hours;

        i++;
    }
}
Eric after dark
  • 1,698
  • 3
  • 28
  • 75
  • 2
    "I was thinking that global arrays would be my best bet. " I disagree. [std::vector](http://en.cppreference.com/w/cpp/container/vector) would be your best bet. – jrok Nov 23 '12 at 20:33
  • You might like to know that you can split a string across multiple lines just by doing `"foo bar" "baz"`. Adjacent string literals are concatenated. – Joseph Mansfield Nov 23 '12 at 20:35
  • So you're saying if I use a vector class I won't have this problem? – Eric after dark Nov 23 '12 at 20:39
  • The error you're getting is something completely unrelated - the forward declaration of `arrayInput` says that the first argument is of type `istream&`, but in the definiton you wrote `ifstream&`. Pick one. – jrok Nov 23 '12 at 20:42
  • @jrok that is the cause of his error. The compiler calls the `istream` version which has no definition so linking fails. – David Brown Nov 23 '12 at 20:44
  • @DavidBroewn Yes. I meant to say that the error he's getting is completely unrelated to the choice between `new`/`std::vector`. – jrok Nov 23 '12 at 20:46

3 Answers3

2

The declaration and definition of arrayInput do not match, specifically one takes an ifstream paramater and the other takes an istream. Change

void arrayInput(istream&, string [], double [], double[],
 string&, double&, double&);

to

void arrayInput(ifstream&, string [], double [], double[],
 string&, double&, double&);
David Brown
  • 12,466
  • 3
  • 36
  • 53
1

u can count the numbers of lines at first .. then initiate the arrays .. and filling data to arrays..

 subscript(employeeInfo, INDEXES, names, rates, hours);
 names_Array = new string[INDEXES];
 rates_Array = new double[INDEXES];
 hours_Array = new double[INDEXES];
 arrayInput(employeeInfo, names_Array, rates_Array, hours_Array,names, rates, hours);

try like this ..

IbrahimAsad
  • 506
  • 1
  • 5
  • 16
1

Your question about the linkage error is already answered in comments by @jrok. Yet, the subject of your question is "How to let the indexes of an dynamic array be determined by lines in a file", and you seem to have done this by traversing the file twice. This not "best" solution by any means, and not even possible for some streams (e.g. terminal input).

std::vector is not only "your best bet" (as @jrok indicated) but also is the better solution for the question of the title. In fact, the whole code is a few lines, without the ugly global "dynamic" arrays. (not to mention your implementation is wrong, as these arrays are never allocated to INDEXES>0), cleaner, and faster (single traversal):

#include <vector>
#include <fstream>

int main () {
   using namespace std;
   vector<string> names;
   vector<double> rates;
   vector<double> hours;

   ifstream file("employee sample file.txt");

   while( !file.eof() ) {
      string name;
      double rate, hour;
      file >> name >> rate >> hour >> ws;
      names.push_back(name);
      rates.push_back(rate);
      hours.push_back(hour);
   }
}

Notes:

  • push_back() is amortized constant time. So, don't worry about efficiency
  • std::ws is so that any trailing empty space (such as trailing lines in the file) are skipped, before iteration begins.
  • no messing around with delete[], new all that junk.

hth

sly
  • 1,608
  • 1
  • 10
  • 13
  • Please read this: [Why is iostream::eof inside a loop condition considered wrong?](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – jrok Nov 23 '12 at 21:11
  • I don't see how or why this is authoritative. Granted, `file.fail()` check right before `push_back()` is missing in the above snippet -- which is besides the point and missing in the original question anyway -- Otherwise there is absolutely nothing wrong with using while(!file.eof()). – sly Nov 23 '12 at 21:26
  • ... also note the use of `std::ws`, which avoids failure in the case where trailing blank lines are acceptable input. – sly Nov 23 '12 at 21:27