字符串坐标提取场景下如何使用try-catch处理异常?
C++坐标字符串提取的异常处理方案
问题1:处理非预期分隔符的异常
当字符串中出现&这类替代预期的,或*的符号时,可在分割、格式校验逻辑中主动识别异常符号,抛出带提示的异常,再通过try-catch捕获输出对应信息。
实现逻辑
- 先清理字符串首尾的
(、)、;及多余空格 - 遍历字符串检查是否存在非预期符号,同时验证每个坐标段是否符合
数字 * SCALE的格式 - 发现异常符号时抛出包含错误提示的异常,在
catch块中输出具体问题
代码示例
#include <iostream> #include <string> #include <stdexcept> #include <algorithm> // 预处理字符串,去除首尾无关字符 std::string preprocess(const std::string& str) { size_t start = str.find_first_not_of("( "); size_t end = str.find_last_not_of("); "); if (start == std::string::npos || end == std::string::npos) { throw std::invalid_argument("无效的坐标格式"); } return str.substr(start, end - start + 1); } // 检查单个坐标段的格式是否合法 void check_segment_format(const std::string& segment) { size_t star_pos = segment.find('*'); if (star_pos == std::string::npos) { size_t wrong_pos = segment.find_first_not_of("0123456789 SCALE"); if (wrong_pos != std::string::npos) { char wrong_char = segment[wrong_pos]; throw std::invalid_argument("该行应使用'*'而非'" + std::string(1, wrong_char) + "'"); } throw std::invalid_argument("坐标段缺少'*'分隔符"); } } // 分割坐标段并检查逗号分隔是否合法 std::vector<std::string> split_segments(const std::string& processed_str) { std::vector<std::string> segments; size_t pos = 0; size_t next_pos; while ((next_pos = processed_str.find(',', pos)) != std::string::npos) { std::string seg = processed_str.substr(pos, next_pos - pos); seg.erase(std::remove_if(seg.begin(), seg.end(), isspace), seg.end()); segments.push_back(seg); pos = next_pos + 1; } std::string last_seg = processed_str.substr(pos); last_seg.erase(std::remove_if(last_seg.begin(), last_seg.end(), isspace), last_seg.end()); segments.push_back(last_seg); // 检查是否存在非逗号的分隔符 size_t wrong_sep_pos = processed_str.find_first_not_of("0123456789 * SCALE,"); if (wrong_sep_pos != std::string::npos) { char wrong_char = processed_str[wrong_sep_pos]; throw std::invalid_argument("该行应使用','而非'" + std::string(1, wrong_char) + "'"); } return segments; } int main() { // 错误输入示例1 std::string str1 = "(94 * SCALE & 10 * SCALE, 62 * SCALE, 10 * SCALE);"; try { std::string processed = preprocess(str1); std::vector<std::string> segments = split_segments(processed); for (const auto& seg : segments) { check_segment_format(seg); } } catch (const std::invalid_argument& e) { std::cout << e.what() << std::endl; // 输出:该行应使用','而非'&' } // 错误输入示例2 std::string str2 = "(94 & SCALE , 10 * SCALE, 62 * SCALE, 10 * SCALE);"; try { std::string processed = preprocess(str2); std::vector<std::string> segments = split_segments(processed); for (const auto& seg : segments) { check_segment_format(seg); } } catch (const std::invalid_argument& e) { std::cout << e.what() << std::endl; // 输出:该行应使用'*'而非'&' } return 0; }
问题2:处理字符串无法转换为整数的异常
stoi转换失败时会抛出std::invalid_argument(非数字格式)或std::out_of_range(数字超出整数范围)异常,直接捕获这些异常并输出对应提示即可。
实现逻辑
- 从坐标段中提取数字部分字符串
- 用
try包裹stoi转换操作 - 捕获转换异常,抛出带具体信息的提示
代码示例
#include <iostream> #include <string> #include <stdexcept> #include <algorithm> std::string preprocess(const std::string& str) { size_t start = str.find_first_not_of("( "); size_t end = str.find_last_not_of("); "); if (start == std::string::npos || end == std::string::npos) { throw std::invalid_argument("无效的坐标格式"); } return str.substr(start, end - start + 1); } std::vector<std::string> split_segments(const std::string& processed_str) { std::vector<std::string> segments; size_t pos = 0; size_t next_pos; while ((next_pos = processed_str.find(',', pos)) != std::string::npos) { std::string seg = processed_str.substr(pos, next_pos - pos); seg.erase(std::remove_if(seg.begin(), seg.end(), isspace), seg.end()); segments.push_back(seg); pos = next_pos + 1; } std::string last_seg = processed_str.substr(pos); last_seg.erase(std::remove_if(last_seg.begin(), last_seg.end(), isspace), last_seg.end()); segments.push_back(last_seg); return segments; } int extract_coordinate(const std::string& segment) { size_t star_pos = segment.find('*'); if (star_pos == std::string::npos) { throw std::invalid_argument("坐标段缺少'*'分隔符"); } std::string num_str = segment.substr(0, star_pos); num_str.erase(std::remove_if(num_str.begin(), num_str.end(), isspace), num_str.end()); try { return std::stoi(num_str); } catch (const std::invalid_argument& e) { throw std::invalid_argument("无法将'" + num_str + "'转换为整数"); } catch (const std::out_of_range& e) { throw std::invalid_argument("数字'" + num_str + "'超出整数范围"); } } int main() { // 错误输入示例:数字部分为非整数 std::string str = "(abc * SCALE, 10 * SCALE, 62 * SCALE, 10 * SCALE);"; try { std::string processed = preprocess(str); std::vector<std::string> segments = split_segments(processed); for (const auto& seg : segments) { int coord = extract_coordinate(seg); std::cout << "提取的坐标值:" << coord << std::endl; } } catch (const std::invalid_argument& e) { std::cout << e.what() << std::endl; // 输出:无法将'abc'转换为整数 } return 0; }
内容的提问来源于stack exchange,提问作者tushar
相关产品推荐
相关产品推荐

