【问题标题】:C++: How to let the indexes of an dynamic array be determined by lines in a fileC++:如何让动态数组的索引由文件中的行确定
【发布时间】:2012-11-12 04:34:16
【问题描述】:

我正在尝试创建三个动态数组,其索引由文本文件中的行数决定。然后我需要修改它们的索引值。我在想全局数组将是我最好的选择。

由于某种原因,我不断收到以下编译器错误: secondLab.obj:错误 LNK2019:无法解析的外部符号“void __cdecl arrayInput(...)

问题,我该如何解决这个问题并基本达到我的程序目标。

这是我的代码:

#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++;
    }
}

【问题讨论】:

  • “我认为全局数组是我最好的选择。”我不同意。 std::vector 是你最好的选择。
  • 您可能想知道您可以通过执行"foo bar" &lt;newline here&gt; "baz" 将字符串拆分为多行。相邻的字符串文字被连接起来。
  • 所以你是说如果我使用矢量类就不会出现这个问题?
  • 你得到的错误是完全不相关的——arrayInput 的前向声明说第一个参数的类型是istream&amp;,但是在你写的定义中ifstream&amp;。选择一个。
  • @jrok 这是他错误的原因。编译器调用没有定义的istream版本,所以链接失败。

标签: c++ arrays dynamic io


【解决方案1】:

arrayInput 的声明和定义不匹配,具体而言,一个采用ifstream 参数,另一个采用istream。改变

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

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

【讨论】:

    【解决方案2】:

    你可以先计算行数..然后启动数组..并将数据填充到数组..

     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);
    

    像这样尝试..

    【讨论】:

    • 我还应该将数组声明保留在 main 上方吗?
    • 字符串 *names_Array ;双 *rates_Array ;双 *hours_Array; // 仅
    • 非常感谢!唯一的问题是,现在当我运行我的程序时,我应该写入 names_Array 索引的值没有打印到控制台....
    【解决方案3】:

    @jrok 已经在 cmets 中回答了您关于链接错误的问题。然而,您的问题的主题是“如何让动态数组的索引由文件中的行确定”,您似乎通过遍历文件两次来做到这一点。这无论如何都不是“最佳”解决方案,甚至对于某些流(例如终端输入)也是不可能的。

    std::vector 不仅是“你最好的选择”(正如@jrok 所指出的那样),而且是标题问题的更好解决方案。事实上,整个代码只有几行,没有丑陋的全局“动态”数组。 (更不用说你的实现是错误的,因为这些数组永远不会分配给INDEXES&gt;0),更干净,更快(单次遍历):

    #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);
       }
    }
    

    注意事项:

    • push_back() 是摊销的常数时间。所以,不用担心效率
    • std::ws 是为了在迭代开始之前跳过任何尾随空格(例如文件中的尾随行)。
    • 不要乱用delete[]new所有这些垃圾。

    【讨论】:

    • 我不明白这是如何或为什么是权威的。当然,@ 987654327@ 在上面的 sn-p 中缺少 push_back() 之前检查一下——这不是重点,而且无论如何在原始问题中都没有——否则使用 while(!file.eof( ))。
    • ... 还要注意std::ws 的使用,这样可以避免在尾随空白行是可接受的输入的情况下失败。
    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多