I've created a program that reads different text files and stores each file in its own Vector list. However, the vector list proportion of the program is not working. Provided below is the text file im currently working on as well the program itself
Text file
A:Head:1:2:15.
B:Torso:0:6:5.
C:Leg:0:4:6.
D:Arm:0:4:8.
E:Tail:0:6:2.
Main file
#include <iostream>
#include <string>
#include <conio.h>
#include <stdio.h>
#include "driver.h"
#include "implementation.cpp"
#include <fstream>
#include <vector>
using namespace std;
int main() {
readFile();
writeFile();
robotComplexity();
getch();
return 0;
}
Implementation file containing functions
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <fstream>
#include <vector>
using namespace std;
//declaration of parts variables
char partCode;
std::string partName;
int maximum;
int minimum;
int complexity;
std::vector<string> partsVector;
std::ifstream partsList("Parts.txt");
std::string outputFile = "output.txt";
std::string input;
std::string newChar;
std::stringstream convertChar;
void readFile() //function to read Builders, Customers and Parts text file
{
std::string line;
while (std::getline(partsList, line)) {
line.pop_back();//removing '.' at end of line
std::string token;
std::istringstream ss(line);
convertChar << partCode;
convertChar >> newChar;
// then read each element by delimiter
int counter = 0;//number of elements you read
while (std::getline(ss, token, ':')) {//spilt into different records
switch (counter) {//put into appropriate value-field according to element-count
case 0:
newChar = token; //convert partCode from a char to a string
break;
case 1:
partName = token;
break;
case 2: maximum = stoi(token);
break;
case 3: minimum = stoi(token);
break;
case 4: complexity = stoi(token);
break;
default:
break;
}
counter++;//increasing counter
}
partsVector.push_back(newChar);
for(string x: partsVector)
cout << x << endl;
}
}
double robotComplexity() {
double complexity;
for(int i = 1; i < partsVector.size(); i++)
/*
if(newChar == "A") {
cout << "Character: " << newChar;
} else {
cout << "Program isnt working! :(";
} */
if(complexity > 100) {
complexity = 100;
}
cout << "\nThe Robot Complexity is: " << complexity << endl;
return complexity;
}
double robotVariability() {
double variability;
cout << "\nThe Robot Variability is: " << variability << endl;
return variability;
}
void writeFile() //writes to a file output.txt the end calculations.
{
}
The code that im currently experiencing issues with is the following
while (std::getline(partsList, line)) {
line.pop_back();//removing '.' at end of line
std::string token;
std::istringstream ss(line);
convertChar << partCode;
convertChar >> newChar;
// then read each element by delimiter
int counter = 0;//number of elements you read
while (std::getline(ss, token, ':')) {//spilt into different records
switch (counter) {//put into appropriate value-field according to element-count
case 0:
newChar = token; //convert partCode from a char to a string
break;
case 1:
partName = token;
break;
case 2: maximum = stoi(token);
break;
case 3: minimum = stoi(token);
break;
case 4: complexity = stoi(token);
break;
default:
break;
}
counter++;//increasing counter
}
partsVector.push_back(newChar);
for(string x: partsVector)
cout << x << endl;
}
When this program is compiled and executed, the following is printed out to the console
A
A
B
A
B
C
A
B
C
D
A
B
C
D
E
This is clearly wrong, as it should be printing one of each letter, as required by my program specs.
A
B
C
D
E
The purpose of this is so i know the function can successfully identify Each Record. To note, this occurs with other varialbes such as partName. Ive deducted that it is an issue with how I'm adding the variables to the vector but I am unsure why. Any help would be great Thankyou.
So the problem is simply where you are printing out the partsVector, it's inside your reading loop when it should be after the reading loop. So it should be this
while (std::getline(partsList, line)) {
...
partsVector.push_back(newChar);
}
for(string x: partsVector)
cout << x << endl;
instead of this
while (std::getline(partsList, line)) {
...
partsVector.push_back(newChar);
for(string x: partsVector)
cout << x << endl;
}
Because you are printing the parts vector as you read it in, you get those repeated values displayed.
Related
In the program im currently writing, im up to a stage that requires the use of data that has been read through a file. Some of this data contains number elements, so the proper conversions have been done in order to store them in a vector of type string. Up to this point works.
I have a function called robotComplexity, which calculates a value based on other values found in the file, which have already been added to a vector List(all code shall be posted below). The text file contains the following data.
A:Head:1:2:15.
B:Torso:0:6:5.
C:Leg:0:4:6.
D:Arm:0:4:8.
E:Tail:0:6:2.
As seen in the code below, this file has been split by a dilimiter at the colon and fullstop to first seperate the variables, then the records. The variables have been stored in their respective holders as shown in the code. The function called robotComplexity contains a for loop
for(std::size_t i=0; i< partsVector.size(); ++i) {
if(partsVector[i] == userChoice) {
cout << userChoice << stoi(stringMaximum) << endl;
}
The issues with my Code stem from this for loop. The program is able to loop through the file and recongise the first variable, partCode(converted to newChar) of respective values A,B,C,D,E. So for example when a user enters A it returns A, enters B returns B etc. Now my issues come from trying to print out other variables stored in the vector. In the cout << userChoice...etc line, it successfully returns the Letter(example A) but does not return the correct Value for stringMaximum converted to an int. The returned value is 0 where it should be whatever it equals for a partCode A(in this case)
Im asking if anyone could create/fix my for loop such that when cout << "Variable" is called, it can successfuly print to the console the value of that variable according to the partCode
For Example, if the user enters A as the partcode the output should be
code
cout << userChoice << partName << stringMaximum << stringMinimum << stringComplexity << endl;
output
A
Head
1
2
15
file containing functions
struct Part {
char partCode;
std::string partName;
int maximum;
int minimum;
int complexity;
} myPart;
std::vector<string> partsVector;
std::ifstream partsList("Parts.txt");
std::string outputFile = "output.txt";
std::string input;
std::string newChar;
std::stringstream convertChar;
std::string stringMaximum = std::to_string(myPart.maximum);
std::string stringMinimum = std::to_string(myPart.minimum);
std::string stringComplexity = std::to_string(myPart.complexity);
void readFile() //function to read Builders, Customers and Parts text file
{
std::string line;
while (std::getline(partsList, line)) {
line.pop_back();//removing '.' at end of line
std::string token;
std::istringstream ss(line);
convertChar << myPart.partCode;
convertChar >> newChar;
// then read each element by delimiter
int counter = 0;//number of elements you read
while (std::getline(ss, token, ':')) {//spilt into different records
switch (counter) {//put into appropriate value-field according to element-count
case 0:
newChar = token; //convert partCode from a char to a string
break;
case 1:
myPart.partName = token;
break;
case 2:
myPart.maximum =stoi(token);
break;
case 3:
myPart.minimum = stoi(token);
break;
case 4:
myPart.complexity = stoi(token);
break;
default:
break;
}
counter++;//increasing counter
}
partsVector.push_back(newChar);
partsVector.push_back(myPart.partName);
partsVector.push_back(stringMaximum);
partsVector.push_back(stringMinimum);
partsVector.push_back(stringComplexity);
}
}
double robotComplexity() {
double complexity;
string userChoice;
cout << "Enter a part code A ,B ,C ,D or E" << endl;
cin >> userChoice;
for(std::size_t i=0; i< partsVector.size(); ++i) {
if(partsVector[i] == userChoice) {
cout << userChoice << stoi(stringMaximum) << endl;
}
}
}
Thankyou for any help offered. If any furuther explaination is required please feel free to ask. PS I know global variables aren't the best to use, but once my functions operate correctly I will clean the code up with local variables.
There are several issues here, but your main problem is that
std::string stringMaximum = std::to_string(myPart.maximum);
std::string stringMinimum = std::to_string(myPart.minimum);
std::string stringComplexity = std::to_string(myPart.complexity);
are global variables, and not functions. They will be evaluated only once at the beginning of your program. So your readFile is already broken in the code that you gave us. The first thing I would do is remove the global state (i.e. remove all global variables) and fix the code that doesn't compile anymore.
You do
partsVector.push_back(stringMaximum);
partsVector.push_back(stringMinimum);
in readFile without ever setting those two variables so you always push the same value in your vector.
Next question is, why do you use a vector of string and not a vector of Part? You already parse the file to Part objects, so just use them. Furthermore, you want to access those parts via a user input that queries for Part.partCode, so we can use a lookup table with partCode as a key (std::unordered_map<char, Part> in this case).
All in all this would look like the following (the inner while loop in readFile was a nightmare too, so I removed that aswell):
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>
#include <unordered_map>
struct Part
{
char partCode = 0;
std::string partName;
int maximum = 0;
int minimum = 0;
int complexity = 0;
};
std::stringstream partsList(
R"(A:Head:1:2:15.
B:Torso:0:6:5.
C:Leg:0:4:6.
D:Arm:0:4:8.
E:Tail:0:6:2.)");
std::string outputFile = "output.txt";
std::string input;
std::unordered_map<char, Part> readFile() //function to read Builders, Customers and Parts text file
{
std::unordered_map<char, Part> parts;
std::string line;
while (std::getline(partsList, line))
{
line.pop_back(); //removing '.' at end of line
std::string token;
std::istringstream ss(line);
Part part;
std::getline(ss, token, ':');
part.partCode = token[0];
std::getline(ss, part.partName, ':');
std::getline(ss, token, ':');
part.maximum = std::stoi(token);
std::getline(ss, token, ':');
part.minimum = std::stoi(token);
std::getline(ss, token, ':');
part.complexity = std::stoi(token);
parts.emplace(part.partCode, std::move(part));
}
return parts;
}
double robotComplexity(std::unordered_map<char, Part> const& parts)
{
double complexity = 10;
char partCode;
std::cout << "Enter a part code A ,B ,C ,D or E" << std::endl;
std::cin >> partCode;
auto const& part = parts.at(partCode);
std::cout << part.maximum;
if (complexity > 100)
{
complexity = 100;
}
std::cout << "\nThe Robot Complexity is: " << complexity << std::endl;
return complexity;
}
void writeFile() //writes to a file output.txt the end calculations.
{
}
int main()
{
auto parts = readFile();
writeFile();
robotComplexity(parts);
return 0;
}
I'm trying to complete a program that reads from a file and calculates the GPA. Basically there are 16 sets of data with 3 types in every set - name, grades, and extra points.
Example text:
Bugs Bunny
A B+ B A- B B C+ A B A-
100
The problem I am getting is at the middle part of the string, when taking in the grades. I am trying to read the entire line of grades, then read each grade itself, like "A" then "B+". Basically read "A", the value is 3, add it to an accumulator, then move to the next letter grade until the newline character is reached.
I thought of using .get but that's for taking in values. I don't really understand how to process the grades from the string. I know a loop is used, however.
struct infoTaker
{
string theirName;
string theirGrade;
double theirDonation;
int totalValue;
};
int main( )
{
double donation;
char letter;
ifstream file;
string fullName, actualGrade, substring;
file.open("F://Yes/thing.txt");
for ( int i = 0; i < 16; i ++){
getline( file, fullName ); // getting the names
infoTaker person;
person.theirName = fullName;
cout << person.theirName << endl; // end of names section
getline(file, actualGrade); // gettting the entire line
person.theirGrade = actualGrade; // the string of grades
cout << letter << endl; // Don't know what to do here
file >> donation;
file.ignore( 3 , '\n');
person.theirDonation = donation;
cout << person.theirGrade << endl;
cout << person.theirDonation << endl;
double convertDoodahs = person.theirDonation / 2.0;
}
}
This is one way to do it by adding the contents you read in a file, or you can also just read that certain line of grades. Im guessing this will be more useful because you can then later retrieve the name and other info.
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
int main(){
std::vector<std::string> vec;
std::string temp;
std::string grades;
std::ifstream input("test.txt");
//add them to vector, and access them later
while(getline(input, temp)) vec.push_back(temp);
//read the grades and seperate them
std::stringstream ss(vec[1]);
while(ss >> grades){
std::cout << grades << "\n";
}
}
sample txt file
Bugs Bunny
A B C D+
100
output
A
B
C
D+
#include<iostream>
#include<string>
using namespace std;
int convert(char a,char b='\0')
{
int result = 0;
if(b == '\0')
{
switch(a)
{
case 'A':
result = 9;
break;
case 'B':
result = 9;
break;
case 'C':
result = 9;
break;
}
}else
{
switch(a)
{
case 'A':
if(b=='+')
result = 10;
else
{
result = 8;
}
break;
case 'B':
if(b=='+')
result = 10;
else
{
result = 8;
}
break;
case 'C':
if(b=='+')
result = 10;
else
{
result = 8;
}
break;
}
}
return result;
}
int getSum(string g)
{
int ans = 0;
int l = g.length();
for(int i=0;i<l;)
{
char a = g[i++],b='\0';
if(g[i]=='+'||g[i]=='-')
{
b = g[i++];
}
ans+=convert(a,b);
i++;
}
return ans;
}
int main()
{
string g = "A B+ B A- B B C+ A B A-";
int sum = getSum(g);
}
try this...
Im sorry about posting a super long code, but when I run this code all I see is this-
Heap size: 1638652
Getting int:
Getting int:
Getting int:
Getting int:
Getting int:
Heap size: 1638653
and it keeps going in a loop with the heapsize being incremented by one.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <exception>
#ifndef WX_REPORT_H
#define WX_REPORT_H
#include <string>
#include <sstream>
using std::string;
using std::stringstream;
typedef struct WX_REPORT
{
string unitType;
string stationName;
string time;
string gpsLoc;
int pressure;
int windSpeed;
int temperature;
int humidity;
int windDirection;
string toString()
{
stringstream str;
str << stationName << ": " << time << "\t" << gpsLoc << "\n";
str << pressure << "\n" << windSpeed << "\n" << temperature << "\n";
str << humidity << "\n" << windDirection;
return str.str();
}
}
WXReport;
#endif
/*
* Reports must be in the following format:
* M or I // Metric or imperial units
*/
using namespace std;
vector<WXReport*> heap;
bool compTime(const WXReport* a, const WXReport* b) {
if(a->time < b->time) { // timing
return false;
} else {
return true; // commands to return true
}
}
void heapAdd(WXReport* wx) {
heap.push_back(wx);
push_heap(heap.begin(), heap.end());
}
WXReport* heapPop() { // header popup
pop_heap(heap.begin(), heap.end());
WXReport* rep = heap.back();
heap.pop_back();
return rep;
}
void getInt(istream &input, int &i) {
string temp;
input>>temp;
cout<<"Getting int: "<<temp<<endl;
i = atoi(temp.c_str());
}
void readInFile(string filename) {
ifstream input(filename);
WXReport *report;
while(!input.eof()) {
report = new WXReport();
getline(input, report->unitType);
getline(input, report->stationName);
getline(input, report->time);
getline(input, report->gpsLoc);
getInt(input, report->pressure);
getInt(input, report->windSpeed);
getInt(input, report->temperature);
getInt(input, report->humidity);
getInt(input, report->windDirection);
heapAdd(report);
cout<<"Heap size: "<<heap.size()<<endl;
}
}
int menu() {
cout<<"\n\nPlease select one: "<<endl;
cout<<"1) Read in another file"<<endl;
cout<<"2) Display the fastest wind speed"<<endl;
cout<<"3) Display weather stations by name"<<endl;
cout<<"4) Display all weather reports"<<endl;
cout<<"5) Remove a weather report"<<endl;
cout<<"6) Write weather reports to file"<<endl;
cout<<"0) Exit"<<endl;
int choice;
cin>>choice;
return choice;
}
void printAllReports() {
cout<<"Printing all reports"<<endl;
for(WXReport* rep: heap) {
cout<<rep->toString()<<endl;
}
cout<<"Done printing reports"<<endl;
}
int main(int argc, char* argv[]) {
string filename = "report.txt";
readInFile(filename);
int choice = menu();
while(choice != 0) {
switch(choice) {
case 1:
cout<<"What file would you like to read in?"<<endl;
cin>>filename;
readInFile(filename);
break;
case 2:
cout<<"Has not been implemented"<<endl;
break;
case 3:
cout<<"Has not been implemented"<<endl;
break;
case 4:
printAllReports();
break;
case 5:
cout<<"Has not been implemented"<<endl;
break;
case 6:
cout<<"Has not been implemented"<<endl;
break;
default:
cout<<"Invalid choice, please try again."<<endl;
}
choice = menu();
}
cout<<"Thank you!"<<endl;
return 0;
}
Important part. If you read nothing else, read this: Always check the error codes and return values.
After ifstream input(filename); you have no idea if the file opened. Testing with input.is_open() gets past that.
If the file isn't open, all those calls to getline fail as does eof(). File not open, can't read end of file and can't exit loop. Even if the the file is open, if you don't check the output of getline, how do you know you read a line?
One of the fun parts of streams is if you test the stream, it tells you if it is in a bad state, so you can write code that looks like
if (getline(...) && getline(...) && ...)
So you don't have to make a massive block of if-else-if or a sea of nested ifs. First bad read and you are out.
The problem with if eof() is covered in the comments to the question. The basic is you don't know if you got the end of the file until you start reading. Also, what happen if you hit the end of the file in the middle of a bunch of reads?
So read a line. If it's good, read the next line, etc... until done.
getInt isn't necessary.
int val;
input >> val;
loads an integer into val, if the stream can be parsed into an int. If it can't, input is marked bad and you can check why. Could be unparsable. Could be end of file.
int val;
if (input >> val)
{
//do stuff
}
else
{
//no int here. Do other stuff
}
Just like above, you can chain the instructions and get
if (input >> val >> anotherval >> ...)
I have a file of format as:
2
3 4
7 8 9
10 20 22 02
...
basically numbers in each line , separated by spaces.
I have to read from the file, extract all numbers and maintain their line number too, as I have to make a tree later. I'm doing this to take input, but getting weird outputs.
#include<cstdio>
#include<iostream>
#include<cctype>
using namespace std;
void input()
{
char c,p;
while(c=getchar()!=EOF)
{
if(c=='\n') printf("},\n{");
else if(c==' ') printf(",");
else if(c=='0')
{
p=getchar();
if(p==' ')
{
printf("%c%c,",c,p);
}
else
{
printf("%c,",p);
}
}
else if(isalpha(c))
{
printf("%c",c);
}
}
}
int main()
{
input();
}
The image shows the input and output
You are writing more C than C++.
In C++ you can use streams. Use peek() to check the next character, and >> to actually read it.
E.g.:
using namespace std;
int main(){
ifstream s("/tmp/input");
int nr;
while (!s.eof()) {
switch (s.peek()){
case '\n': s.ignore(1); cout << "},\n{"; break;
case '\r': s.ignore(1); break;
case ' ': s.ignore(1); cout << ", "; break;
default: if (s >> nr) cout << nr;
}
}
}
Use a file stream, read line by line and parse each line with a stringstream:
std::ifstream file("filename");
std::string line;
size_t line_number(1);
while ( std::getline(file, line) ) // reads whole lines until no more lines available
{
std::stringstream stream(line);
int tmp;
std::cout << "Numbers in line " << line_number << ":";
while ( stream >> tmp ) // reads integer divided by any whitespace until no more integers available
{
std::cout << " " << tmp;
}
std::cout << "\n";
++line_number;
}
You'll need to include
#include <iostream> // for std::cout
#include <string> // for std::string
#include <fstream> // for std::ifstream
#include <sstream> // for std::stringstream
I'm working on this project and I'm fairly new to C++. Its kind of hard to explain what I'm trying to do but I shall try. So I'm working with a file called flix.txt and in it looks like the following:
1 A 5
1 B 4
1 D 3
1 F 5
2 A 1
3 E 3
3 F 1
4 A 2
The first column are people(my objects), second columns are movies, and the third are the ratings given by the objects.
I'm trying to first extract the first int from every line and create an object using an 'operator new'. Then I'm taking a movie and turning it into an int so I can plug the rating into an array. Sorry if it sounds confusing. Heres the code I have now:
//flix program
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#define NUMBER_OF_MOVIES 6
using namespace std;
int tokenize(string line);
int getMovieNum(char movie);
void resetPos(istream& flix);
class Matrix{
public:
int movieRate[NUMBER_OF_MOVIES];
};
int main(){
int distinctCount = 0;
int checker = -1;
int check = 0;
string line;
int personNum;
char movie;
int rating;
int movieNum;
ifstream flix("flix.txt");
ofstream flick("flix1.txt");
//identify distinct account numbers in file
while(getline(flix, line)){
check = tokenize(line);
if(check != checker)
distinctCount++;
checker = check;
check = 0;
}
//reset position in file
resetPos(flix);
//create objects in accordance with distinct numbers
Matrix* person = new Matrix[distinctCount];
for(int i = 0; i < distinctCount; i++){
for(int j = 0; j < NUMBER_OF_MOVIES; j++){
person[i].movieRate[j] = 0;
cout << i + 1 << ' ' << person[i].movieRate[j] << endl;
}
cout << "\n";
}
//reset position in file
resetPos(flix);
//get data from file and put into respective variables
while(getline(flix, line)){
flix >> personNum >> movie >> rating;
cout << personNum << ' ' << movie << ' ' << rating << endl;
//changes the char into an int
movieNum = getMovieNum(movie);
person[personNum].movieRate[movieNum] = rating;
}
//reset position in file
resetPos(flix);
//input ratings into movie array
for(int i = 0; i < distinctCount; i++){
for(int j = 0; j < NUMBER_OF_MOVIES; j++){
cout << i + 1 << ' ' << person[i].movieRate[j] << endl;
flick << i + 1 << ' ' << person[i].movieRate[j] << endl;
}
}
//write data to text file
//??
flick.close();
//free memory
delete[] person;
system("pause");
return 0;
}
int tokenize(string line){
string myText(line);
istringstream iss(myText);
string token;
getline(iss, token, ' ');
int strInt = atoi(token.c_str());
return strInt;
}
int getMovieNum(char movie){
int movieNum = 0;
switch(movie){
case 'A':
movieNum = 1;
break;
case 'B':
movieNum = 2;
break;
case 'C':
movieNum = 3;
break;
case 'D':
movieNum = 4;
break;
case 'E':
movieNum = 5;
break;
case 'F':
movieNum = 6;
break;
default:
movieNum = 0;
break;
}
return movieNum;
}
void resetPos(istream& flix){
flix.clear();
flix.seekg(0);
}
I also apologize in advance if there are noobish mistakes here.
I think the problem is somewhere in the while loop, that's where it keeps locking up. I spent hours on this and I can't figure out why it doesn't work. In the while loop, I'm trying to access every line of the file, snag the data from the line, take the movie char and turn it into an int, and then plug the data into the array within the object. When I did have it working, all the data was wrong too. Any input is highly appreciated. Thanks in advance.
You need to change a little in your program and i'l paste only the changed part.
Somewhere after you reset the person[].movieRate[] to zero,you have written this while loop
resetPos(flix);
int k = NUMBER_OF_MOVIES + 2; //this is the variable that i have declared
//get data from file and put into respective variables
while(k){ //do you see that instead of getline() i have used the variable k. i'l tell you why later
flix >> personNum >> movie >> rating;
//personNum = tokenize(line,1);
cout << personNum << ' ' << movie << ' ' << rating << endl;
//changes the char into an int
movieNum = getMovieNum(movie);
person[personNum - 1].movieRate[movieNum] = rating; //this is personNum-1 and NOT personNum the most common mistake while indexing array.
k--;
}
this code seems to work as your criteria.
the reason that i removed getline() is, if u call getline then the get pointer position will be incremented. so after this you call flix >> something... , this reads the data from the second line. your first line 1 A 5 is lost. this was the cause of the trouble. change it n let me know.
Okay, let me try to give at least some idea of a simple starting point:
#include <iostream>
#include <iterator>
#include <vector>
#include <fstream>
struct rater {
std::vector<int> ratings;
rater() : ratings(6) {}
friend std::istream &operator>>(std::istream &is, rater &r) {
char movie;
is >> movie;
return is >> r.ratings[movie-'A'];
}
friend std::ostream &operator<<(std::ostream &os, rater const &r) {
for (int i=0; i<r.ratings.size(); i++) {
os << char(i + 'A') << ":" << r.ratings[i] << "\t";
}
return os;
}
};
int main() {
std::ifstream in("flix.txt");
std::vector<rater> ratings(5);
int i;
while (in >> i)
in >> ratings[i-1];
i=1;
for (auto r : ratings)
std::cout << i++ << "-> " << r << "\n";
}
Here's a bit of a clean up. It uses std::map to keep track of the Person and Movie keys, which is more flexible as textual strings of any kind (sans whitespace) can be used. You've added a comment saying you specifically want to list movies people didn't rate in their outputs - that can be done by using a std::set and ensuring each movie name encountered is inserted, then using an iteration over the set to guide lookups in each person's ratings: left as an exercise.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <map>
using namespace std;
typedef std::map<std::string, int> Movie_Ratings;
typedef std::map<std::string, Movie_Ratings> Persons_Movie_ratings;
int main()
{
if (!ifstream flix("flix.txt"))
{
std::cerr << "error opening input\n";
exit(1);
}
if (!ofstream flick("flix1.txt"))
{
std::cerr << "error opening output\n";
exit(1);
}
Persons_Movie_Ratings ratings;
std::string line;
while (getline(flix, line))
{
istringstream iss(line);
string person, movie;
int rating;
if (line >> person >> movie >> rating)
ratings[person][movie] = rating;
}
// input ratings into movie array
for (Persons_Movie_Ratings::const_iterator i = ratings.begin();
i != ratings.end(); ++i)
{
for (Movie_Ratings::const_iterator j = i->second.begin();
j != i->second.end(); ++j)
{
cout << i->first << ' ' << j->second << endl;
flick << i->first << ' ' << j->second << endl;
}
}
system("pause");
}