C++ splitStringOutInt函数丢失首字符问题及转vector方法咨询
问题分析与解决方案
我写了一段C++代码(CP Code为模板代码),遇到两个问题:
splitStringOutInt函数丢失第一个字符,输入11 12 13时输出[1, 12, 13];- 作为C++初学者,想了解将整行字符串输入转为数组/vector的更优方法。
原代码如下:
// START CP CODE #include <sstream> #include <iostream> #include <vector> #include <string> using namespace std; string cinLine() { cin.ignore(); string tempVar {}; getline(cin, tempVar); return tempVar; } long long int stringToInt(string num) { long long int convertedVal = 0; stringstream strConverterOBJ; strConverterOBJ << num; strConverterOBJ >> convertedVal; return convertedVal; } int printIntVector(vector<long long int> lst) { cout << "["; for(int i=0; i<lst.size(); i++){ if(i!=lst.size()-1) { cout << lst.at(i) << ", "; }else{ cout << lst.at(i); } } cout << "]" << endl; return 0; } string printStrVector(vector<string> lst) { for(int i=0; i<lst.size(); i++){ if(i!=lst.size()-1) { cout << lst.at(i) << endl; }else{ cout << lst.at(i); } } return ""; } vector<long long int> splitStringOutInt(char divider, string str) { vector<long long int> intList; for(long long int j=0; j<=str.length(); j++){ long long int answer {}; if(str[j] == divider || j == str.length()){ answer = stringToInt(str.substr(0, j+1)); str.erase(0,j+1); intList.insert(intList.end(), answer); j=0; } } return intList; } // END CP CODE int main() { vector<long long int> inp1; inp1 = splitStringOutInt(' ', cinLine()); printIntVector(inp1); return 0; }
问题原因
cinLine函数误删首字符
cinLine中的cin.ignore()是多余的:程序启动后输入缓冲区无残留换行符,该语句会直接读取并丢弃输入的第一个字符。比如输入11 12 13时,getline实际获取到的是1 12 13,最终split结果自然丢失了第一个1。splitStringOutInt函数逻辑缺陷
- 用
str.substr(0, j+1)会包含分隔符(或超出字符串长度),虽然转int时空格会被忽略,但逻辑上错误,正确应该取0到j的前j个字符(不包含分隔符); - 每次修改原字符串并重置索引
j的做法效率低,且用long long作为索引没必要,size_t更匹配字符串长度的类型。
修复与优化方案
1. 修复原代码
修复cinLine函数
去掉多余的cin.ignore():
string cinLine() { string tempVar {}; getline(cin, tempVar); return tempVar; }
修复splitStringOutInt函数
优化索引逻辑,使用stoll直接转换字符串:
vector<long long int> splitStringOutInt(char divider, string str) { vector<long long int> intList; size_t start = 0; for (size_t j = 0; j <= str.length(); ++j) { if (j == str.length() || str[j] == divider) { string numStr = str.substr(start, j - start); if (!numStr.empty()) { // 处理连续分隔符的情况 intList.push_back(stoll(numStr)); } start = j + 1; } } return intList; }
2. 更优实现方法
利用C++标准库的stringstream可以自动处理空格分隔,代码更简洁高效,无需手动实现split:
#include <sstream> #include <iostream> #include <vector> #include <string> using namespace std; vector<long long int> readIntsFromLine() { vector<long long int> intList; string line; getline(cin, line); stringstream ss(line); long long int num; // 自动跳过空白字符,读取所有整数 while (ss >> num) { intList.push_back(num); } return intList; } int printIntVector(vector<long long int> lst) { cout << "["; for(size_t i=0; i<lst.size(); i++){ if(i != lst.size()-1) { cout << lst.at(i) << ", "; }else{ cout << lst.at(i); } } cout << "]" << endl; return 0; } int main() { vector<long long int> inp1 = readIntsFromLine(); printIntVector(inp1); return 0; }
说明:
stringstream会自动跳过所有空白字符(空格、换行、制表符等),无需手动处理分隔符;stoll是标准库函数,直接将字符串转为long long,无需自己实现转换逻辑;- 代码逻辑清晰,避免了手动操作字符串和索引的潜在错误。
内容的提问来源于stack exchange,提问作者user19474938
相关产品推荐
相关产品推荐

