【问题标题】:Passing vectors by reference in C++ functions在 C++ 函数中通过引用传递向量
【发布时间】:2015-05-24 14:36:10
【问题描述】:

这里是 CS 大一学生。我目前正在尝试编写这个项目,这是一个使用向量的灵活待办事项列表。但是,我终其一生都无法弄清楚代码出了什么问题。

它应该从选项菜单功能中选择用户选择的功能,并继续要求用户将内容添加到列表中,除非他们另有选择。当用户选择“完成”选项 7 时,整个事情将结束,并且只有在验证 taskList 数组中没有剩余项目之后。

代码如下:

#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

void options()
{
  cout << "\nWhat to do?\n\n" << endl;

  cout << "1) Add to the list. \n";
  cout << "2) Show the next item on the list. \n";
  cout << "3) Do the next item on the list, and remove it. \n";
  cout << "4) List all items \n";
  cout << "5) Save list. \n";
  cout << "6) Load list. \n";
  cout << "7) All done with this To Do List! \n\n";
}

void addToList(vector<string>& vec) //add item to list
{
  string task;
  cout << "\nPlease add an item to the to-do list: ";

  getline(cin, task);
  vec.push_back(task);
} //addToList

void showNextItem(const vector<string>& vec) //display next item in list, do not remove it
{
  cout << "\nThe next item on the list is: ";
  cout << "==> " << vec.front();
} //showNext Item

void displayAllItems(const vector<string>& vec) //display all items in list
{
  cout << "\nHere's everything you still need to do: ";
  cout << "\n\n";

  for (unsigned int i = 0; i < vec.size(); i++)
  {
    cout << vec[i];
  } //for
} //displayAllItems

void doThis(vector<string>& vec) //display item, remove from list
{
  cout << "\nOK, time to do this list item: \n";
  cout << "==> " << vec.front();

  vec.erase(vec.begin());
} //doThis

void save(const vector<string>& vec) //asks user to input file name, saves all items to file
{
  string fileName;
  cout << "\nEnter file to save items: ";

  getline(cin, fileName);

  ofstream fout(fileName.c_str());
  fout.open(fileName);

  for(unsigned int i = 0; i < vec.size(); i++)
  {
    fout << vec[i];
  } //for

  fout.close();

} //save

void load(vector<string>& vec) //asks user to input file name, loads items         from file and populates to do list with items
{
  string fileName;
  string line;
  cout << "\nEnter file to load to-do list: ";

  getline(cin, fileName);
  ifstream fin(fileName.c_str());

  fin.open(fileName);

  while (fin.good())
  {
    getline(fin, line);
    vec.push_back(line);
  } //while

  fin.close();

} //load

bool allDone() //displays goodbye message, exits
{
    bool done = true;
    cout << "\nAll done!";
    return done;
} //all done

int main()
{
  int option;
  bool done = false;
  string userOption;
  stringstream mystr;
  vector<string> taskList;

    options();
    cout << "==> ";
    getline(cin, userOption);
    mystr << userOption;
    mystr >> option;

    switch(option)
    {
      case 1:
        addToList(taskList);
        break;
      case 2:
        showNextItem(taskList);
        break;
      case 3:
        doThis(taskList);
        break;
      case 4:
        displayAllItems(taskList);
        break;
      case 5:
        save(taskList);
        break;
      case 6:
        load(taskList);
        break;
      case 7:
        allDone();
        break;
    } //switch
} //main

提前感谢任何可以提供帮助的人!

【问题讨论】:

  • 什么地方不能正常工作,你希望它如何工作?
  • 你有什么问题?
  • @AtlasC1:我希望用户输入的选项(int 选项)能够选择其对应的功能。 1为addToList,2为showNextItem等。问题是当我运行代码时,无论选择哪个选项,都只执行第一个程序addToList。我还试图找出一种在 bool allDone 返回 true 时终止程序的方法,但前提是向量中没有更多项目。抱歉,如果到目前为止还不清楚,仍然刚刚开始学习。

标签: c++ vector pass-by-reference


【解决方案1】:

我也是这方面的新手,我为您的计划找到了一些建议。

您不能选择其他,因为您只运行一次 switch 部分。所以我认为您需要while 才能继续获得您的意见

  1. 我认为选择一次号码后问题不应该停止。所以我认为您可能需要whilefor 来选择您的部分。并在case 7 处添加return

    while(1)
    {
        options();
        cout << "==> ";
        getline(cin, userOption);
        option = atoi(userOption.c_str());
        switch(option)
        {
        case 1:
           addToList(taskList);
           break;
        case 2:
           showNextItem(taskList);
           break;
        case 3:
           doThis(taskList);
           break;
        case 4:
           displayAllItems(taskList);
           break;
        case 5:
           save(taskList);
           break;
        case 6:
           load(taskList);
           break;
        case 7:
           cout << "\nAll done!\n";
           return 0;
        default:
           return -1;
    }
    cout<<"\n========================"<<endl;
    

    }

  2. 当您保存数据时,您打开文件两次,我认为这就是您无法将数据写入文件的原因。当然,您需要添加一些运算符来分隔文件中的句子,以便下次可以从文件中获取。 问题也在于您的开放部分。您可以只使用ofstream fout(fileName.c_str(), ios::out); 而不使用open 打开文件。如果您使用while(fin.good()),您可以从文件中多读取一行。代码是:

    void save(const vecotr<string>& vec)
    {
        string fileName;
        cout <<"\nEnter file to save items: ";
        getline(cin, fileName);
        ofstream fout(fileName.c_str(), ios::out);
    
        for(unsigned int i = 0; i < vec.size(); i++)
        {
           fout <<vec[i] << "\n";
        }
        fout.close();
    } 
    
    void load(vector<string>& vec) 
    {
        string fileName;
        string line;
        cout << "\nEnter file to load to-do list: ";
    
       getline(cin, fileName);
       ifstream fin(fileName.c_str());
    
       while(getline(fin, line))
       {
           vec.push_back(line);
       } //while
       cout <<"======" <<vec.size()<<endl;
    
       fin.close();
    } 
    
  3. 两件小事是你可能需要测试输入的单词,在你的显示部分你可以添加 num 来帮助用户阅读。

    void displayAllItems(const vector<string>& vec)
    {
         cout << "\nHere's everything you still need to do: ";
         cout << "\n\n";
    
         for (unsigned int i = 0; i < vec.size(); i++)
         {
             cout << i <<"."<< vec[i] << endl;
         }
    }
    

【讨论】:

  • atoi 比 OP 的方法更糟糕,因为如果输入是超出INT_MAX 范围的整数,它会导致未定义的行为。 OP 的代码很好,只是他/她应该检查失败并采取行动
  • 是的,这只是基本功能,我认为0-7 atoi就足够了。并且为了程序的健壮性,我们需要检查用户输入的单词。我认为这是提问者需要做的。
【解决方案2】:
for(unsigned int i = 0; i < vec.size(); i++)
{
  fout << vec[i];
}

这会将字符串写入文件,但不会用空格分隔它们。

例如,如果向量包含{ "this", "is", "a test" },则循环后文件将包含thisisa test,而不是this is a testthis\nis\na test

当您尝试使用getline(fin, line) 读取文件的内容时,它只会向向量添加一个字符串,内容为"thisisa test"

要解决此问题,请在 fout &lt;&lt; vec[i] 之后向文件中添加一个换行符:

fout << vec[i] << '\n';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    相关资源
    最近更新 更多