File input/output and reading in a line - c++

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.

Related

Reading from multiple lines from a txt file in a single iteration

I am working at the moment with linked lists, and my nodes have 4 elements( where each of them is a variable type string). In a .txt file there are groups of text where each group has 4 lines, for example:
This is the first line
This is the second line
This is the third line
This is the fourth line
'\n'
This is the fifth line
This is the sixth line
This is the seventh line
This is the eighth line
and so on and so on...
What I'm trying to achieve is reading the four lines in a single iteration and give them to a node, and let the program iterate until there is no more lines.
So if reading the example above our nodes will be left with;
Node1.string1 = This is the first line;
Node1.string2 = This is the second line;
Node1.string3 = This is the third line;
Node1.string4 = This is the fourth line;
While looking for a way to do this on internet, I found one way you can do this and tell the "ifstream reader" to do a '\n' before the next iteration, but I lost this page and cant seem to find it
Easy enough
while (getline(in, node.string1) &&
getline(in, node.string2) &&
getline(in, node.string3) &&
getline(in, node.string4))
{
...
string dummy;
getline(in, dummy); // skip blank line
}
You can also use in.ignore(std::numeric_limits<std::streamsize>, '\n'); to skip the blank line, but reading into a dummy variable allows you to easily check if the blank line really is blank.

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.

Printing duplicate strings and how many times they appear in a file C++

Here is the question I have to solve and the code I've written so far.
Write a function named printDuplicates that accepts an input stream and an output stream as parameters.
The input stream represents a file containing a series of lines. Your function should examine each line looking for consecutive occurrences of the same token on the same line and print each duplicated token along how many times it appears consecutively.
Non-repeated tokens are not printed. Repetition across multiple lines (such as if a line ends with a given token and the next line starts with the same token) is not considered in this problem.
For example, if the input file contains the following text:
hello how how are you you you you
I I I am Jack's Jack's smirking smirking smirking smirking smirking revenge
bow wow wow yippee yippee yo yippee yippee yay yay yay
one fish two fish red fish blue fish
It's the Muppet Show, wakka wakka wakka
My expected result should be:
how*2 you*4
I*3 Jack's*2 smirking*5
wow*2 yippee*2 yippee*2 yay*3
\n
wakka*3
Here is my function:
1 void printDuplicates(istream& in, ostream& out)
2 {
3 string line; // Variable to store lines in
4 while(getline(in, line)) // While there are lines to get do the following
5 {
6 istringstream iss(line); // String stream initialized with line
7 string word; // Current word
8 string prevWord; // Previous word
9 int numWord = 1; // Starting index for # of a specific word
10 while(iss >> word) // Storing strings in word variable
11 {
12 if (word == prevWord) ++numWord; // If a word and the word 13 before it are equal add to word counter
14 else if (word != prevWord) // Else if the word and the word before it are not equal
15 {
16 if (numWord > 1) // And there are at leat two copies of that word
17 {
18 out << prevWord << "*" << numWord << " "; // Print out "word*occurrences"
19 }
20 numWord = 1; // Reset the num counter variable for next word
21 }
22 prevWord = word; // Set current word to previous word, loop begins again
23 }
24 out << endl; // Prints new line between each iteration of line loop
25 }
26 }
My result thus far is:
how*2
I*3 Jack's*2 smirking*5
wow*2 yippee*2 yippee*2
I have tried adding (|| iss.eof()), (|| iss.peek == EOF), etc inside the nested else if statement on Line 14, but I am unable to figure this guy out. I need some way of knowing I'm at the end of the line so my else if statement will be true and try to print the last word on the line.

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

read file 1 line at a time with variable amount of data on each line

I have a question on how to read data from my input .dat file using isstream to be used as a chord implementation
I have inputs of various lengths and type. an example of my input is shown below:
addC 2 #ignore this msg
addC 3 #ignore this msg
addC 9 #ignore this msg
print 9
insert 2 data0
insert 9 data1
insert 3 data2
I would like to capture each input line by line, ignoring any msg behind # key.
What I've done till yet is as follows:
if (myfile.is_open())
{
while (getline(myfile, line))
{
string command;
string id;
string input;
unsigned int hashKey = 0;
istringstream iss(line);
getline(iss, command, ' ');
getline(iss, number, ' ');
getline(iss, message, '#');
//other codes
}
}
however, when i read in my file, it seems that it somehow reads in more then required at times. for example,
//first few commands up till insert 0 is fine
command = insert number = 2 input = data0
INSERTING data0 at: 2
command = insert number = 9 input = data1
command = insert number = 3 input = data2
//program stops here due to some fault in reading i believe