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

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

Related

How to make c++ using cin optional?

I want to allow user to input three strings from the keyboard. For example, firstname, lastname and middle name. The middle name is optional.
The code sample below:
cout << "Enter your name, first name then middle name and last name (Ex: Abby Scuito S): ";
char lastName[21], firstName[21], middleName[21];
cin >> lastName >> firstName >> middleName;
The problem is that it always ask for middle name input when the third block is missing which is correct based on how cin works. The problem is that I cannot figure out how to make it optional.
For example,
Input 1: Abby Scuito A => Output: Abby Scuito A
Input 2: Abby Scuito => Output: Abby Scuito
Read the data into a single string and separate them by space.
You may have to do some filtering, but you'll get the idea.

Reading specific column from .csv in 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"

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.

File input/output and reading in a line

So basically what my code wants me to do is read in from a file a line
Movie name MPAA Rating Rating 1 Rating 2 Rating 3 Rating 4 Rating 5
I have this line of code that does that
file1 >> movieName >> mpaa >> rating1 >> rating2 >> rating3 >> rating4 >> rating5;
Example input(from first line in file):
Frozen PG13 1 2 3 4 5
That works perfectly.
But if I were to put in something like:
Peter Pan PG 1 2 3 4 5
I would get an error because it would try to put Pan in for mpaa and rating 1 would be PG and so on.
How do I get that code to recognize the space?
Change your separator to something else like commas, and try the following:
getline(file1, moveName, ',');
getline(file1, mpaa, ',');
// etc
If you need to read line by line and make sure each line is correct, you might want to first read the line with getline(file1, line), and then use the string to initialize an istringstream to extract the comma separated values from.

C++ cin whitespace question

Programming novice here. I'm trying to allow a user to enter their name, firstName middleName lastName on one line in the console (ex. "John Jane Doe"). I want to make the middleName optional. So if the user enters "John Doe" it only saves the first and last name strings. If the user enters "John Jane Doe" it will save all three.
I was going to use this:
cin >> firstName >> middleName >> lastName;
then I realized that if the user chooses to omit their middle name and enters "John Doe" the console will just wait for the user to enter a third string... I know I could accomplish this with one large string and breaking it up into two or three, but isn't there a simpler way to do it with three strings like above?
I feel like I'm missing something simple here...
Thanks in advance.
Use getline and then parse using a stringstream.
#include <sstream>
string line;
getline( cin, line );
istringstream parse( line );
string first, middle, last;
parse >> first >> middle >> last;
if ( last.empty() ) swap( middle, last );