Reading specific column from .csv in C++ - c++

I have a .csv file that has around 5 rows and it looks something like this:
"University of Illinois, Chicago","1200, West Harrison","41.3233313","88.221376"
The first column is the name of the building, the second is the address and the third and fourth column represent the latitude and longitude.
I want to take only the values in the 3rd and 4th column for every row.
If I use the getline method and separate every entry with , I do not get the desired result. Here is a sample of what I am doing:
ifstream file("Kiosk Coords.csv");
double latt[num_of_lines];
double longg[num_of_lines];
string name;
string address;
string latitude;
string longitude;
flag = 0;
while(file.good()){
getline(file,name,',');
getline(file,address,',');
getline(file,latitude,',');
getline(file,longitude,'\n');
//cout<<name<<" "<<address<<" "<<latitude<<" "<<longitude<<endl;
cout<<longitude<<endl;
}
For the above given input, I get the following values in the variable if I use my method:
name = "University of Illinois"
address = "Chicago
latitude = "1200"
longitude = "West Harrison,41.3233313,88.221376"
What I specifically want is this:
latitude = "41.3233313"
longitude = "88.221376"
Please help

C++14's std::quoted to the rescue:
char comma;
file >> std::quoted(name) >> comma // name: University of Illinois, Chicago
>> std::quoted(address) >> comma // address: 1200, West Harrison
>> std::quoted(latitude) >> comma // latitude: 41.3233313
>> std::quoted(longitude) >> std::ws; // longitude: 88.221376
DEMO

I think you have to manually parse it. Given that all elements are wrapped in quotes, you can easily extract them by just looking for the quotes.
Read a whole line then look for a pair quotes, and take the content between them.
std::string str;
std::getline(file, str);
std::vector<std::string> cols;
std::size_t a, b;
a = str.find('\"', 0);
while (true) {
b = str.find('\"', a + 1);
if (b != std::string::npos){
cols.push_back(str.substr(a, b-a));
}
a = str.find('\"', b + 1);
}
Results (double quote included):
cols[0]: "University of Illinois, Chicago"
cols[1]: "1200, West Harrison"
cols[2]: "41.3233313"
cols[3]: "88.221376"

Related

Separately reading a word like "a-b-" from a text file and deleting

The first question is I have code like this for reading from the text file:
File >> product.projectNo >> product.date
>> product.productNo >> product.productQ
>> product.productTotalPrice;
And I write productNo, productQ and productTotalPrice to the file, separated by - because there can be more than one. Here is an example of the text file:
17 5 17-7051-10- 9-8-11- 720-616-55-
The last one 720-616-55- (productTotalPrice) is a list of prices. I need to read them separately and add them. So: 720+616+55. How can I do that?
The second question is I need to delete any of them, meaning productNo 17-7051-10-, needs to delete 17-. How can I do this?
The first part of your problem is reading each word from your file. This can be done using:
std::string word0, word1;
std::getline(file, word0, ' ');
std::getline(file, word1, ' ');
...
Of course, the above code assumes that there is exactly one ' ' is being used as a separator between words.
The next problem is parsing your prices. This can be done using std::stoi:
size_t index;
int price0 = `std::stoi(word, &index);
word = word.substr(index + 1);
int price1 = `std::stoi(word, &index);
word = word.substr(index + 1);
int price2 = `std::stoi(word);
int totalPrice = price0 + price1 + price2;
This works because std::stoi returns the index of the first character which is not part of the integer. So this would be the - separator between your numbers.
As for the second part of your question: You wouldn't delete 17- as a string. Instead you should simply ignore the 17 before adding it onto the sum or you should remove it from the list of numbers after parsing.

Read elements from a txt file that are separeted by a character

I'am working on a program where there are first names, last names and a numbers on a file and i need to read that information into my program. My actual problem is that there is people who doesnt have a second name or second last name. To solve the issue I started trying to read from a file until a specific character is found, For example:
Robert, Ford Black,208 //Where Robert is the first name, and Ford Black are his two last names
George Richard, Bradford,508 //Where George Richard are both his first names, and Bradford is his only last
name
I am saving this information in three separeted string, one that will store first and second name, first last and second last name and the third one for the numbers.
I'm trying to only use native libraries from c++.
I've been reading that getline(a,b,c) and IStringStream can actually solve my problem but I don't know how to correctly implement it
It's just a matter of using std::getline with a delimiter character to read out of the string stream. See a simplified example (no error checking) below:
for (std::string line; std::getline(std::cin, line); )
{
std::string firstName, lastName;
std::istringstream iss(line);
std::getline(iss, firstName, ','); // A comma delimits end-of-input
iss >> std::ws; // Skip over any whitespace characters
std::getline(iss, lastName); // Read remaining line
std::cout << "First Name: " << firstName << std::endl;
std::cout << "Last Name: " << lastName << std::endl;
}
Note the line iss >> std::ws; using std::ws from <iomanip> is there to eat up extra whitespace characters (which appear after your comma, in your example).
I'm assuming the C++ line comments in the input are only an annotation for this question, and not part of the actual input.
#include<bits/stdc++.h>
using namespace std;
int main()
{
ifstream myfile("files.txt");
string fullname;
while(getline(myfile,fullname,'/')) break; //here im reading till the first / is acquired and the entire string is stored in "fullname"
string firstname,lastname;
size_t pos=fullname.find(',');
firstname=fullname.substr(0,pos); //store the firstname
lastname=fullname.substr(pos+1);// storee the lastname
cout<<firstname<<" "<<lastname;
}
As the question posed was to read names im assuming before the digit if there were a " / " you can read upto the first occurance of /. this will give you the fullname. Then using the substr on the fullname and find the occurance of a comma if at all it exists. All the characters to the left of position of comma will form your first name and the rest on the right of the position of comma will form the lastname.

Split String into 2 sub strings on first occurrence of comma?

I am trying to split String in to 2 sub_strings on the first appearance of comma character.
Also the first occurred comma must be removed.
Example :
Suppose this is the string
Manhattan Ave, Brooklyn,NY,USA
dividing this into this
Manhattan Ave
Brooklyn,NY,USA
also to note that first comma has been removed.
and finally saving these sub_string into variables.
String Place = "Manhattan Ave, Brooklyn,NY,USA";
String result_1 = Place.substring(0, Place.indexOf('.'));
String result_2 ="";
You can try this,
String place = "Manhattan Ave, Brooklyn,NY,USA";
int index = place.indexOf(',');
String result1 = place.substring(0,index).trim();
String result2 = place.substring(index+1).trim();

C++ : Pick portions/data from a string having fixed format

I have a string with some fixed format. Let's say :
This is 24 day of Aug of 2016
So, is there a simple way in C++ (similar to strtol in C), so that I can extract the data into variables as below :
day = 24;
month = "Aug";
year = 2016;
You can accomplish this with a std::stringstream. You can load the string into the stringstream and then read it into the variables that you want. It will do the conversions for you into the data types that you are using. For example you could use
std::string input = "This is 24 day of Aug of 2016";
std::stringstream ss(input)
std::string eater; // used to eat non needed input
std::string month;
int day, year;
ss >> eater >> eater >> day >> eater >> eater >> month >> eater >> year;
It looks a little verbose but now you don't need to use find and substr and conversion functions.
You can use the substr() function.
Sample code snippet as below:
string str = "This is 24 day of Aug of 2016";
std::string day = str.substr (8,2); //day = 24
std::string month = str.substr (18,3); //month = Aug
std::string year = str.substr (25,4); //year = 2016
The first parameter of substr() is the start position of the substring; while the second parameter specifies the number of characters to be read from that position.

C++ Reading tab-delimited input and skipping blank fields

I am making a program that will take a long string of tab-delimited metadata pasted into the console by the user and split them into their correct variables. I have completed the code to split the line up by tab, but there are empty fields that should be skipped in order to put the correct metadata into the correct string variable, which I can't get to work.
Here is the code that I have so far:
string dummy;
string FAImport;
cin.ignore(1000, '\n');
cout << "\nPlease copy and paste the information from the finding aid and press Enter: ";
getline(cin, FAImport);
cout << FAImport;
stringstream ss(FAImport);
auto temp = ctype<char>::classic_table();
vector<ctype<char>::mask> bar(temp, temp + ctype<char>::table_size);
bar[' '] ^= ctype_base::space;
ss.imbue(locale(cin.getloc(), new ctype<char>(bar.data())));
ss >> coTitle >> altTitle >> description >> dateSpan >> edition >> publisher >>
physicalDescription >> scale >> extentField >> medium >> dimensions >> arrangement >>
degree >> contributing >> names >> topics >> geoPlaceNames >> genre >> occupations >>
functions >> subject >> langIN >> audience >> condition >> generalNotes >> collection >>
linkToFindingAid >> source >> SIRSI >> callNumber;
checkFAImport(); //shows the values of each variable
cout << "\n\nDone";
With this code, I get this output after inputing the metadata:
coTitle = William Gates photograph with Emiliano Zapata
altTitle = 1915
description = 1915
datespan = Electronic version
edition = 1 photograph : sepia ; 11 x 13 cm
publisher = L. Tom Perry Special Collections, Harold B. Lee Library, Brigham Young University
physicalDescription = Photographs
scale = William Gates papers
extentField = http://findingaid.lib.byu.edu/viewItem/MSS%20279/Series%2011/Subseries%205/Item%20979/box%20128/folder%2012
medium = William Gates photograph with Emiliano Zapata; MSS 279; William Gates papers; L. Tom Perry Special Collections; 20th Century Western & Mormon Manuscripts; 1130 Harold B. Lee Library; Brigham Young University; Provo, Utah 84602; http://sc.lib.byu.edu/
dimensions = MSS 279 Series 11 Subseries 5 Item 979 box 128 folder 12
arrangement =
degree =
contributing =
names =
topics =
geoPlaceNames =
genre =
occupations =
functions =
subject =
langIN =
audience =
condition =
generalNotes =
collection =
linkToFindingAid =
source =
SIRSI =
callNumber =
In this example, fields like altTitle and description should be blank and skipped. Any help would be much appreciated.
You've solved the issue with spaces in the fields in an elegant manner. Unfortunately, operator>> will skip consecutive tabs, as if they were one single separator. So, good bye the empty fields ?
One easy way to do it is to use getline() to read individual string fields:
getline (ss, coTitle, '\t');
getline (ss, altTitle, '\t');
getline (ss, description, '\t');
...
Another way is