C++ 使用C+;读取带有两个连续分隔符的csv文件+;

C++ 使用C+;读取带有两个连续分隔符的csv文件+;,c++,csv,delimiter,sudoku,C++,Csv,Delimiter,Sudoku,我正在尝试从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 r

我正在尝试从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;
}
int-grid[9][9];
ifstream输入文件;
打开(inputFileName);
对于(int row=0;row>grid[row][col];
如果((si+1u)>=line.length()| | si==std::string::npos)中断;
line=line.substr(si+1u,标准::字符串::npos);
}
}
对于(int i=0;ifor(int col=0;col<9;col++)的循环
for
if(ch.length()==0)中断时过早中断;
-每个双冒号
“;”
停止进一步读取。第二个中断
如果((si+1u)>=line.length()| si==std::string::npos)中断;
将过早匹配

我将通过助手函数将每个输入行拆分为单个值。这可能会使用更多的行,但更便于读取和调试:

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;
  }
}
第二种方法是将字符串拆分为字符串数组:

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;
}
向量拆分(常量字符串&str,字符delim)
{
向量标记;
大小\u t上一个=0,位置=0;
做
{
pos=str.find(delim,prev);
if(pos==string::npos)
{
pos=str.length();
}
回推(str.substr(prev,pos-prev));
上一个=位置+1;
}而(位置
Hi,非常感谢您的帮助!我刚刚将行“line.find_first_of(“\n 123456789”)”替换为“line.find_first_of(“,;\t”)”,以便集中处理我想要处理的分隔符。代码非常有效,除了最后一行,其中每个数字都替换为“-858993460”,但如果在我的文件中添加一个空行(用notepad++打开),它工作得很好。我将尝试找出问题出在哪里。再次感谢。当到达文件结尾时,
if(!inputFile.good())
显示
false
。该行已成功读取,但已到达文件结尾——因此在最后一行读取文件后,请说“不好”。将该行移到循环的末尾可能会修复它。。并且检查字符串的长度可能足以进行“读取成功”检查。我将这一行替换为if(inputFile.eof()){inputFile.close()},它工作得非常好,但感谢您的回答
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;
}