Please need help with opening csv file as string and double.

Hello,

I would like to read both double and string values from a csv file as input data. I have already programmed to open the csv file as double, but I'm not sure how I can read it as string as well. I tried to simply program to open the file again as string, but received an error for trying to initialize the same file twice.

Does anyone know how I could write the code to close the file after the double values are stored and then reopen it as string? Or is there a way to read both string and double values when opening the file only once? Thank you in advance.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>

using namespace std;

int main()
{
	double data[25][41];
	std::ifstream file("C:\\file.csv");

	for (int row = 0; row < 25; ++row)
	{
		std::string line;
		std::getline(file, line);
		if (!file.good())
			break;

		std::stringstream iss(line);

		for (int col = 0; col < 41; ++col)
		{
			std::string val;
			std::getline(iss, val, ';');
			if (!iss.good())
				break;

			std::stringstream convertor(val);
			convertor >> data[row][col];
		}
	}

	cin.get();
	return 0;

}
Last edited on
It can't be that complicated to input both letters and numbers from the same input file, or? lol
A file is neither "string" or "double". It is just a series of bytes.

Since this is a .CSV file, we know it is series of ASCII bytes and does not contain binary values. How you read the file depends on whether you know in advance the format of the columns in the CSV file.

If you know the format in avvance (you should), then it is rather simple. If the cell is a string then file >> str; otherwise the cell is a double cin >> dbl;

With a CSV file, the first row typically contains labels for each column, so you would want to handle this separately.

If you don't know the format of the CSV file in advance, then you have a much harder problem. You need to read each cell, determine it type, convert it if necessary and then store it appropriately.

Based on your previous posts, you know the format and the file in question does have a header row. I'm assuming you want to keep the column labels in the first row.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <vector>
#include <iostream> 
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

const int max_columns = 41; 
const int max_rows = 24;	// Excludes header row

bool parse_header_row (const string & line, vector<string> &labels)
{ stringstream ss(line); 
  for (int col = 0; col < max_columns; ++col)
  {  string lbl; 
      if (! getline(ss, lbl, ';'))
        return false;  // some error 
      labels.push_back (lbl); 	
  }
  return true;
}

bool parse_data_row (const string & line, double data[max_columns])
{	stringstream iss(line); 
    string temp;

    for (int col = 0; col < max_columns; ++col)
    {  // get one column
        if (! getline(iss, temp, ';'))
          return false;  // some error 
        stringstream convertor (temp);
        convertor >> data[col]; 	
  }
  return true;
}

int main ()
{   vector<string> labels;
    double data[max_rows][max_columns];
    ifstream file("C:\\file.csv");
    string line;

    if (! getline(file, line))
	{   // handle error 
		return 0;
	}
    if (! parse_header_row (line, labels))
	{	// handle error 
		return 0;
	}
    // Now handle the data rows
    for (int row = 0; row < max_rows; ++row)
    {   if (! getline(file, line)) 
		{	// handle the error
			return 0;
		}
        if (! parse_data_row (line, data[row]))
		{	// handle the error 
			return 0;
		}
    }
} 


Note: You're assuming the file has only 25 rows (including the header row) and 41 columns. This may be a valid assumption for the problem at hand, however, a more general solution would accomodate a variable number of rows and columns. Using vectors rather than a fixed array accomodates this flexibility.
Last edited on
Thanks Abstraction,

I would like to include the header row if possible. I am trying to identify letters in the very first row of the array as well as numbers from the first column, but I'm not sure what I should change from your code. The other values in the array are all numbers. I tried changing the number of rows to 25, but it didn't work.
Last edited on
I would like to include the header row if possible

The code I posted saves the column labels from the first row into the labels vector. I have no idea what you want to do with the labels once you've read them.

I am trying to identify letters in the very first row

To what end? What are you trying to do with them. The columns headings are stored as a vector of strings. Very easy to access, but you have to know what you want to do with them.

I am trying to identify letters .. as well as numbers from the first column

If the first column is not numeric (other than the header row), you're going to have to deal with that column separately. You're not going to be able to input it into a double. I thought I remembered seeing a post of your CSV file, showing labels in the first column, but I may be remembering someone else's post.

The code I posted saves the column labels from the first row into the labels vector. I have no idea what you want to do with the labels once you've read them.


Sorry I am completely new to programming. I'm not sure how to display/cout these values from the vector.

If the first column is not numeric (other than the header row), you're going to have to deal with that column separately.

Just to clarify what I'm doing, the program I've made identifies a certain value from a large array. Then it identifies which row and column it's in and uses those values to display the associated header column label (within the first row of letters), and the row label (within the first column of numbers) associated with that value.
Last edited on
Thanks again Abstraction,

I've got it fully working now!
Topic archived. No new replies allowed.