So we have a text file with the following data:
Year - Make - Model - Price
2011 Chevrolet Tahoe $30588
There is only 1 space between everything. There is a Dollar Sign ($) in front of the price. We still have to have miles in our code, even if it's not in the data file. I don't know why.
How would I go about getting this information from a text file?
I have tried a bunch of methods, and none of them seem to work.
Here is the code that grabs the information:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <ctime>
#include "car.h"
using namespace std;
const int number=3;
const int maxPrice=25000;
int main()
{
int a;
string b; string c;
float d;
float e;
car cars [number];
int i, j;
float temp; //Price
int temp2; //Year
string temp3; //Make
string temp4; //Model
float temp5; //Miles
ifstream inFile; //declaring the File
inFile.open("carData.txt");
for(i=0; i<number; i++)
{
//cout << "Enter the YEAR of the car: ";
inFile >> a;
cars[i].setYear(a);
//cout << "Enter the MAKE of the car: ";
getline(inFile,b);
cars[i].setMake(b);
//cout << "Enter the MODEL of the car: ";
getline(inFile,c);
cars[i].setModel(c);
//cout << "Enter the number of MILES on the car: ";
inFile >> d;
cars[i].setMiles(d);
//cout << "Enter the PRICE of the car: ";
inFile >> e;
cars[i].setPrice(e);
//cout << " " << endl;
}
// ...
}
The main continues much further than that, this is just to getline all of the data. I've really been having trouble with this all day. I've seen so many different methods.
If you used a standard parsing function, such as std::fscanf, then you could
take away a lot of your pain. You can find out more about *scanf() and friends
from http://en.wikipedia.org/wiki/Scanf_format_string and http://www.cplusplus.com/reference/cstdio/fscanf/.
I normally write C (or python, i'm not choosy ;>) so I'd come up with something
like this:
infile = open("datafile");
res = 0;
while (res != EOF) {
res = fscanf(infile, "%d %d %s %s %d",
&price, &year, &model, &model, &miles);
if (res < 0) {
/* error condition from fscanf() */
(void) fprintf(stderr, "error (%d) from fscanf: %s\n",
res, strerror(res));
exit(res);
}
}
[BTW, the reason exercises like these typically require 'miles' (which are
featured in the data snippet you gave, it's missing the final column) is because
they usually want you to build on these for ranking the cars based on miles or
km travelled vs price vs age].
Ok, so I know it is a bit late but here is a way to achieve your desired results, if you haven't done it already, in c++
The problem is that std::getline will put in the argument string the whole line
So if you have something like this
std::getline(inFile, temp3)
The temp3 will have the value: "Year - Make - Model - Price".
This also sets the cursor to the next line so if you repeat the function
std::getline(inFile, temp3)
then temp3 will be equal to "" as the line after the first is empty(at least in the file that you used as an example).
Now to work around this you need to use a stringstream that is a stream but reads it's values from a , drum rolls please, string.
So the basic idea is this:
1->Go to the line that contains the information
2->Use a stringstream to read the data()
Here is an implementation of that idea:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
int a;
string b; string c;
float d;
float e;
//This assumes that the array is correctly initialized
car cars [number];
string tempLine;
ifstream inFile;
inFile.open("carData.txt");
//get the cursor past the first line that contains the column names
std::getline(inFile, tempLine)
//get the cursor past the second line that is blank
std::getline(inFile, tempLine)
//Now we are at the line that interests us
//I am assuming that the next lines don't have a blank line between them
unsigned int = 0;
int numberOfMiles;
while(std::getline(inFile, tempLine) && i<number)
{
std::stringstream iss(tempLine)
string tempPrice; //this will be the price value with the dollar sign
//you can also write in expanded form this read, but this works just fine
iss>>a>>b>>c>>numberOfMiles>>tempPrice; //notice that the price is now a string
tempPrice.erase(0,1)//this eliminates the dollar($) sign
std::stringstream iss1(tempPrice)//new stringstream as we need to read this string
iss1>>temp;//I believe this is your price variable
cars[i].setYear(a);
cars[i].setMake(b);
cars[i].setModel(c);
cars[i].setMiles(numberOfMiles);
cars[i].setPrice(temp); //i am assuming that this is how the function in called
i++;
}
}
Hope this helps.
Related
I have created a .txt file which a sample would be like this:
Item 1 $1.00
Item # $2.00
Item & $3.50
Item ( $0.30
If I want to ask the user to input the item they want and find the price, how can I do that?
I have tried using .find() to solve the problem, but it didn't work because array cannot use .find().
I'm new to C++, please explain.
#include <array>
#include <string>
#include <fstream>
using namespace std;
string product;
ifstream file("Item.txt");
int main(){
cout << "Enter item you want" << endl;
cin >> product;
file.open("Item.txt", fstream::ate);
findItem.find((file.begin(),file.end(), product) + 1);
cout << findItem << endl;
file.close();
}
Here's a sample code fragment to search your file:
std::string text_line;
while (std::getline(file, text_line))
{
std::string text_item;
std::string item_name;
char dollar_sign;
double price;
std::istringstream text_stream(text_line);
text_stream >> text_item >> item_name >> dollar_sign >> price;
if (product == item_name)
{
std::cout << "Found item\n";
break;
}
}
The usual method is to create a class that models the input line, then overload operator>> to read from a stream.
Notes: 1) commas separating fields would make reading easier; 2) Remove the dollar sign to make reading easier.
So, I am trying to implement a function that can read a file and save some variables to it. The text file will look like this
- Account Number: 12345678
- Current Balance: $875.00
- Game Played: 2
- Total Amount Won: $125.00
- Total Amount Loss: $250.00
So far, I am able to read the account number but when I try to read the rest using the same method, nothing gets outputted to the console.
Here is my progress so far.
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inFile;
int accNum;
string accID;
int games;
double balance;
double amountWon, amountLost;
// Check if file with account number exists
cout << "Please enter account number: ";
cin >> accNum;
// Append correct format to string
accID.append("acc_");
accID.append(to_string(accNum));
accID.append(".txt");
// Open the file
inFile.open(accID);
// Check if the account number exists
if (!inFile)
{
cout << "Account number does not exist.\n";
}
int num;
string str, str2, str3;
// Read through the file
while (inFile >> str >> str2 >> str3 >> num)
{
cout << num << " ";
}
return 0;
}
When I run this code, I can get the account number to be output, but when I try adding more variables to read through the rest of the file nothing gets output to console.
You can use std::getline to read the rest of the file as shown below:
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
int accNum;
string accID;
int games;
double balance;
double amountWon, amountLost;
// Check if file with account number exists
cout << "Please enter account number: ";
cin >> accNum;
// Append correct format to string
accID.append("acc_");
accID.append(to_string(accNum));
accID.append(".txt");
std::cout<<accID<<std::endl;
// Open the file
ifstream inFile(accID);
if(inFile)
{
std::string strDash,strTitle, strNumber;
int num;
// Read through the file
while (std::getline(inFile, strDash, ' '),//read the symbol -
std::getline(inFile, strTitle, ':'), //read the title(for eg, Account number,Current Balance etc)
std::getline(inFile, strNumber, '\n')) //read the number at the end as string
{
std::cout<<strDash<<" "<<strTitle<<strNumber<<std::endl;//print everything read
}
}
// Check if the account number exists
else
{
cout << "Account number does not exist.\n";
}
return 0;
}
The output of the program can be seen here.
Let's say I have a text file:
83 71 69 97Joines, William B.
100 85 88 85Henry, Jackson Q.
And I want to store each number in an array of ints, and each full-name into an array of strings (a full name would be Joines, William B for example).
What would be the best way, because I debated whether using while (inputFile >> line) or while (getline(inputFile, line)) would be better. I don't know if it would be easier to read them one word at a time or read them one line at a time. My main problem will be splitting the 97Joines, William B. to 97 and Joines, William B. which I don't understand how to do in C++.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
int counter = 0;
int scores[40];
string names[10];
string filename, line;
ifstream inputFile;
cout << "Please enter the location of the file:\n";
cin >> filename;
inputFile.open(filename);
while (inputFile >> line) {
// if line is numeric values only, do scores[counter] = line;
// if it is alphabet characters only, do names[counter] = line;
//if it is both, find a way to split it // <----- need help figuring out how to do this!
}
inputFile.close();
}
You need to #include <cstdlib> for strtol I am sure there are better ways to do this but this is the only way I know and this is only for 97joines, and 85Henry,
string word; // to get joines,
string str; // for 97
string numword;
inputFile >> numword;
for(int k = 0; k < numword.length(); k++)
{
if(isdigit(numword[k]))
{
str = str + numword[k];
}
else
{
word = word + numword[k];
}
}
int num = strtol(str.c_str(), NULL, 0);
You can, given the file structure you have shown, read it like this:
int a, b, c, d;
std::string name;
for (int i = 0; i < 2; ++i)
{
// read the numbers
inputFile >> a >> b >> c >> d;
// read the name
std::getline(inputFile, name);
// do stuff with the data... we just print it now
std::cout << a << " " << b << " " << c << " " << d << " " << name << std::endl;
}
Since the numbers are space separated it is easy to just use the stream operator. Furthermore, since the name is the last part we can just use std::getline which will read the rest of the line and store it in the variable name.
You can try it here, using std::cin.
I'm trying to write a program to read a file with temperatures from various cities, for each day of the week, and in the end find the lowest and highest temperature, and output it along the day of the week in which it was measured and the city in which it was measured.
The file is formatted as such:
M
New York -5.3
Dallas 8.5
Fargo -1.3
T
New York -3.3
Dallas 5.2
Fargo -3.6
W
...
The problem I'm having is taking input and storing it in an array, because of the lines with only the name of the week. Also, I don't think I can chain the >> operators because some lines have the city New York in it, which has a white space in between. I've been wresting with this problem for days now, and I never got further than nowhere.
This is a beginner course, so keep that in mind with help :) I'll post what little code I managed to scramble, which is not much, and it doesn't work.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
string line;
ifstream infile("temps.txt");
float numbers[30] = { 0.0 };
int count = 1;
istringstream iss(line);
string city;
float n;
while (getline(infile, line))
{
if (count % 4 == 0)
{
}
else
{
iss >> city >> n;
}
}
for (int i = 0; i < 10; i++)
{
cout << numbers[i] << " ";
}
}
Once you have gotten a row from the file into a string, it's easy:
if(line.size() == 1)
{
// you have a day in line
}
else
{
// you have a <city + temperature>, let's parse
// the last space in line is always the one right before the temperature. Here is it's index.
int lastSpace = line.find_last_of(' ');
int temp = std::stoi(line.substr(lastSpace + 1, line.size()));
string cityName = line.substr(0, lastSpace);
}
After you have gotten the temperature as an int and the city name as a string, you can store them however you want (array, map, list, whatever) to get the max temperature of the week.
I am having a lot of trouble being able to get data from a file and input it into given structs and arrays of structs and then outputting the file. We are given a file that contains 96 lines and looks like this:
Arzin, Neil
2.3 6.0 5.0 6.7 7.8 5.6 8.9 7.6
Babbage, Charles
2.3 5.6 6.5 7.6 8.7 7.8 5.4 4.5
This file continues for 24 different people and then repeats with different scores (the second line).
The first number, in this case is 2.3 for both people is a difficulty rating. The next 6 numbers are scores.
We are given this data in order to set up our structs and arrays and my code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cmath>
using namespace std;
int main ()
{
ifstream inFile;
inFile.open("C://diveData.txt");
// checking to see if file opens correctly
if (!inFile)
{
cout << "Error opening the file!" << endl;
}
const int numRounds = 2; // variable to hold the number of rounds
const int numScores = 7; // variable to hold the number of rounds
const int numDivers = 24; // variable to hold the number of divers
typedef double DifficultyList[numRounds]; // 1D array for storing difficulty of dives on each round
typedef double ScoreTable [numRounds] [numScores]; // 2D array of dive scores
// struct to store information for one diver
struct DiverRecord
{
string name;
double totalScore;
double diveTotal;
DifficultyList diff;
ScoreTable scores;
};
DiverRecord DiverList[numDivers];
// my attempt at printing out the contents of the file
while (!EOF)
{
for (int x = 0; x < 25; x++)
{
infile >> DiverList[x].name;
inFile >> DiverList[x].totalScore;
inFile >> DiverList[x].diveTotal;
cout << DiverList.[x].name << endl;
cout << DiverList.[x].totalScore << endl;
cout << DiverList.[x].diveTotal << endl;
}
}
return 0;
}
First of all the >> operator ends input at the first whitespace character so when you read in the name you only get the last name and the comma it will try to put the first name into totalScore. To get the full name do the following.
string temp;
infile >> DiverList[x].name;
infile >> temp;
DiverList[x].name + " ";
DiverList[x].name + temp;
Also when outputting you don't need that extra '.'
cout << DiverList[x].name << endl;
and so on should work just fine.
Couple of questions:
decide whether ifstream is open or not, use ifstream::is_open;
decide whether end of file is encountered, try code below;
If I get it right, your input file format should be:
name1,name2
difficulty score1 score2 ... score7
In this sense, the totalScore should not be input from the stream, but calculated instead.
you have two names for one record, so the definition of your record structure seems fuzzy.
Here is a revised version:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
using namespace std;
struct DiverRecord
{
string a, b;
double totalScore;
double difficulty;
double scores[7];
};
int main ()
{
ifstream inFile("C://diveData.txt");
// checking to see if file opens correctly
if (!inFile.is_open()) {
cout << "Error opening the file!" << endl;
}
vector<DiverRecord> DiverList;
DiverRecord record;
char ch;
while (inFile) {
inFile >> record.a >> ch >> record.b >> record.difficulty;
record.totalScore = 0;
for (int i = 0; i < 7; ++i) {
inFile >> record.scores[i];
record.totalScore += record.scores[i];
}
DiverList.push_back(record);
}
// output your DiverList here.
return 0;
}
As I said in my earlier comment I am now trying to concentrate on not using the structs and arrays of structs and am trying to use other functions in order to read the data from the file. I want to put the data in a logical form such as:
Name Of Person
Round 1: Difficulty Scores
Round 2: Difficulty Scores
But I am having trouble accessing specific elements from the file.
The code I am using is:
while(inFile)
{
string name;
getline(inFile, name);
cout << name << endl;
}
This outputs the data file as is, but when I try to declare different variables for the difficulty and the seven scores it does not output correctly at all.