搜索文本文件中的名称和 ID 对,尝试/捕获异常

问题描述 投票:0回答:3

我没有看到这个问题已经发布,或任何有用的类似内容。

我正在上第二学期的 C++ 课程,只通过了 10 个测试点中的 5 个。我可以看出我的 try/catch 设置有问题。在互联网上搜索之后,我可能对我遇到的错误更加困惑:

main.cpp: In function ‘std::string FindID(std::string, std::ifstream&)’:
main.cpp:24:1: warning: control reaches end of non-void function [-Wreturn-type]
   24 | }
      | ^
main.cpp: In function ‘std::string FindName(std::string, std::ifstream&)’:
main.cpp:49:1: warning: control reaches end of non-void function [-Wreturn-type]
   49 | }
      | ^

问题和我的代码如下:


6.9 LAB:未找到学生信息

给定一个在文本文件中搜索学生 ID 或姓名的程序,请完成

FindID()
FindName()
函数。然后,在
main()
中插入try/catch语句来捕获
FindID()
FindName()
抛出的任何异常,并输出异常消息。文本文件中的每一行都包含一个名称和 ID,以空格分隔。

函数

FindID()
有两个参数:学生姓名(字符串)和文本文件的内容(ifstream)。如果学生姓名在文件中,则函数
FindID()
返回与学生姓名关联的 ID,否则,函数抛出
runtime_error
并显示消息“未找到 StudentName 的学生 ID”,其中 StudentName 是学生的姓名.

函数

FindName()
有两个参数:学生的ID(字符串)和文本文件的内容(ifstream)。如果 ID 在文件中,则函数 FindName() 返回与学生 ID 关联的名称,否则,函数会抛出运行时错误,并显示消息“未找到学生 ID 的学生姓名”,其中 StudentID 是学生的 ID。

主程序接受用户的三个输入:文本文件的名称(字符串)、用于查找学生的 ID 或姓名的搜索选项(int)以及学生的 ID 或姓名(字符串)。如果搜索选项为 0,则以学生姓名作为参数调用 FindID()。如果搜索选项为 1,则以学生 ID 作为参数调用 FindName()。主程序输出搜索结果或捕获的异常消息。

例如:如果程序的输入是:

roster.txt 0 Reagan

roster.txt的内容是:

Reagan rebradshaw835
Ryley rbarber894
Peyton pstott885
Tyrese tmayo945
Caius ccharlton329

程序的输出是:

rebradshaw835

例如:如果程序的输入是:

roster.txt 0 Mcauley

程序输出异常信息:

Student ID not found for Mcauley

例如:如果程序的输入是:

roster.txt 1 rebradshaw835

程序的输出是:

Reagan

例如:如果程序的输入是:

roster.txt 1 mpreston272

程序输出异常信息:

Student name not found for mpreston272

我的main.cpp代码:

#include <string>
#include <iostream>
#include <stdexcept>
#include <fstream>
using namespace std;

string FindID(string name, ifstream &infoFS) {
   bool foundID = false;
   string input;
   infoFS >> input;
   while (infoFS) 
   {
      if (input == name)
      {
         infoFS >> input;
         return input;
      }
      else { infoFS >> input; }
   }
   if (foundID == false)  
   {
      throw name;
   }   
}

string FindName(string ID, ifstream &infoFS) {
   bool foundName = false;
   string previous;
   string input;
   infoFS >> previous;
   infoFS >> input;
   while (infoFS) 
   {
      if (input == ID)
      {
         foundName = true;
         return previous;         
      }
      else 
      { 
         previous = input;
         infoFS >> input; 
      }
   }
   if (foundName == false) 
   {
      throw ID;
   }   
}

int main() {
   int userChoice;
   string studentName;
   string studentID;
   string studentInfoFileName;
   ifstream studentInfoFS;
   
   // Read the text file name from user
   cin >> studentInfoFileName;
   
   // Open the text file
   studentInfoFS.open(studentInfoFileName);
   
   // Read search option from user. 0: FindID(), 1: FindName()
   cin >> userChoice;

   try 
   {
      if (userChoice == 0) {
         cin >> studentName;
         studentID = FindID(studentName, studentInfoFS);
         cout << studentID << endl;
      }
      else {
         cin >> studentID;
         studentName = FindName(studentID, studentInfoFS);
         cout << studentName << endl;
      }
   }
   catch (string name)
   {
      if (userChoice == 0) {
         cout << "Student ID not found for " << name << endl;
      }
   }  
   catch (char ID)
   {
      cout << "Student name not found for " << ID << endl;
   }
    
   studentInfoFS.close();
   return 0;
}

提交时编译器警告:

main.cpp: In function ‘std::string FindID(std::string, std::ifstream&)’:
main.cpp:24:1: warning: control reaches end of non-void function [-Wreturn-type]
   24 | }
      | ^
main.cpp: In function ‘std::string FindName(std::string, std::ifstream&)’:
main.cpp:49:1: warning: control reaches end of non-void function [-Wreturn-type]
   49 | }
      | ^

通过测试:

1: Compare output

    Input
    roster.txt 0 Reagan
    Your output
    rebradshaw835

2: Compare output

    Input
    roster.txt 0 Mcauley
    Your output
    Student ID not found for Mcauley

3: Compare output

    Input
    roster.txt 1 rebradshaw835
    Your output
    Reagan
7: Unit test

    Test FindName("mpreston272", infoFS) with roster1.txt, should return Mcauley
    Your output
    FindName("mpreston272", infoFS) correctly returned Mcauley

8: Unit test

    Test FindID("Mcauley", infoFS) with roster1.txt, should return mpreston272
    Your output
    FindID("Mcauley", infoFS) correctly returned mpreston272

失败的测试:

4: Compare output

    Input
    roster.txt 1 mpreston272
    Your output
    Your program produced no output
    Expected output
    Student name not found for mpreston272

5: Unit test

    Test FindID("John", infoFS) with roster1.txt, should throw an exception
    Returned unexpected error code (-6)

6: Unit test

    Test FindName("jsmith474", infoFS) with roster1.txt, should throw an exception
    Returned unexpected error code (-6)
c++ exception try-catch ifstream
3个回答
0
投票

我终于让它工作并通过了所有 10 项测试。感谢@WBuck 的评论,让我更仔细地研究了 try/catch 语法:“不要抛出 std::string,而是抛出 std::runtime_error。然后,将异常处理程序更改为:catch ( const std: :异常&错误) – WBuck”

我发现这篇文章很有帮助:如何抛出 C++ 异常

以及 cpp 参考站点:https://en.cppreference.com/w/cpp/language/function-try-block

我试图传递通用错误字符串,然后在 catch 语句中添加变量名称/ID 输入,但除非传递变量,否则这不起作用。因此,我必须使用默认消息 + 输入变量创建一个新字符串,然后将其作为一个字符串传递到引发的运行时错误中。

编译器内置于 ZyBooks 的网站中,并且没有说明它使用的 C++ 版本。

这是通过所有测试的代码,以防其他人遇到类似的问题。

#include <string>
#include <iostream>
#include <stdexcept>
#include <fstream>
using namespace std;

string FindID(string name, ifstream &infoFS) {
   bool foundID = false;
   string input;
   infoFS >> input;
   while (infoFS) 
   {
      if (input == name)
      {
         foundID = true;
         infoFS >> input;
         return input;
         break;
      }
      else { infoFS >> input; }
   }
   if (foundID == false)  
   {
      string NoNameMsg = "Student ID not found for " + name;
      throw runtime_error(NoNameMsg);
   }   
   return "";
}

string FindName(string ID, ifstream &infoFS) {
   bool foundName = false;
   string previous;
   string input;
   infoFS >> previous;
   infoFS >> input;
   while (infoFS) 
   {
      if (input == ID)
      {
         foundName = true;
         return previous;
         break;
      }
      else 
      { 
         previous = input;
         infoFS >> input; 
      }
   }
   if (foundName == false) 
   {
      string NoIDMsg = "Student name not found for " + ID;
      throw std::runtime_error(NoIDMsg);
   }  
   return "";
}

int main() {
   int userChoice;
   string studentName;
   string studentID;
   string studentInfoFileName;
   ifstream studentInfoFS;
   
   // Read the text file name from user
   cin >> studentInfoFileName;
   
   // Open the text file
   studentInfoFS.open(studentInfoFileName);
   
   // Read search option from user. 0: FindID(), 1: FindName()
   cin >> userChoice;

   try 
   {
      if (userChoice == 0) {
         cin >> studentName;
         studentID = FindID(studentName, studentInfoFS);
         cout << studentID << endl;
      }
      else {
         cin >> studentID;
         studentName = FindName(studentID, studentInfoFS);
         cout << studentName << endl;
      }
   }
   catch ( const std::runtime_error& e )
   {
      cout << e.what() << endl;
   } 
         
   studentInfoFS.close();
   return 0;
}

0
投票

以下是 Python 中该问题的解决方案:

# Define custom exception
class StudentInfoError(Exception):
    def __init__(self, message):
        self.message = message  # Initialize the exception message


def find_ID(name, info):
    # Type your code here.
    if name not in info.keys():
        raise StudentInfoError('Student ID not found for {}'.format(name))
    the_id = info[name]
    return the_id
    
def find_name(ID, info):
    # Type your code here.
    if ID not in info.values():
        raise StudentInfoError('Student name not found for {}'.format(ID))
    the_name = list(info.keys())[list(info.values()).index(ID)]
    return the_name

if __name__ == '__main__':
    # Dictionary of student names and IDs
    student_info = {
        'Reagan' : 'rebradshaw835',
        'Ryley' : 'rbarber894',
        'Peyton' : 'pstott885',
        'Tyrese' : 'tmayo945',
        'Caius' : 'ccharlton329'
    }
    
    userChoice = input()    # Read search option from user. 0: find_ID(), 1: find_name()
    
    # FIXME: find_ID() and find_name() may throw an Exception.
    #        Insert a try/except statement to catch the exception and output any exception message.
    if userChoice == "0":
        try:
            name = input()
            result = find_ID(name, student_info)
            print(result)
        except StudentInfoError as e:
            print(e)
        
    else:
        try:
            ID = input()
            result = find_name(ID, student_info)
            print(result)
        except StudentInfoError as e:
            print(e)

0
投票

发现对我的 Python 课程非常有帮助。谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.