Нежелательный символ в CSV-файле при сериализации из QTableWidget

#c #qt #qt5 #qtextstream #qdatastream

#c #qt #qt5 #qtextstream #qdatastream

Вопрос:

Я пытаюсь прочитать данные из QTableWidget и сохранить их в CSV-файле.

Значения, сохраненные в файле, верны, но для первого столбца в каждой строке в начале присутствует нежелательный символ.

Вот мой код:

 void Task::on_button_Export_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this,tr("Export Task List"), "",tr("CSV Files (*.csv)"));
    if (fileName.isEmpty())
            return;
    else
    {
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly))
        {
            QMessageBox::information(this, tr("Unable to open file"),
            file.errorString());
            return;
        }
        QDataStream out(amp;file);
        out.setVersion(QDataStream::Qt_5_4);
        int rowCount = ui->tableWidget->rowCount();
        int colCount = ui->tableWidget->columnCount();
        for (int i = 0; i < rowCount; i  )
         {
            QString str(QString::null);

           /* if (i > 0)
            {
               str = "n";
            }*/

            for (int j = 0; j < colCount; j  )
            {
               if (j > 0)
               {
                  str  = ",";
               }
               QTableWidgetItem* item = ui->tableWidget->item(i,j);
               str  = item->data(Qt::DisplayRole).toString();
            }
            str  = "n";
            out << str;
         }
    }
}
  

Сохраненный файл выглядит следующим образом:

 ÎDPC Task
ÞMain Task
ÌWorkLoop
ÐWorkLoop
ÌIST0
ÊIST1
ÆIST2
  

Я использую Qt 5.4.0.

Любая помощь здесь была бы высоко оценена.

Комментарии:

1. QString str(QString::null); — что это? Просто напишите QString str; . Кстати, есть QTextStream класс для построения строк.

2. Сначала я попробовал String str. Я предполагал, что он получал какое-то ненужное значение, поэтому позже изменил его на QString str (QString::null), чтобы инициализировать его с помощью null

Ответ №1:

Ваше else начало бесполезно, если вы используете return для завершения выполнения функции (вы не использовали else во втором тесте).

Если вам нужно написать текст, вы должны использовать a QTextStream вместо a QDataStream , который предназначен для чтения / записи двоичных данных.

Зачем использовать временное QString в ваших циклах? У вас есть поток, используйте его:

 void Task::on_button_Export_clicked() {
    QString fileName = QFileDialog::getSaveFileName(
        this,tr("Export Task List"), "",tr("CSV Files (*.csv)")
    );
    if (fileName.isEmpty()) {
        return;
    }

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly)) {
        QMessageBox::information(this, tr("Unable to open file"),
        file.errorString());
        return;
    }

    QTextStream out(amp;file);
    int rowCount = ui->tableWidget->rowCount();
    int colCount = ui->tableWidget->columnCount();

    for (int i = 0; i < rowCount; i  ) {
        /* if (i > 0) {
            out << "n";
        }*/
        for (int j = 0; j < colCount; j  ) {
            if (j > 0) {
                out << ",";
            }
            QTableWidgetItem* item = ui->tableWidget->item(i,j);
            out << item->data(Qt::DisplayRole).toString();
        }
        out << "n";
    }
}
  

Комментарии:

1. Большое вам спасибо. Это сработало, и теперь я получаю правильный результат.

Ответ №2:

Не используйте QDataStream для сохранения текстовых файлов. Используйте QTextStream . QDataStream используйте его собственный формат сериализации вместо написания обычного текста.

Для строк первые два байта — это длина, затем это содержимое (по 2 байта на символ). Ваш «мусор» — это длина каждой строки. Вы видите только один символ, потому что ваш файл в юникоде.

Комментарии:

1. Спасибо, Дмитрий. Вы правы, говоря, что мусор на самом деле был длиной каждой строки.