【问题标题】:Read a csv file with two consecutive delimiters using C++使用 C++ 读取具有两个连续分隔符的 csv 文件
【发布时间】:2019-09-22 15:02:57
【问题描述】:

我正在尝试从 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;
}

你有什么想法用几个连续的分隔符来做吗?

非常感谢

【问题讨论】:

    标签: c++ csv delimiter sudoku


    【解决方案1】:

    循环for (int col = 0; col &lt; 9; col++) 在if (ch.length() == 0) break; 处中断得太早 - 每个双冒号";;" 都会停止进一步阅读。此外,第二次休息if ((si + 1u) &gt;= 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;
    }
    

    【讨论】:

    • 您好,非常感谢您的帮助!我刚刚将“line.find_first_not_of("\n 123456789")" 行替换为 "line.find_first_of(",;\t")" 以便专注于我想要处理的分隔符。代码效果很好,除了最后一行,每个数字都被“-858993460”替换,但是如果在我的文件中添加一个空行(用记事本++打开),它可以完美运行。我会试着找出问题出在哪里。再次感谢。
    • 当到达文件末尾时,if (!inputFile.good()) 表示false。该行已成功读取,但已到达文件末尾 - 因此在最后一行读取文件后说“不好”。将该行移动到循环的末尾可能会修复它..并检查字符串的长度可能足以进行“读取成功”检查。
    • 我用 if(inputFile.eof()) {inputFile.close()} 替换了这一行,它工作得很好,但是谢谢你的回答
    猜你喜欢
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 2020-07-18
    相关资源
    最近更新 更多