📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

233行目: 233行目:
   
   
     return true;
     return true;
}
</syntaxhighlight>
<br><br>
== ストリーミング処理を使用したCSVファイルの読み込み ==
* ストリーミング処理
*: ファイル全体を1度にメモリに読み込むのではなく、1レコードずつ処理する。
*: これにより、大規模なファイルでもメモリ使用量を抑えることができる。
* コールバック関数
*: 各レコードの処理をコールバック関数として渡すことにより、柔軟な処理が可能になる。
<br>
<syntaxhighlight lang="c++">
#include <QFile>
#include <QTextStream>
#include <QStringList>
#include <functional>
#include <QDebug>
enum class CSVError {
    NoError,
    FileOpenError,
    ReadError,
    ParseError
};
class CSVReader
{
private:
    QString m_filename;
public:
    CSVReader(const QString &filename) : m_filename(filename) {}
    CSVError readCSV(std::function<void(const QStringList&)> rowCallback)
    {
      QFile file(m_filename);
      if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
          qDebug() << "ファイルのオープンに失敗: " << m_filename;
          return CSVError::FileOpenError;
      }
      QTextStream in(&file);
      in.setCodec("UTF-8");
      QString line;
      QStringList fields;
      bool inQuotes = false;
      QString field;
      qint64 lineNumber = 0;
      while (!in.atEnd()) {
          QChar ch;
          in >> ch;
          if (in.status() != QTextStream::Ok) {
            qDebug() << "読み込みエラー:" << m_filename << "行:" << lineNumber;
            return CSVError::ReadError;
          }
          if (inQuotes) {
            if (ch == '"') {
                if (in.peek() == '"') {
                  field += ch;
                  in >> ch;  // 次の文字(二重引用符)を読み飛ばす
                }
                else {
                  inQuotes = false;
                }
            }
            else {
                field += ch;
            }
          }
          else {
            if (ch == '"') {
                inQuotes = true;
            }
            else if (ch == ',' || ch == '\n' || in.atEnd()) {
                fields.append(field.trimmed());
                field.clear();
                if (ch == '\n' || in.atEnd()) {
                  rowCallback(fields);
                  fields.clear();
                  lineNumber++;
                }
            }
            else {
                field += ch;
            }
          }
      }
      if (inQuotes) {
          qDebug() << "パースエラー: 閉じていない引用符があります。行:" << lineNumber;
          return CSVError::ParseError;
      }
      file.close();
      return CSVError::NoError;
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
int main()
{
    CSVReader reader("example.csv");
    CSVError error = reader.readCSV([](const QStringList& row) {
      // 各レコードの処理
      qDebug() << row;
    });
    switch (error) {
      case CSVError::NoError:
          qDebug() << "CSVファイルの読み込みに成功";
          break;
      case CSVError::FileOpenError:
          qDebug() << "ファイルのオープンに失敗";
          break;
      case CSVError::ReadError:
          qDebug() << "ファイルの読み込み中にエラーが発生";
          break;
      case CSVError::ParseError:
          qDebug() << "CSVのパース中にエラーが発生";
          break;
    }
    return 0;
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>