0

I'm reading a csv file into c++ to make an multiple parallel arrays and print reports from it. I'm able to cout the strings, no problem, but when I try to create indices, conditions, or translate into int, the strings return no values. There are no characters when I try to atoi, so that is not the issue. I've looked everywhere and can't find any other similar questions. The logic of my code is also not the issue because it works when I populate the tempArray2 manually. Also, I'm a first semester student, so there's going to be some kludge in my code. Does the getline eliminate the value of the string?

(Because this was flagged as answered: This is not a duplicate question, I am not trying to parse the csv into vectors, I'm using parallel arrays and this worked for generating my first report because those values were not strings. Using a parser someone else programed would cause me to fail this assignment and doesn't answer my question why values become 0.)

Here's a snippet of the .csv; the lines are not double spaced on the notepad.

"LOCATION","INDICATOR","SUBJECT","MEASURE","FREQUENCY","TIME","Value","Flag Codes"

"GBR","FERTILITY","TOT","CHD_WOMAN","A","2019",1.63,

"USA","FERTILITY","TOT","CHD_WOMAN","A","1970",2.48,

"USA","FERTILITY","TOT","CHD_WOMAN","A","1971",2.27,

Here's the readFile function. You can see the comment where I tried to atoi the year column (replacing yr[x] with temp like in column 7, which works) and it returns 0 value, even though that column clearly has only ints in the string.

bool ReadFile(string loc[], string yr[], float rates[])
{   
    ifstream input{FILENAME.c_str()};
    if (!input)
    {
        return false;
    }

    //init trash and temp vars
    string trash, temp;
    //trash header line
    for (int i{ 0 }; i < 1; ++i)
    {
        getline(input, trash);
    }
    
    for (int x{ 0 }; x < SIZE; ++x)
    {
        getline(input, loc[x], ',');//read column 1 country
        getline(input, trash, ','); // column 2 trash
        getline(input, trash, ','); // column 3 trash
        getline(input, trash, ','); // column 4 trash
        getline(input, trash, ','); // column 5 trash
        getline(input, yr[x], ',');// read column 6 year
        //yr[x] = atoi(temp.c_str());// would always return value 0 even though no char interfering
        getline(input, temp, ',');//read column 7 rates
        rates[x] = atof(temp.c_str());
        
            cout << yr[x];
            cout << loc[x];
            cout << rates[x];
    }
    return true;
}

And the analyze function, where the issue also occurs in the tempArray2 block. It cannot read "USA" for the boolean, but works if I set it to !=, it will also include indices that clearly have "USA". The first tempArray works as expected.

void Analyze(string loc[], string yr[], float rates[], FertilityResults& result)
{
    // array for highest and lowest fertrates
    float tempArray[SIZE];
    for (int i{ 0 }; i < SIZE; ++i)
    {
        tempArray[i] = rates[i];
    }
    
    result.highestRate = 0;
    result.lowestRate = 20;

    for (int i{ 1 }; i < SIZE; ++i)
    {
        if (tempArray[i] >= result.highestRate)
        {
            result.highestRate = tempArray[i];
            result.highestRateIndex = i;
        }
        else if (tempArray[i] > 0 && tempArray[i] < result.lowestRate)
        {
            result.lowestRate = tempArray[i];
            result.lowestRateIndex = i;
        }
    }
    //2nd array to retrieve USA data
    string tempArray2[SIZE];
    for (int i{ 0 }; i < SIZE; ++i)
    {
        tempArray2[i] = loc[i];
        //cout << tempArray2[i];
        if (tempArray2[i] == "USA")
        {
            cout << "hi";
            result.usaIndex = i;
            cout <<result.usaIndex<<endl;
        }
    }
}

Please let me know if you need anything else or if it runs on your terminal as is somehow. Thanks, this is my final project and the first time I've had to ask for help.

Seoultron
  • 11
  • 1
  • 2
    Always test the stream state after an IO transaction and most definitely before taking actions based on the assumption of success. Any one of those `getline`s could have failed and rather than a simple bit of handler code, now you have to waste time debugging. – user4581301 Oct 17 '22 at 20:55
  • Sorry, this is a little above my head as a first semester student. I haven't learned about testing stream states or handler code. When I cout the 3 arrays I wanted, the data appears to all be there. Doesn't that mean the input was successful? – Seoultron Oct 17 '22 at 21:10
  • 1
    Related to how to check if getline() was a success: [https://stackoverflow.com/questions/4708335/istreamgetline-return-type](https://stackoverflow.com/questions/4708335/istreamgetline-return-type) – drescherjm Oct 17 '22 at 21:15
  • I tried to implement this loop: while ( file.getline( char*, int ) ) { // handle input Does this go in main, with the readFile function nested inside or in the function itself? I'm getting errors I'm unfamiliar with. What is the object "file" in this case? Is it the variable for my input filename or something else? I'm also getting that the parameters char and int are not allowed. – Seoultron Oct 17 '22 at 21:55
  • `getline(input, temp, ',');` `yr[x] = atoi(temp.c_str());` This is what I tried to convert the year strings to ints. When I cout the array without atoi, it shows the characters. Are you saying it's possible that the strings that are cout'ed are actually buffer objects only and not the actual strings? That's why the value is 0 when I atoi, because the getline has actually failed? – Seoultron Oct 17 '22 at 22:12
  • Let's start with a different trick that fives better diagnostics. Replace `yr[x] = atoi(temp.c_str());` with `yr[x] = std::stoi(temp);` and see if it throws an exception. [Link to `std::stoi` documentation](https://en.cppreference.com/w/cpp/string/basic_string/stol). You can also take advantage of the optional `pos` parameter to see where in the string the translation failed. – user4581301 Oct 17 '22 at 23:07
  • I got "Unhandled exception at 0x00007FFFDDCD4FD9 in KortzP8pt2.exe: Microsoft C++ exception: std::invalid_argument at memory location 0x00000094291982D0." "stoi argument out of range" "invalid stoi argument" . Is this a memory issue? – Seoultron Oct 18 '22 at 01:25
  • I don't think this is relevant, but I don't want to be wrong and waste everyone's time. The original csv is 2700 lines long with 8 items on each line. I didn't think this mattered because I copied 4 lines into a txt and read from that file instead and still got the same errors. – Seoultron Oct 18 '22 at 02:04
  • I didn't link that. Someone flagged my question as a duplicate and a mod must have linked it and closed my question. I tried to edit the question so they'll review it and re-open it, but that hasn't happened. They have little to do with each other except that it's parsing from a csv. Even when I turn the file into a txt, it has the same error, so there is something wrong in my code. – Seoultron Oct 19 '22 at 00:54

0 Answers0