FileInputStream.readNextLine() returns empty String

I am using the function FileInputStream.readNextLine() which for some lines it returns an empty String.

Anyone have an idea of that I’m missing or if this is a bug?

The data I’m reading are comma separated, like this,
20.83333333,35.63360901
22.43589744,35.77016562
24.03846154,35.90762935

I suspect there is not enough information in your post for anyone to help you, but the great thing about JUCE is that you have the source code. Just step into the function and find out what is going on. :slight_smile:

What happens if you simply ignore empty lines? Do you still get all your data, or are there missing lines?

Hard to tell from that info, but perhaps the data has multiple CR/LF endings on some lines, but not others?

Thank you for your replies.

I actually found out that it was not the readNextLine() that was giving the error but nonetheless I switched my method from readying single bytes to tokenizing the String and now the reading is more robust to preculiar input files.

I am now having a different problem and after many tries I believe it must be because of the StringArray, which is allocating memory on the heap. When I have arrays < 200 items then I do not get any errors. The moment I read arrays above 400 items (not exact as I have not measured that), I get malloc errors!

Funny thing is, if I read the shorter file first and then the longer, most times I won’t get the error :expressionless:

Example code of what I am doing,

#define DATALENGTH 8192

class ClassTwo
{
public:

    ClassTwo() 
    {
        dataStrings.ensureStorageAllocated(DATALENGTH * sizeof(float));
    }
    ~ClassTwo() 
    {
        dataStrings.clear();
    }

    void readData(const File& fileToRead, const std::unique_ptr<float[]>& FR_f) 
    {
        //## if stream cannot be read, this will return a nullptr
        if (std::unique_ptr<FileInputStream> inputStream{ fileToRead.createInputStream() })
        {
            // Counters
            int n = 0;
            int m = 0;
            int row = 0;

            // Local Objects
            String delim = ",";

            //## Read each line
            while (!inputStream->isExhausted())
            {
                auto inputString = inputStream->readNextLine();

                auto tokensAdded = dataStrings.addTokens(inputString, delim, "");

                //## Skip line if starts with Text
                if (dataStrings[row + m].getFloatValue() != 0.0f)
                {
                    //... Assignment, Etc ...
                }
            }

            // Clear
            dataStrings.clear();
    }

private:
    StringArray dataStrings;

};


class ClassOne
{
public:

    ClassOne()
    {
        FR.reset(new float[DATALENGTH * sizeof(float)]);
    }

    ~ClassOne() 
    {
        FR = nullptr;
    }

    //... Other Stuff...

    void getSomeData()
    {
        File fileToRead(pathBox.getText());

        //... Other Checks etc...

        void theOtherClass.readData(fileToRead, FR);
    }

private:
    std::unique_ptr<float[]> FR;

    ClassTwo theotherClass;
};

If anyone could help it would be awesome. If anyone has better ideas, of guaranteeing I always get the memory size thay I need, that is also appreciated.

I’ve looked into the documentation and thought of maybe implementing an Array with a CriticalSection but this will not give me the wonderful addTokens function.