You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac终端g++编译C++待办列表程序遇两处运行错误求助

C++待办列表程序错误修复方案

问题根源分析

1. 删除任务偶发报错、第二次添加任务报错的核心原因

函数参数使用了值传递,比如addToDoItems和deleteToDoItems的参数定义为vector<string>(toDoList),这意味着函数内部操作的是原vector的副本,而非原数据本身:

  • 删除任务时,副本的任务数量和原vector不一致,若用户输入的任务编号超出副本的有效范围,会触发out_of_range异常导致报错;
  • 第二次添加任务时,函数修改的是副本,原vector数据完全没更新,后续操作基于无效的副本数据,必然引发错误。

2. 第二次添加任务报错的额外诱因

cin >> userInput执行后,输入缓冲区会残留换行符,后续调用getline(cin, userInput)时会直接读取这个空行,导致userInput为空字符串,执行userInput.at(0)时触发越界异常。

具体修复步骤

  1. 将函数参数改为引用传递
    把所有函数声明和定义的参数从vector<string>(toDoList)改为vector<string>& toDoList,让函数直接操作原vector:
void addToDoItems(vector<string>& toDoList);
void deleteToDoItems(vector<string>& toDoList);
  1. 处理输入缓冲区残留的换行符
    在每次使用cin >>之后,添加代码清除缓冲区的换行符,需先包含<limits>头文件:
#include <limits>

示例:在addToDoItems中cin >> userInput之后添加:

cin.ignore(numeric_limits<streamsize>::max(), '\n');
  1. 添加输入验证,防止删除任务时越界
    在删除任务的循环中,先检查用户输入的任务编号是否在有效范围(1到当前列表任务数),无效则提示重新输入:
while (taskNumToDelete != -1) {
    if (taskNumToDelete < 1 || taskNumToDelete > toDoList.size()) {
        cout << "无效的任务编号,请输入1到" << toDoList.size() << "之间的数字,或输入-1退出:";
        cin >> taskNumToDelete;
        cout << endl;
        continue;
    }
    toDoList.erase(toDoList.begin() + taskNumToDelete - 1);
    cout << "请输入下一个已完成任务的编号(输入-1查看剩余任务):";
    cin >> taskNumToDelete;
    cout << endl;
}

修改后的完整代码

#include <iostream>
#include <vector>
#include <string>
#include <limits>
using namespace std;

void addToDoItems(vector<string>& toDoList);
void deleteToDoItems(vector<string>& toDoList);

int main(){
   vector<string> toDoList;
   
   addToDoItems(toDoList);

   return 0;
} 

void addToDoItems(vector<string>& toDoList) {
   int count = toDoList.size() + 1;
   char capitalizeFirstLetter;
   string userInput;

   // 清除之前cin操作残留的换行符
   cin.ignore(numeric_limits<streamsize>::max(), '\n');

   cout << "\n请输入要添加的任务:";
   getline(cin, userInput);
   cout << endl;

   while (userInput != "q") {
      if (userInput.empty()) {
          cout << "任务不能为空,请重新输入,或输入q退出:";
          getline(cin, userInput);
          cout << endl;
          continue;
      }
      capitalizeFirstLetter = toupper(userInput.at(0));
      userInput.erase(0,1);
      userInput = to_string(count) + ". " + capitalizeFirstLetter + userInput;
      toDoList.push_back(userInput);
      cout << "添加另一个任务或按q完成添加:";
      getline(cin, userInput);
      cout << endl;
      ++count;
   }

   cout << "你今天需要完成的任务:\n" << endl;
   for (int i = 0; i < toDoList.size(); ++i) {
      cout << toDoList.at(i) << endl;
   }

   cout << "\n按d可以标记完成任务,按其他键退出:";
   cin >> userInput;
   cout << endl;

   if (userInput == "d") {
      deleteToDoItems(toDoList);
   } else {
      cout << "祝你愉快!\n" << endl;
   }
}

void deleteToDoItems(vector<string>& toDoList) {
   int taskNumToDelete;
   int count = 1;
   string tasksLeft;
   string userInput;

   cout << "请输入已完成任务的编号(参考上方列表):";
   cin >> taskNumToDelete;
   cout << endl;

   while (taskNumToDelete != -1) {
      if (taskNumToDelete < 1 || taskNumToDelete > toDoList.size()) {
          cout << "无效编号,请输入1到" << toDoList.size() << "之间的数字,或输入-1退出:";
          cin >> taskNumToDelete;
          cout << endl;
          continue;
      }
      toDoList.erase(toDoList.begin() + taskNumToDelete - 1);
      cout << "请输入下一个已完成任务的编号(输入-1查看剩余任务):";
      cin >> taskNumToDelete;
      cout << endl;
   }

   if (toDoList.size() > 0) {
      if (toDoList.size() == 1) {
         cout << "快完成了!你还有" << toDoList.size() << "个任务要做!\n" << endl;   
      } else {
         cout << "快完成了!你还有" << toDoList.size() << "个任务要做!\n" << endl;
      }

      for (int i = 0; i < toDoList.size(); ++i) {
         tasksLeft = toDoList.at(i);
         // 找到第一个点的位置,删除编号部分,避免多位数编号处理错误
         size_t dotPos = tasksLeft.find(".");
         if (dotPos != string::npos) {
             tasksLeft = tasksLeft.substr(dotPos + 2);
         }
         cout << count << ". " << tasksLeft << endl;
         // 更新vector中的编号,避免后续操作编号混乱
         toDoList[i] = to_string(count) + ". " + tasksLeft;
         ++count;
      }

      cout << endl;
      cout << "按d继续标记完成任务,按a添加新任务,按其他键退出:";
      cin >> userInput;
      cout << endl;

      if (userInput == "d") {
         deleteToDoItems(toDoList);
      } else if(userInput == "a") {
         addToDoItems(toDoList);
      } else {
         cout << "祝你愉快!\n" << endl;
      }
   } else {
      cout << "恭喜!你完成了所有任务,可以放松一下了:)\n" << endl;
   }
}

内容的提问来源于stack exchange,提问作者Nicholas Davies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:35:16