Git Product home page Git Product logo

qtcsv's Introduction

qtcsv

Build status

Small easy-to-use library for reading and writing csv-files in Qt.

Qt suppport:

  • Qt6: branch master (you're here)
  • Qt4 and Qt5: branch qt4_qt5

Tested on:

  • Ubuntu with gcc, Qt6
  • Windows with MinGW, Qt6
  • OS X with clang, Qt6

Table of contents

1. Quick Example

#include <QList>
#include <QString>
#include <QDir>
#include <QDebug>

#include "qtcsv/stringdata.h"
#include "qtcsv/reader.h"
#include "qtcsv/writer.h"

int main()
{
    // prepare data that you want to save to csv-file
    QList<QString> strList;
    strList << "one" << "two" << "three";

    QtCSV::StringData strData;
    strData.addRow(strList);
    strData.addEmptyRow();
    strData << strList << "this is the last row";

    // write to file
    const auto filePath = QDir::currentPath() + "/test.csv";
    QtCSV::Writer::write(filePath, strData);

    // read data from file
    const auto readData = QtCSV::Reader::readToList(filePath);
    for (auto i = 0; i < readData.size(); ++i)
    {
        qDebug() << readData.at(i).join(",");
    }

    return 0;
}

2. Usage

Library could be separated into three parts: Reader, Writer and Containers.

2.1 Containers

qtcsv library can work with standard Qt containers (like QList) and special data containers.

2.1.1 AbstractData

AbstractData is a pure abstract class that provides interface for a class of special data containers.

class AbstractData {
public:
    virtual ~AbstractData() = default;

    virtual void addEmptyRow() = 0;
    virtual void addRow(const QList<QString>& values) = 0;
    virtual void clear() = 0;
    virtual bool isEmpty() const = 0;
    virtual qsizetype rowCount() const = 0;
    virtual QList<QString> rowValues(qsizetype row) const = 0;
};

As you can see, AbstractData declare virtual functions for adding new rows, getting rows values, clearing all information and so on. Basic stuff for a container class.

2.1.2 StringData

StringData inhertis interface of AbstractData class and provides some useful functions for inserting/removing rows and so on. Class uses strings to store data.

2.1.3 VariantData

If you store information in different types - integers, floating point values, strings or (almost) anything else (example: [1, 3.14, "check"]) - and you don't want to manually transform each element to string, then you can use QVariant magic. Wrap your data into QVariants and pass it to VariantData class. It also inherits interface of AbstractData plus has several useful methods.

2.2 Reader

Use Reader class to read csv-files / csv-data. Let's see it's functions.

2.2.1 Reader functions

  1. Read data to QList<QList<QString>>
QList<QList<QString>> readToList(
    const QString& filePath,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    QStringConverter::Encoding codec = QStringConverter::Utf8);
                              
QList<QList<QString>> readToList(
    QIODevice& ioDevice,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    QStringConverter::Encoding codec = QStringConverter::Utf8);
  • filePath - string with absolute path to existent csv-file (example: "/home/user/my-file.csv");
  • ioDevice - IO Device that contains csv-formatted data;
  • separator (optional) - delimiter symbol, that separates elements in a row (by default it is comma - ",");
  • textDelimiter (optional) - text delimiter symbol that encloses each element in a row (by default it is double quoute - ");
  • codec (optional) - codec type that will be used to read data from the file (by default it is UTF-8 codec).

As a result function will return QList<QList<QString>> that holds content of the file / IO Device. Size of it will be equal to the number of rows in csv-data source. Each QList<QString> will contain elements of the corresponding row. On error these functions will return empty list.

  1. Read data to AbstractData-based container
bool readToData(
    const QString& filePath,
    AbstractData& data,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    QStringConverter::Encoding codec = QStringConverter::Utf8);
                
bool readToData(
    QIODevice& ioDevice,
    AbstractData& data,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    QStringConverter::Encoding codec = QStringConverter::Utf8);

These functions are little more advanced and, I hope, a little more useful.

  • filePath - string with absolute path to existent csv-file;
  • ioDevice - IO Device that contains csv-formatted data;
  • data - reference to AbstractData-based class object;
  • separator (optional) - delimiter symbol;
  • textDelimiter (optional) - text delimiter symbol;
  • codec (optional) - codec type.

Functions will save content of the file / IO Device in data object using virtual function AbstractData::addRow(QList<QString>). Elements of csv-data will be saved as strings in objects of StringData / VariantData.

If you would like to convert row elements to the target types on-the-fly during file reading, please implement your own AbstractData-based container class.

  1. Read data and process it line-by-line by AbstractProcessor-based processor
bool readToProcessor(
    const QString& filePath,
    AbstractProcessor& processor,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    QStringConverter::Encoding codec = QStringConverter::Utf8);
                     
bool readToProcessor(
    QIODevice& ioDevice,
    AbstractProcessor& processor,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    QStringConverter::Encoding codec = QStringConverter::Utf8);
  • filePath - string with absolute path to existent csv-file;
  • ioDevice - IO Device that contains csv-formatted data;
  • processor - reference to AbstractProcessor-based class object;
  • separator (optional) - delimiter symbol;
  • textDelimiter (optional) - text delimiter symbol;
  • codec (optional) - codec type.

This function will read csv-data from file / IO Device line-by-line and pass data to processor object.

2.2.2 AbstractProcessor

AbstractProcessor is an abstract class with two methods:

class AbstractProcessor
{
public:
    virtual ~AbstractProcessor() = default;
    virtual void preProcessRawLine(QString& /*editable_line*/) {}
    virtual bool processRowElements(const QList<QString>& elements) = 0;
};

When Reader opens a csv-data source (file or IO Device), it starts reading it line by line in a cycle. First of all, Reader passes each new line to processor's method preProcessRawLine(QString&). In this method you can edit the line - replace values, remove sensitive information and so on.

After that Reader parses elements of the row and passes them to processor's method processRowElements(QList<QString>). At that step you can do whatever you want with row elements - convert/edit/save/filter the elements. Please check out ReadToListProcessor class (defined in reader.cpp) as an example of such processor.

2.3 Writer

Use Writer class to write csv-data to files / IO Devices.

bool write(
    const QString& filePath,
    const AbstractData& data,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    WriteMode mode = WriteMode::REWRITE,
    const QList<QString>& header = {},
    const QList<QString>& footer = {},
    QStringConverter::Encoding codec = QStringConverter::Utf8);
                   
bool write(
    QIODevice& ioDevice,
    const AbstractData& data,
    const QString& separator = QString(","),
    const QString& textDelimiter = QString("\""),
    const QList<QString>& header = {},
    const QList<QString>& footer = {},
    QStringConverter::Encoding codec = QStringConverter::Utf8);
  • filePath - string with absolute path to csv-file (new or existent);
  • ioDevice - IO Device;
  • data - object, that contains information that you want to write to csv-file / IO Device;
  • separator (optional) - delimiter symbol (by default it is comma - ",");
  • textDelimiter (optional) - text delimiter symbol that encloses each element in a row (by default it is double quoute - ");
  • mode (optional) - write mode flag. If it set to WriteMode::REWRITE and csv-file exist, then csv-file will be rewritten. If mode set to WriteMode::APPEND and csv-file exist, then new information will be appended to the end of the file. By default mode is set to WriteMode::REWRITE.
  • header (optional) - strings that will be written as the first row;
  • footer (optional) - strings that will be written at the last row;
  • codec (optional) - codec type that will be used in write operations (by default it is UTF-8 codec).

Writer uses CRLF as line ending symbols in accordance with standard. If element of the row contains separator symbol or line ending symbols, such element will be enclosed by text delimiter symbols (or double quoute if you have set empty string as text delimiter symbol).

3. Requirements

Qt6, only core/base modules.

4. Build

4.1 Building on Linux, OS X

4.1.1 Using qmake

cd /path/to/folder/with/qtcsv

# Create build directory
mkdir ./build
cd ./build

# Build library. You can choose build type: release or debug
qmake ../qtcsv.pro CONFIG+=[release|debug]
make

# Create build directory for tests
mkdir ./tests
cd ./tests

# Build tests. Besides of setting build type, we set path where linker could find compiled library file.
qmake ../../tests/tests.pro CONFIG+=[release|debug] LIBS+=-L../
make

4.1.2 Using cmake

cd /path/to/folder/with/qtcsv

# Create build directory
mkdir ./build
cd ./build

# Build library and tests. See CMakeLists.txt for list of additional options that you can set.
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ..
make

4.2 Building on Windows

4.2.1 Prebuild step on Windows

If you going to build qtcsv library on Windows with MinGW, first of all check that your PATH variable contains paths to Qt and MinGW toolsets.

4.2.2 Using qmake

cd C:\path\to\folder\with\qtcsv

# Create build directory
mkdir .\build
cd .\build

# Build library. You can choose build type: release or debug. Set DESTDIR to current directory.
qmake ..\qtcsv.pro CONFIG+=[release|debug] DESTDIR=%cd%
mingw32-make

# Create build directory for tests
mkdir .\tests
cd .\tests

# Copy library file into 'tests' directory
copy ..\qtcsv.dll .\

# Build tests
qmake ..\..\tests\tests.pro CONFIG+=[release|debug] DESTDIR=%cd%
mingw32-make

4.2.3 Using cmake

cd C:\path\to\folder\with\qtcsv

# Create build directory
mkdir .\build
cd .\build

# Build library and tests. See CMakeLists.txt for list of additional options that you can set.
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ..
mingw32-make

5. Run tests

To run tests use these commands after build of qtcsv:

5.1 Linux, OS X

cd /path/to/folder/with/qtcsv/build/tests

# Set LD_LIBRARY_PATH variable so test binary will know where to search library file.
# Suppose, that library file is located in "build" directory, up a level from current directory.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/../

chmod 777 qtcsv_tests
./qtcsv_tests

5.2 Windows

cd /path/to/folder/with/qtcsv/build/tests

# Copy library file into "tests" directory
copy ..\*qtcsv.dll .\

qtcsv_tests.exe

6. Installation

On Unix-like OS you can install qtcsv library using these commands:

sudo make install
sudo ldconfig -n -v /usr/local/lib

These commands will copy all compiled files (libqtcsv.so*) from build folder to "/usr/local/lib". Also all headers files will be copied from "./include" folder to "/usr/local/include/".

All installation settings are defined in qtcsv.pro file. See copy_lib_headers and target variables.

For additional information, see Qt documentation about files installation.

7. Examples

If you would like to try qtcsv, you can download qtcsv-example project. Don't forget to read README.md file!

8. Other

If you want to know more about csv-file format, please read RFC 4180 standard.

Also on this page you can find useful tips about how should look proper csv-file.

9. Creators

Author: Antony Cherepanov ([email protected])
Contributors: Patrizio "pbek" Bekerle, Furkan "Furkanzmc" Üzümcü, Martin "schulmar" Schulze, cguentherTUChemnitz, David Jung, Nicu Tofan, Florian Apolloner, Michael Pollind, Kuba Ober, Akram Abdeslem Chaima, Bogdan Cristea, Markus Krause

qtcsv's People

Contributors

apollo13 avatar cguenthertuchemnitz avatar gakramx avatar iamantony avatar kubao avatar pbek avatar pollend avatar schulmar avatar tnick avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qtcsv's Issues

Failure when line begins with closing field delimiter

Thanks for QtCSV!

I am reading some CSV files from elsewhere that I have no control over. I've discovered that some rows span multiple lines of the file and are delimited by double quotes (the default). However, with lines on which the terminating quote is at the first position of the line, QtCSV doesn't interpret it correctly and adds the quote to the field data and gets confused.

For example, consider some rows like:

A,B,C,D
a,b,c,d
a,"b field","c field
","d field"
aa,bb,cc,dd

QtCSV returns the 3rd row as "a", "b field", "c field\n\",\"d field", ""

I hacked a fix for my immediate purpose by adding a line in reader.cpp to check if the line starts with '\"' and if so, just add a leading " " (space).
However, I thought you would like to fix it in the master properly.

(Note that it would be useful if the reader method could take a string or stream instead of just a filename. That way, I could have read the (small) file into memory first and done a search-replace before passing it to QtCSV).

Cheers,
David

New methods for Reader

Idea from @davidljung:

It would be useful if the reader method could take a string or stream instead of just a filename. That way, I could have read the (small) file into memory first and done a search-replace before passing it to QtCSV.

Installation problem

I am not able to install this library. I am using Windows operating system.
I get error like this

C:\Users\cvpr\Documents\QT\qtcsv-master>make
cd src/ && ( test -e Makefile || C:/Qt/5.6/mingw49_32/bin/qmake.exe C:/Users/cvpr/Documents/QT/qtcsv-master/src/src.pro -o Makefile ) && make -f Makefile
make[1]: Entering directory `C:/Users/cvpr/Documents/QT/qtcsv-master/src'
C:/Program Files (x86)/GnuWin32/bin/make -f Makefile.Release
/usr/bin/sh: -c: line 0: syntax error near unexpected token `('
/usr/bin/sh: -c: line 0: `C:/Program Files (x86)/GnuWin32/bin/make -f Makefile.Release'
make[1]: *** [release] Error 1
make[1]: Leaving directory `C:/Users/cvpr/Documents/QT/qtcsv-master/src'
make: *** [sub-src-make_first] Error 2

Store last error message somewhere

Hi,
would it be possible not just to do

 //part of openFile function

    if (false == CheckFile(filePath, true))
    {
        qDebug() << __FUNCTION__ << "Error - wrong file path:" << filePath;
        return false;
    }

but do something like

    if (false == CheckFile(filePath, true))
    {
        internalError  << __FUNCTION__ << "Error - wrong file path:" << filePath;
        qDebug() <<internalError;
        return false;
    }

 QString xxx::getError()
 {
   return internalError;
  }

everywhere where qDebug() is used, so that I can get latest error message when functions returns false and then report it to user?

Thanks.

Is QtCsv compile able for Android?

Is QtCsv compile able for Android?
I failed with some older version (from 2017-06-13):
19:52:55: Uruchamianie kroków budowania dla projektu qtcsv... 19:52:55: Konfiguracja niezmieniona, krok qmake pominięty. 19:52:55: Uruchamianie "C:\x-tools\Qt\Tools\mingw530_32\bin\mingw32-make.exe" C:\x-tools\android-ndk-r15c/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -c -fstack-protector-strong -DANDROID -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove --sysroot=C:\x-tools\android-ndk-r15c/platforms/android-16/arch-arm/ -O2 -Os -mthumb -std=gnu++11 -Wall -W -Werror -Wformat=2 -Wuninitialized -Winit-self -Wswitch-enum -Wundef -Wpointer-arith -Wdisabled-optimization -Wcast-align -Wcast-qual -D_REENTRANT -fPIC -DQTCSV_LIBRARY -DQT_NO_DEBUG -DQT_CORE_LIB -I../QtCSV -I. -I../QtCSV/include -I../../../x-tools/Qt/5.9.1/android_armv7/include -I../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore -I. -I../../../x-tools/android-ndk-r15c/sources/cxx-stl/gnu-libstdc++/4.9/include -I../../../x-tools/android-ndk-r15c/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include -I../../../x-tools/android-ndk-r15c/platforms/android-16/arch-arm/usr/include -I../../../x-tools/Qt/5.9.1/android_armv7/mkspecs/android-g++ -o writer.obj ../QtCSV/sources/writer.cpp In file included from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qvariant.h:47:0, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlocale.h:43, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qtextstream.h:46, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/QTextStream:1, from ../QtCSV/sources/writer.cpp:7: ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qmap.h: In instantiation of 'QMapData<Key, T>::Node* QMapData<Key, T>::end() [with Key = QString; T = QVariant; QMapData<Key, T>::Node = QMapNode<QString, QVariant>]': ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qmap.h:793:22: required from 'QMap<K, V>::iterator QMap<K, V>::insertMulti(const Key&, const T&) [with Key = QString; T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qvariant.h:798:66: required from here ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qmap.h:215:58: error: cast from 'QMapNodeBase*' to 'QMapData<QString, QVariant>::Node* {aka QMapNode<QString, QVariant>*}' increases required alignment of target type [-Werror=cast-align] Node *end() { return reinterpret_cast<Node *>(&header); } ^ In file included from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qstringlist.h:41:0, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/QStringList:1, from ../QtCSV/include/qtcsv/writer.h:5, from ../QtCSV/sources/writer.cpp:1: ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h: In instantiation of 'void QList<T>::node_destruct(QList<T>::Node*, QList<T>::Node*) [with T = QVariant]': ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:866:68: required from 'void QList<T>::dealloc(QListData::Data*) [with T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:827:18: required from 'QList<T>::~QList() [with T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qvariant.h:762:30: required from here ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:496:34: error: cast from 'QList<QVariant>::Node*' to 'QVariant*' increases required alignment of target type [-Werror=cast-align] while (from != to) --to, reinterpret_cast<T*>(to)->~T(); ^ ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h: In instantiation of 'void QList<T>::node_copy(QList<T>::Node*, QList<T>::Node*, QList<T>::Node*) [with T = QVariant]': ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:788:92: required from 'void QList<T>::detach_helper(int) [with T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:572:32: required from 'void QList<T>::reserve(int) [with T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qvariant.h:763:38: required from here ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:475:17: error: cast from 'QList<QVariant>::Node*' to 'QVariant*' increases required alignment of target type [-Werror=cast-align] new (current) T(*reinterpret_cast<T*>(src)); ^ ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:481:17: error: cast from 'QList<QVariant>::Node*' to 'QVariant*' increases required alignment of target type [-Werror=cast-align] (reinterpret_cast<T*>(current))->~T(); ^ ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h: In instantiation of 'void QList<T>::node_destruct(QList<T>::Node*) [with T = QVariant]': ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:604:36: required from 'void QList<T>::append(const T&) [with T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:386:15: required from 'QList<T>& QList<T>::operator<<(const T&) [with T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qvariant.h:765:27: required from here ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qlist.h:452:39: error: cast from 'QList<QVariant>::Node*' to 'QVariant*' increases required alignment of target type [-Werror=cast-align] else if (QTypeInfo<T>::isComplex) reinterpret_cast<T*>(n)->~T(); ^ In file included from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qshareddata.h:46:0, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qfileinfo.h:45, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qdir.h:44, from ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/QDir:1, from ../QtCSV/sources/writer.cpp:6: ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qhash.h: In instantiation of 'static QHash<K, V>::Node* QHash<K, V>::concrete(QHashData::Node*) [with Key = QString; T = QVariant; QHash<K, V>::Node = QHashNode<QString, QVariant>]': ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qhash.h:536:18: required from 'static void QHash<K, V>::deleteNode2(QHashData::Node*) [with Key = QString; T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qhash.h:576:5: required from 'void QHash<K, V>::freeData(QHashData*) [with Key = QString; T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qhash.h:254:47: required from 'QHash<K, V>::~QHash() [with Key = QString; T = QVariant]' ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qvariant.h:779:30: required from here ../../../x-tools/Qt/5.9.1/android_armv7/include/QtCore/qhash.h:237:45: error: cast from 'QHashData::Node*' to 'QHash<QString, QVariant>::Node* {aka QHashNode<QString, QVariant>*}' increases required alignment of target type [-Werror=cast-align] return reinterpret_cast<Node *>(node); ^ cc1plus.exe: all warnings being treated as errors Makefile:869: recipe for target 'writer.obj' failed mingw32-make: *** [writer.obj] Error 1 19:52:58: Proces "C:\x-tools\Qt\Tools\mingw530_32\bin\mingw32-make.exe" zakończył się kodem wyjściowym 2. Błąd budowania / instalowania projektu qtcsv (zestaw narzędzi: Android dla armeabi-v7a (GCC 4.9, Qt 5.9.1 for Android armv7)) Podczas wykonywania kroku "Make" 19:52:58: Czas trwania: 00:03.

Can you added a "lineno" parameter to the methods of AbstractProcessor?

Hi, everybody:
I am a new guy enrolled in github recently.
I found AbstractProcessor is useful, and I think it could be better if there is a lineno (number of the line in csv being processed currently) parameter in the methods of AbstractProcessor. With an added 'lineno' parameter , the users can locate errors or exceptions in csv rapidly.
Hoping to get any feedback. Thanks a lot!

[HELP] I'm trying to build it with an application on Windows, but can't make it work.

I've got a lot of errors, as for now, the last error I got is:

gmapplicationloader.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: static class QList<class QStringList> __cdecl QtCSV::Reader::readToList(class QString const &,class QString const &,class QString const &,class QTextCodec *)" (__imp_?readToList@Reader@QtCSV@@SA?AV?$QList@VQStringList@@@@AEBVQString@@00PEAVQTextCodec@@@Z) referenced in function "public: class QList<class GMApplication *> __cdecl GMApplicationLoader::load(bool)" (?load@GMApplicationLoader@@QEAA?AV?$QList@PEAVGMApplication@@@@_N@Z)

The build is done using QTCreator with QT 5.9.6. The structure looks like:

.
├── qtcsv
├── ItLogin
└── build.pro

My build settings:
image

I really don't know what more can I do to solve these problems. Thanks in advance.

Install target does not copy DLLs on windows

When building as shared libraries on windows (the default), the "install" target doesnt copy the DLLs (typically to a "bin" directory).

This is because in the install command (CMakeLits.txt) there is no instructions to copy "runtime" files.

It should look something like this:

install(TARGETS ${LIBRARY_NAME} EXPORT ${LIBRARY_NAME}Config
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin
        ARCHIVE DESTINATION lib)

portable cmake

Hi there,

i will use this ticket to comment some strategy decisions for your cmake implementation. With modern cmake you are not only able to handle your build environment, also others are able to integrate your project directly into their project structure. That is what i do currently and why i discuss a lot of your cmake efforts :)

A good starting point is for example this tutorial:
https://rix0r.nl/blog/2015/08/13/cmake-guide/

Make QtCreator list all project files

Also a lot of IDEs (e.g. the QtCreator) are able to handle cmake projects directly. So no more qmake is then necessary. One little hack, which does not influence other stuff, is necessary to lets the IDE display all your project files. QtCreator displays only those, which are referenced by the build targets. To achieve this you can add this statement to your cmake files:

file(GLOB_RECURSE ALL_FILES "*")
add_custom_target(show_all_files_in_${PROJECT_NAME} SOURCES ${ALL_FILES})

Don't modify the cmake default behavior

When other guys include your project into their project structure, they expect default cmake behavior. So do not alter this. The "modern" part of the cmake tutorials are to set as most as possible configuration only for your target. This ensures, that no other targets are influenced by global cmake variables.

In-source and out-of-source builds

Please do not modify the

LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}

Cmake create build folder structures in cooperation with the used IDE. If you modify those pathes, it is possible that the IDE can't find the libs after building. I think you are not aware of one cmake concept. You can build where you want. So you can decide if you do an in-source build (putting the temp files and binaries into the source folders) or and out-of-source build (placing the files elsewhere, what is what the most IDEs do, to keep the source folder clean, like QtCreator). With your modification of the LIBRARY_OUTPUT_DIRECTORY you enforce the in-source build (for the lib placement), even when the IDE tries to do it otherwise. The build directory used by cmake is the dir, where you call the cmake statement. So when you want to do an in-source build, you only need to call
cd qtcsv cmake .

cmake automatic compiler flags

Cmake is highly platform, compiler and toolchain independed. So you should try to set at least as possible flags, which depend either on specific compiler, platforms or toolchains. The most of your explicitly defined flags, are handled by cmake automatically.

  1. position independed code (-fPIC for gcc compiler)
    https://cmake.org/cmake/help/v3.0/command/add_library.html
    "For SHARED and MODULE libraries the POSITION_INDEPENDENT_CODE target property is set to ON automatically."
    So you don't need to set this flag. CMake does this for your at the moment, when you request to build a shared lib. A great benefit of such an automation is, that cmake also selects the correct flags for other compilers etc.
  2. compiler flags implicitly defined by CMAKE_BUILD_TYPE
    CMake provides a stock of build types. Those can be defined by calling cmake like this:
    cmake . -DCMAKE_BUILD_TYPE=RELEASE. This is the same what the IDEs do during their configuration. When you start for example QtCreator opening a Cmake project, it configures different out-of-source build folder with different CMAKE_BUILD_TYPE. The build types also switch automatically the compiler flags. This blog shows by example that the compiler flags for Release and Debug builds are the same, what explicitly set.
    https://ecrafter.wordpress.com/2012/04/24/cmake-tutorial-part-2/

CMAKE_CXX_FLAGS_DEBUG is "-g"
CMAKE_CXX_FLAGS_RELEASE is "-O3 -NDEBUG"

Summery - action points

I suggest to:

  1. delete the explicit compiler flags based on the build type:
    https://github.com/iamantony/qtcsv/blob/dev/CMakeLists.txt#L42-L51
    Call cmake with -DCMAKE_BUILD_TYPE=[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL] instead.

  2. ensure library placement handled by cmake
    Delete the LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} statements.
    https://github.com/iamantony/qtcsv/blob/dev/CMakeLists.txt#L66
    https://github.com/iamantony/qtcsv/blob/dev/CMakeLists.txt#L79
    Call cmake in your source folder for in-source builds instead.

  3. Optionally add a not used target containing all files to enforce some IDEs like QtCreator to show all files.

add_custom_target(show_all_files_in_${PROJECT_NAME} SOURCES ${ALL_FILES})

Wrong version in library name under Linux

I compiled from the tag v1.3 via following commands in the toplevel folder:

[schulmar@Nitro qtcsv]$ ls
appveyor.yml  include  LICENSE  qtcsv.pro  README.md  sources  tests
[schulmar@Nitro qtcsv]$ LANG=en git status
HEAD detached at v1.3                                                                                                                                                                                                                                                          
nothing to commit, working tree clean 
[schulmar@Nitro qtcsv]$ qmake
Info: creating stash file /home/schulmar/job/qtcsv/.qmake.stash
[schulmar@Nitro qtcsv]$ ls
appveyor.yml  include  LICENSE  Makefile  qtcsv.pro  README.md  sources  tests
[schulmar@Nitro qtcsv]$ make -j8
g++ -c -pipe -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -Werror -Wformat=2 -Wuninitialized -Winit-self -Wmissing-include-dirs -Wswitch-enum -Wundef -Wpointer-arith -Wdisabled-optimization -Wcast-align -Wcast-qual -D_REENTRANT -fPIC -DQTCSV_LIBRARY -DQT_NO_DEBUG -DQT_CORE_LIB -I. -Iinclude -isystem /usr/include/qt -isystem /usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o writer.o sources/writer.cpp
g++ -c -pipe -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -Werror -Wformat=2 -Wuninitialized -Winit-self -Wmissing-include-dirs -Wswitch-enum -Wundef -Wpointer-arith -Wdisabled-optimization -Wcast-align -Wcast-qual -D_REENTRANT -fPIC -DQTCSV_LIBRARY -DQT_NO_DEBUG -DQT_CORE_LIB -I. -Iinclude -isystem /usr/include/qt -isystem /usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o variantdata.o sources/variantdata.cpp                                                                                     
g++ -c -pipe -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -Werror -Wformat=2 -Wuninitialized -Winit-self -Wmissing-include-dirs -Wswitch-enum -Wundef -Wpointer-arith -Wdisabled-optimization -Wcast-align -Wcast-qual -D_REENTRANT -fPIC -DQTCSV_LIBRARY -DQT_NO_DEBUG -DQT_CORE_LIB -I. -Iinclude -isystem /usr/include/qt -isystem /usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o stringdata.o sources/stringdata.cpp                                                                                       
g++ -c -pipe -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -Werror -Wformat=2 -Wuninitialized -Winit-self -Wmissing-include-dirs -Wswitch-enum -Wundef -Wpointer-arith -Wdisabled-optimization -Wcast-align -Wcast-qual -D_REENTRANT -fPIC -DQTCSV_LIBRARY -DQT_NO_DEBUG -DQT_CORE_LIB -I. -Iinclude -isystem /usr/include/qt -isystem /usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o reader.o sources/reader.cpp                                                                                               
g++ -c -pipe -O2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -Werror -Wformat=2 -Wuninitialized -Winit-self -Wmissing-include-dirs -Wswitch-enum -Wundef -Wpointer-arith -Wdisabled-optimization -Wcast-align -Wcast-qual -D_REENTRANT -fPIC -DQTCSV_LIBRARY -DQT_NO_DEBUG -DQT_CORE_LIB -I. -Iinclude -isystem /usr/include/qt -isystem /usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o contentiterator.o sources/contentiterator.cpp                                                                             
rm -f libqtcsv.so.1.0.0 libqtcsv.so libqtcsv.so.1 libqtcsv.so.1.0                                                                                                                                                                                                              
g++ -Wl,-O1 -Wl,-O1,--sort-common,--as-needed,-z,relro -shared -Wl,-soname,libqtcsv.so.1 -o libqtcsv.so.1.0.0 writer.o variantdata.o stringdata.o reader.o contentiterator.o  -lQt5Core -lpthread                                                                              
ln -s libqtcsv.so.1.0.0 libqtcsv.so                                                                                                                                                                                                                                            
ln -s libqtcsv.so.1.0.0 libqtcsv.so.1                                                                                                                                                                                                                                          
ln -s libqtcsv.so.1.0.0 libqtcsv.so.1.0                                                                                                                                                                                                                                        
[schulmar@Nitro qtcsv]$ ls                                                                                                                                                                                                                                                     
appveyor.yml  contentiterator.o  include  libqtcsv.so  libqtcsv.so.1  libqtcsv.so.1.0  libqtcsv.so.1.0.0  LICENSE  Makefile  qtcsv.pro  reader.o  README.md  sources  stringdata.o  tests  variantdata.o  writer.o

As you can see, the versioned .so files have version 1.0.0 which is in contrast to the tag v1.3.

Not all field are parsed in an csv file.

Hello!

I have big csv file: I have 31 headers and 31 fields in each row below headers. Bug is in first row of my table:
Headers:
"cNumer","Data","NazwaS","Szablon","MagDest","MagW","MagP1","MagP2","RRuch","Zlec","CreUser_","CreTime","ModUser_","ModTime","DataOC","NumerFakt","Opis","SumWart","SumWartW","id_transp","PrzewNs","CzyOpakZ","opakdo","DokMId1","DokMId2","KontrId1","KontrId2","cLista_DokH","_checked","przewoznikKontrId1","przewoznikKontrId2"

First row:
"PR/3/15","2015-07-22 14:17:53.650","IKEA-125-STO","_WZ","(brak)","OCI��","Kntr_IKEA125STO","(brak)","OCIAZ",,"i.kret","2015-07-22 14:17:53.650","i.kret","2015-07-22 14:19:29.402",,,"",,,"","","NIE",0,1,1586989,1,7090,"",0,,

You will notice that last two fields are empty. But QtCsv threats them as one! I have serious errors in my program just because this bug! Please fix this as soon as possible.

thanks and best regards
Jacek

Error parsing quatted strings

The cell value of

CCLK="yy/MM/dd,hh:mm:ss±zz"

should be stored like

"CCLK=""yy/MM/dd,hh:mm:ss±zz"""

in a csv raw text, but it seems the reader could not parse the above format correctly.

Reader: Line breaks lost

Hello,

we noticed that when the CSV is read, the line breaks that have been lost are lost. These do not seem to be imported.

Qt 5.10 support

On Qt 5.10 tests executable catch exception in function testReadFileWithEmptyFields() or testReadFileWorldCitiesPop():

QDEBUG : TestReader::testReadFileWorldCitiesPop() CheckFile Warning - file suffix is not .csv
QDEBUG : TestReader::testReadFileWorldCitiesPop() Elapsed time: 8171 ms
PASS : TestReader::testReadFileWorldCitiesPop()
QFATAL : TestReader::testReadFileWithEmptyFields() Received signal 11
Function time: 0ms Total time: 10648ms
FAIL! : TestReader::testReadFileWithEmptyFields() Received a fatal error.
Loc: [Unknown file(0)]

ld: symbol(s) not found for architecture x86_64

I've Dowloaded and compiled qtcsv. It does so faultlessly. Then I copied libqtcsv.1.0.0.dylib in /opt/local/libexec/qt4/lib and made its corresponding symlinks; I did the same for the header files, I copied them to /opt/local/libexec/qt4/include/QtCSV. So far no problem. But when I tried to compile this code:

#include <QList>
#include <QStringList>
#include <QDir>
#include <QDebug>
#include "QtCSV/stringdata.h"
#include "QtCSV/reader.h"
int main()
{
QString filePath = QDir::currentPath() + "/mytest.csv";
QList<QStringList> readData = QtCSV::Reader::readToList(filePath);
for ( int i = 0; i < readData.size(); ++i )
{
qDebug() << readData.at(i).join(",");
}
return 0;
}

I get the following result:

/usr/bin/clang++ -c -pipe -O2 -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.11 -Wall -W -DQT_NO_DEBUG -DQT_CORE_LIB -DQT_SHARED -I/opt/local+quartz/libexec/qt4/share/mkspecs/macx-g++ -I. -I. -I/opt/local+quartz/libexec/qt4/Library/Frameworks/QtCore.framework/Versions/4/Headers -I/opt/local+quartz/libexec/qt4/Library/Frameworks/QtCore.framework/Versions/4/Headers -I/opt/local+quartz/libexec/qt4/include -F/opt/local/libexec/qt4/Library/Frameworks -F/opt/local/libexec/qt4/lib -o main.o main.cpp
/usr/bin/clang++ -headerpad_max_install_names -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.11 -o ejemplo-csv main.o -F/opt/local/libexec/qt4/Library/Frameworks -F/opt/local/libexec/qt4/lib -F/opt/local/libexec/qt4/Library/Frameworks -F/opt/local/libexec/qt4/lib -L/opt/local/libexec/qt4/lib -framework QtCore
Undefined symbols for architecture x86_64:
"QtCSV::Reader::readToList(QString const&, QString const&, QString const&, QTextCodec_)", referenced from:
main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *
* [ejemplo-csv] Error 1

In a forum I read something about these errors happen when linking against libc and not against libstdc, so i modified the qtcsv Makefile adding to LFLAGS "-stdlib=stdlibc++". In order to checkout if it linked as desired I ran:
otool -L libqtcsv.1.0.0.dylib
and the output was:

libqtcsv.1.0.0.dylib:
/usr/lib/libqtcsv.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/opt/local/libexec/qt4/Library/Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.8.0, current version 4.8.7)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

So this time I was sure it linked against libstdc++. But when I try to compile the program with this library I got the same error.

Can you help please?

Im Using Os X El Capitan 10.11.2
MacPorts 2.3.4
qt4-mac 4.8.7_4
Xcode 7.1 (7B91b)

Hi, please help.

Hi,

I am getting error while compiling your QtCSV. The problem arises due to the no-longer presence of .addRowValues(). By only changing it to addRow(), I am getting a list of errors.

Please help.

Thank you

JayJoe

Error facing in compiling with Raspberry pi toolchain on Linux

Thank you very much for sharing this library. I tried implementing in on linux and successfully able to store the data in csv file with Qt.
I'm using raspberry pi as a end device and created a raspi tool chain to cross compile and build the application on Ubuntu and then test on raspberry pi.
With integration of qtcsv library in the program, the program is not able to read the files. I think there is an issue in defining the target path in pro file. Can anyone please share their valuable inputs to successfully build the project with shared libraries?

Option to not trim spaces

In some cases spaces should not be trimmed from strings when loading CSV.
In my case I want to preserve this strings as is when loaded:

" lvl. %i"," niv. %i"," Level %i"

In current implementation starting spaces will be trimmed. So resulting QStringList will be:

"lvl. %i","niv. %i","Level %i"

It would be nice to have an option to keep or to trim said white-spaces

extra linefeed

We have different results in notepad, notepad++ and wps
image

Actually we just took an original CSV and removed some fields and wrote it back using your CSV program. But the original file looks way different then the CSV made by your LIB.
Looks like there is an extra linefeed.

What we did is:

void MainWindow::on_PB_Start_clicked()
{

QString dir;
if(ui->spinBoxProvider->value()==1)
{
    dir = "C:/Users/Ritsk/Documents/QT PROJECTS/TarievenProgramma/CSV/DIDLOGIC";
}
else
{
    dir = "C:/Users/Ritsk/Documents/QT PROJECTS/TarievenProgramma/CSV/COMMPEAK";
}

QDir directory(dir);
const QString FS = QFileDialog::getOpenFileName(this,tr("Open File"), directory.absolutePath(), tr("Files (*.csv)"));
QList<QStringList> data = QtCSV::Reader::readToList(FS);
data.removeAt(0);
for(int i=1;i<data.size();i++)
{
    if(ui->spinBoxProvider->value()==1)
    {
        data[i].removeAt(0);
    }
    else
    {
        data[i].removeAt(0);
        data[i].removeAt(2);
    }
}
QtCSV::StringData strData;
QStringList Header;
Header << "RATE" << "PREFIX";
strData.addRow(Header);
for(int i=1;i<data.size();i++)
{
    QStringList strList;
    if(ui->spinBoxProvider->value()==1)
    {
        strList << data[i].at(0) << data[i].at(1);
    }
    else
    {
        //QString s = data[i].at(0);
        //s + "\r";
        strList << data[i].at(1) << data[i].at(0);
    }
    strData.addRow(strList);
}

bool writeResult;
if(ui->spinBoxProvider->value()==1)
{
    writeResult = QtCSV::Writer::write("C:/Users/Ritsk/Documents/QT PROJECTS/TarievenProgramma/DIDLOGIC.csv", strData);

}
else
{
    writeResult = QtCSV::Writer::write("C:/Users/Ritsk/Documents/QT PROJECTS/TarievenProgramma/COMMPEAK.csv", strData);
}

if(writeResult)
{
    QMessageBox msgBox;
    msgBox.setText("CSV has been CONVERTED");
    msgBox.exec();
}
else
{
    QMessageBox msgBox;
    msgBox.setText("ERROR: CSV has NOT been CONVERTED!!");
    msgBox.exec();
}

I have send the code to your email adres as well.

WHAT are we doing WRONG?
Why is the original different then the one made with your LIB?

addRowValues method does not exist

Hi Antony

First it all, thanks for sharing.

FYI (my 2 cents)
I've seen that in the example included in the README.md you mentioned the use of a method, addRowValues for the Class StringData. However, this class method does not exist in the current commit. But there is an addRow Method (without the Suffix Values).
Thanks!!!

Set library version as part of `project()`

Newer CMake versions issue the following warning:

CMake Warning (dev) at vendor/qtcsv/CMakeLists.txt:3 (project):
  Policy CMP0048 is not set: project() command manages VERSION variables.
  Run "cmake --help-policy CMP0048" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.

  The following variable(s) would be set to empty:

    PROJECT_VERSION
    PROJECT_VERSION_MAJOR
    PROJECT_VERSION_MINOR
    PROJECT_VERSION_PATCH
This warning is for project developers.  Use -Wno-dev to suppress it.

Could we raise the minimal CMake version to 3.0 and utilize the VERSION component of project?

Build issues under Windows

Thanks a lot for this nifty library!

I use it in https://github.com/pbek/QOwnNotes and it works great under Linux und macOS.
But when I build QOwnNotes under Windows with AppVeyor (and also locally) I get the error message:
/release/tabledialog.o:tabledialog.cpp:(.text+0x68d): undefined reference to _imp___ZN5QtCSV6Reader10readToListERK7QStringS3_S3_P10QTextCodec

for example here: https://ci.appveyor.com/project/pbek/qownnotes/build/windows-b2567

tabledialog.cpp is where I use your library at https://github.com/pbek/QOwnNotes/blob/develop/src/dialogs/tabledialog.cpp#L70

Do you have any idea why this might happen?

This is the AppVeyor config: https://github.com/pbek/QOwnNotes/blob/develop/appveyor.yml
And this my qmake project file: https://github.com/pbek/QOwnNotes/blob/develop/src/QOwnNotes.pro

Thank you very much!

Unable to read CSV files with filename containing dots "."

Hi,
I found that QtCSV lib cannot read files which have in its filename string one or more dots.

The file src\sources\filechecker.h calls the completeSuffix() function of QInfoFileclass to check the file extension.

Line 15 to 24:

    inline bool CheckFile(const QString& filePath)
    {
        QFileInfo fileInfo(filePath);

        if ( fileInfo.isAbsolute() && "csv" == fileInfo.completeSuffix() )
        {
            return true;
        }

        return false;
    }

As you can see in Qt documentation the completeSuffix() function returns all characters in the file after (but not including) the first dot ".". In case you have a filename such as "myFile.v123.csv" the return string will be "v123.cvs" which is not equal to "cvs as supposed in line 17 of filechecker.h.

I replaced completeSuffix() by suffix() and everything worked just fine. I checked and the CheckFile function is used file validation in both read and write features.

Please let me know if there's any additional implication on changing this in the library.

Best,
Filipe

Bug in Qt 5.12 which appears when we use QtCsv

Hi!
Please check attached project. You have set Qt5.12 as your chosen Qt version and run app in debug mode (F5). Then program will hang in main() function on the first line (of the two).
I report you this problem, because I am unable to determine reasons of this hang. This is not happen in Qt5.9.7.
I guess this bug is related to they "great speed improvement" in 5.12 release (as you can see there are some SSE code around).
Please take a look in debuger output and give me a hint how describe this bug to the Qt (or better: you can report it by yourself).
QtCsvAndQt512Bug.zip

Building test fails?

[OK ]cd C:\path\to\folder\with\qtcsv

[OK ]# Create build directory
[OK ]mkdir .\build
[OK ]cd .\build

[OK ]# Build library. You can choose build type: release or debug. Set DESTDIR to current directory.
[OK ]qmake ..\qtcsv.pro CONFIG+=[release|debug] DESTDIR=%cd%
[OK ]mingw32-make

[OK ]# Create build directory for tests
[OK ]mkdir .\tests
[OK ]cd .\tests

[OK ]# Copy library file into 'tests' directory
[OK ]copy ..\qtcsv.dll .\

[OK ]# Build tests
[OK ]qmake ....\tests\tests.pro CONFIG+=[release|debug] DESTDIR=%cd%
[ERROR]mingw32-make

..\..\tests\testreader.cpp: In member function 'void TestReader::testReadFileWorldCitiesPop()':
..\..\tests\testreader.cpp:383:17: error: 'void QTime::start()' is deprecated: Use QElapsedTimer instead [-Werror=deprecated-declarations]
     timer.start();
                 ^
In file included from C:\Qt\5.14.2\mingw73_32\include/QtCore/qcborvalue.h:44:0,
                 from C:\Qt\5.14.2\mingw73_32\include/QtCore/qcborarray.h:43,
                 from C:\Qt\5.14.2\mingw73_32\include/QtCore/QtCore:38,
                 from C:\Qt\5.14.2\mingw73_32\include/QtTest/QtTestDepends:3,
                 from C:\Qt\5.14.2\mingw73_32\include\QtTest/QtTest:3,
                 from ..\..\tests\testreader.h:5,
                 from ..\..\tests\testreader.cpp:1:
C:\Qt\5.14.2\mingw73_32\include/QtCore/qdatetime.h:228:55: note: declared here
     QT_DEPRECATED_X("Use QElapsedTimer instead") void start();
                                                       ^~~~~
..\..\tests\testreader.cpp:385:50: error: 'int QTime::elapsed() const' is deprecated: Use QElapsedTimer instead [-Werror=deprecated-declarations]
     qDebug() << "Elapsed time:" << timer.elapsed() << "ms";
                                                  ^
In file included from C:\Qt\5.14.2\mingw73_32\include/QtCore/qcborvalue.h:44:0,
                 from C:\Qt\5.14.2\mingw73_32\include/QtCore/qcborarray.h:43,
                 from C:\Qt\5.14.2\mingw73_32\include/QtCore/QtCore:38,
                 from C:\Qt\5.14.2\mingw73_32\include/QtTest/QtTestDepends:3,
                 from C:\Qt\5.14.2\mingw73_32\include\QtTest/QtTest:3,
                 from ..\..\tests\testreader.h:5,
                 from ..\..\tests\testreader.cpp:1:
C:\Qt\5.14.2\mingw73_32\include/QtCore/qdatetime.h:230:54: note: declared here
     QT_DEPRECATED_X("Use QElapsedTimer instead") int elapsed() const;
                                                      ^~~~~~~
cc1plus.exe: all warnings being treated as errors
mingw32-make[1]: *** [Makefile.Release:2670: release/testreader.o] Error 1
mingw32-make[1]: Leaving directory 'D:/APP/qtcsv-master/build/tests'
mingw32-make: *** [Makefile:45: release] Error 2

Bug: wrong processing of string that contains separator symbol

Based on this comment: http://stackoverflow.com/questions/22802491/create-csv-file-in-c-in-qt/30391988?noredirect=1#comment57510719_30391988

When data string contains separator symbol, writer (and reader) will split it in two different strings.
Example:
Separator: ","
Input: "one", "two", "str with, comma"
What we want to see in file: one,two,"str with, comma"
What we get: one,two,str with, comma

Solution: check if data string contains separator symbol. If yes, then we need to add double quotes at the begining and at the end of the date string.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.