使用 C++ 读取带有两个连续分隔符的 csv 文件
Read a csv file with two consecutive delimiters using C++
我正在尝试从 CSV 文件生成数独网格。
我制作的代码适用于这种文件:
1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8,9
...
但是我需要它来用这种文件创建网格:
; ; 5; ;;1; ;;1
3; ; ;;;;6; ;
;7;;;;2;;;4
;;1;3;;5;;8;
...
这是我的代码:
int grid[9][9];
ifstream inputFile;
inputFile.open(inputFileName);
for (int row = 0; row <9 ; row++) {
string line;
getline(inputFile, line);
if (!inputFile.good())
break;
stringstream ss(line);
for (int col = 0; col < 9; col++) {
size_t si = line.find_first_not_of("\n 123456789");
string ch = line.substr(0, si);
if (ch.length() == 0) break;
istringstream converter(ch);
converter >> grid[row][col];
if ((si + 1u) >= line.length() || si == std::string::npos) break;
line = line.substr(si + 1u, std::string::npos);
}
}
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++) {
if (grid[i][j] == 0) {
cout << " ";
}
else {
cout << grid[i][j] << " ";
}
if ((j + 1) % 3 == 0) {
cout << "|";
}
if (j == 8)
cout << " " << (i + 1);
}
cout << endl;
if ((i + 1) % 3 == 0) {
for (int s = 0; s <= 20; s++)
cout << "-";
cout << endl;
}
}
cout << endl;
return 0;
}
你有没有想过用几个连续的分隔符来做到这一点?
非常感谢
循环 for (int col = 0; col < 9; col++)
在 if (ch.length() == 0) break;
处过早中断 - 每个双冒号 ";;"
都会停止进一步阅读。此外,第二次中断 if ((si + 1u) >= line.length() || si == std::string::npos) break;
将匹配得太早。
我会通过辅助函数将每个输入行拆分为单个值。这可能会使用更多行,但更易于阅读和调试:
for (int row = 0; row < 9; row++)
{
string line;
getline(inputFile, line);
if (!inputFile.good())
{
break; // handle error
}
size_t delimiterPos = line.find_first_not_of("\n 123456789");
if (delimiterPos == std::string::npos)
{
break; // handle error
}
char delimiter = line[delimiterPos];
vector<string> singleValues = split(clearBlanks(line), delimiter);
if (singleValues.size() != 9)
{
break; // handle error
}
for (size_t col = 0; col < singleValues.size(); col++)
{
grid[row][col] = singleValues[col].size() > 0 ? stoi(singleValues[col]) : 0;
}
}
借助二加。功能 - 一个清除字符串中的所有空白:
std::string clearBlanks(const std::string& input)
{
std::string returnValue = input;
size_t pos = returnValue.find(" ");
while (pos != std::string::npos)
{
returnValue.erase(pos, 1);
pos = returnValue.find(" ");
}
return returnValue;
}
然后将字符串拆分为字符串数组:
vector<string> split(const string& str, char delim)
{
vector<string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == string::npos)
{
pos = str.length();
}
tokens.push_back(str.substr(prev, pos - prev));
prev = pos + 1;
} while (pos < str.length());
return tokens;
}
我正在尝试从 CSV 文件生成数独网格。 我制作的代码适用于这种文件:
1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8,9
...
但是我需要它来用这种文件创建网格:
; ; 5; ;;1; ;;1
3; ; ;;;;6; ;
;7;;;;2;;;4
;;1;3;;5;;8;
...
这是我的代码:
int grid[9][9];
ifstream inputFile;
inputFile.open(inputFileName);
for (int row = 0; row <9 ; row++) {
string line;
getline(inputFile, line);
if (!inputFile.good())
break;
stringstream ss(line);
for (int col = 0; col < 9; col++) {
size_t si = line.find_first_not_of("\n 123456789");
string ch = line.substr(0, si);
if (ch.length() == 0) break;
istringstream converter(ch);
converter >> grid[row][col];
if ((si + 1u) >= line.length() || si == std::string::npos) break;
line = line.substr(si + 1u, std::string::npos);
}
}
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++) {
if (grid[i][j] == 0) {
cout << " ";
}
else {
cout << grid[i][j] << " ";
}
if ((j + 1) % 3 == 0) {
cout << "|";
}
if (j == 8)
cout << " " << (i + 1);
}
cout << endl;
if ((i + 1) % 3 == 0) {
for (int s = 0; s <= 20; s++)
cout << "-";
cout << endl;
}
}
cout << endl;
return 0;
}
你有没有想过用几个连续的分隔符来做到这一点?
非常感谢
循环 for (int col = 0; col < 9; col++)
在 if (ch.length() == 0) break;
处过早中断 - 每个双冒号 ";;"
都会停止进一步阅读。此外,第二次中断 if ((si + 1u) >= line.length() || si == std::string::npos) break;
将匹配得太早。
我会通过辅助函数将每个输入行拆分为单个值。这可能会使用更多行,但更易于阅读和调试:
for (int row = 0; row < 9; row++)
{
string line;
getline(inputFile, line);
if (!inputFile.good())
{
break; // handle error
}
size_t delimiterPos = line.find_first_not_of("\n 123456789");
if (delimiterPos == std::string::npos)
{
break; // handle error
}
char delimiter = line[delimiterPos];
vector<string> singleValues = split(clearBlanks(line), delimiter);
if (singleValues.size() != 9)
{
break; // handle error
}
for (size_t col = 0; col < singleValues.size(); col++)
{
grid[row][col] = singleValues[col].size() > 0 ? stoi(singleValues[col]) : 0;
}
}
借助二加。功能 - 一个清除字符串中的所有空白:
std::string clearBlanks(const std::string& input)
{
std::string returnValue = input;
size_t pos = returnValue.find(" ");
while (pos != std::string::npos)
{
returnValue.erase(pos, 1);
pos = returnValue.find(" ");
}
return returnValue;
}
然后将字符串拆分为字符串数组:
vector<string> split(const string& str, char delim)
{
vector<string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delim, prev);
if (pos == string::npos)
{
pos = str.length();
}
tokens.push_back(str.substr(prev, pos - prev));
prev = pos + 1;
} while (pos < str.length());
return tokens;
}