I am making a program for class that needs to read certain lines from an output file based on what "data set" a person chooses. For example, if a person inputs "1" for the desired data set, I need it to use lines 1 through 8 of the data file (inclusively). If they input "2" for the desired data set, I need the program to use lines 9 through 16 from the data file (inclusively), and if "3", then lines 17 through 24 (inclusively).
Here is the code I have so far-
int main()
{
int latA, latB, latC, latD;
int longA, longB, longC, longD;
int AtoB, BtoC, CtoD, threeFlightTotal, nonStop;
int dataSet;
string cityA, cityB, cityC, cityD;
intro();
cout << "Which data set do you wish to use? 1, 2, or 3? ";
cin >> dataSet;
while(dataSet < 1 || dataSet > 3)
{
cout << "Sorry, that is not a valid choice. Please choose again." << endl;
cin >> dataSet;
}
ifstream dataIn;
dataIn.open("cities.txt");
if (dataIn.fail())
{
cout << "File does not exist " << endl;
system("pause");
exit(1);
}
else
{
cout << "File opened successfully" << endl;
}
dataIn.close();
system("pause");
return 0;
}
Here is my data file-
43.65 79.4
Toronto
40.75 74
New York
33.64 84.43
Atlanta
51.5 0
London
37.78 122.42
San Francisco
47.61 122.33
Seattle
44.88 93.22
Minneapolis
41.88 87.63
Chicago
21.19 157.5
Honolulu
45.31 122.41
Portland
42.2 83.03
Detroit
25.47 80.13
Miami
How would I go about doing this? I've looked at other posts but I am having a hard time understanding how to implement their solutions to mine. Thank you for any help in advance. If I'm not giving enough information let me know.
You can simply skip the unneeded lines:
//here you calculate the amount of lines to skip.
//if dataSet=1 --> linesToSkip=0, if dataSet=2 --> linesToSkip=8...
int linesToSkipt = (dataSet-1) * 8;
//getline Needs a string to load the Content.
//So we don't use the data but wee Need to store it somewhere
std::string helper;
//We use a for Loop to skip the desired amount of lines
for(int i = 0; i < linesToSkip; ++i)
std::getline(dataIn, helper); //Skip the unneeded lines
If you knew the exact length of one line you could simply seek to desired Position. But from your example data set it seems like you don't. So you Need to read the file line by line until you reach the desired Position.
Related
I am having an issue reading from a file in a c++ problem. Please find my code below and tell me what you think. I keep on getting "File open failure!"
Problem:
Write a program that produces a bar chart showing the population growth of Prairieville, a small town in the Midwest, at 20 year intervals during the past 100 years. The program should read in the population figures (rounded tot he nearest 1000 people) for 1900, 1920, 1940, 1960, 1980 and 2000 from a file. For each year it should display the date and a bar consisting of one asterisk for each 1000 people. For example, let's use 3000, 7000,10000, 25000, 29000 and 30000.
Here is an example of how the chart might begin:
PRAIRIEVILLE POPULATION GROWTH
(each * represents 1000 people)
1900 ***
1920 *******
1940 **********
// main.cpp
// Population Chart
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int year,population;
ifstream inputFile;
inputFile.open("People.txt");
//if (inputFile.fail())
if(!inputFile)
{
cout << "File open failure!";
}
cout << "PRAIRIEVILLE POPULATION GROWTH\n" <<endl;
cout << "(each * represents 1000 people)\n" <<endl;
while (inputFile >> population)
{
for (year =1900 ; year<=2020; year += 20)
{
cout<< year;
for (int i = 1; i <= population/1000; i++)
{
cout<<"*";
}
cout<< endl;
}
}
inputFile.close();
return 0;
}
From the tag you put to the question, I think you are using Xcode, right? You need to know where does Xcode output the executable, and your People.txt file needs to be put under the same folder as the executable. In Xcode, goto
Xcode > Preference > Locations
The path shown under "Derived Data", is where Xcode put executable. It's typically ~/Library/Developer/Xcode/DerivedData.
There you will probably find a lot of folders of your projects. Go into the folder corresponds to this project and goto Build/Products/Debug, then you will find your executable. What you can do is put your People.txt there.
OR your can add the full path of your "People.txt" file to your inputFile.open() method.
ifstream open() sets errno on failure. So you may obtain its string representation to output the reason of failure:
cout << "File open failure:" << strerror(errno);
This post was very useful New to Xcode can't open files in c++? the issue is now resolved. Turns out the file was not in the folder containing the generated executable. Thanks :)
I have this homework assignment that has me a little lost. I have been working on this assignment writing my code, erasing, rewrite, repeat etc. Here are the instructions:
Step (1)
Associated with this assignment is a data file called prices.txt. It contains details of the prices for items in a
grocery store. The first column is the barcode for the item (http://en.wikipedia.org/wiki/Barcode) the
second column, starting in position 11, is the product name, and the third column, starting in position 37 is
the product price.
Write a function with the signature int loadData() which prompts the user for the location of the data file
on disk and then loads the data from the file into an array of elements. Each element of the array should be
a struct declared as follows:
struct Item {
string code;
string name;
double price;
};
The array itself should be called items and should be declared at file scope as follows:
const int MAX_ITEMS = 100;
Item items[MAX_ITEMS];
Notice that the array has size 100, so you can assume the number of items in the data file is less than 100.
Therefore, when loadData has finished loading the data into the array some elements in the array will be unused. The function loadData returns the number of items actually loaded into the array.
I am unsure on how to attempt the function described in the instructions. My code:
int loadData () {
string inputFileName;
ifstream inputFile;
int numOfItems = 0;
cout << "Please input the name of the backup file: ";
cin >> inputFileName; //read user input for the location of the
//backup file
inputFile.open(inputFileName.c_str()); //open specified document
if (!inputFile.is_open()) { //If the file does not open the errormsg
cout << "Unable to open input file." << endl;
cout << "Press enter to continue...";
getline(cin, reply);
exit(1);
}
//Not sure where to start. I know I need to get each element from
//each newline.
return numOfItems;
}
I wanted to figure this out on my own but that isn't gonna happen. So if I could just get some hints or even suggested pools of knowledge that would guide me or even give me an idea of where to start.
addition: input file:
10001 Apples (bunch) 4.59
10002 Bananas (bunch) 4.99
10003 Pears (bunch) 5.49
20001 White bread (loaf) 2.69
20002 Brown bread (loaf) 2.89
20003 English Muffins (bag) 3.99
30001 Sugar (5 lb bag) 3.99
30002 Tea (box) 4.29
30003 Folger's Coffee (Can) 13.29
This is the entire input file.
Since the input file seems to be using fixed-width columns, it's actually very easy to extract the fields. Just read one line at a time, and for each line get each element as a sub-string, and put into the structure members. And there are functions to convert strings to floating-point values as well.
Don't worry about the possible leading or trailing spaces, there are ways of trimming that.
I wanted to ask how can I append strings to the end of fixed number of lines (fixed position). I am trying and searching books and websites for my answer but I couldn't find what I am doing wrong.
My structure :
const int numberofdays=150 ;
const int numberofstudents=2;
struct students
{
char attendance[numberofdays]; int rollno;
char fullname[50],fathersname[50];
}
Creating a text file
ofstream datafile("data.txt", ios::out );
Then I take input from the user and save it to the file.
How I save my data to text files :
datafile <<attendance <<endl<< rollno <<endl<<
fullname <<endl<< fathersname <<endl ;
How it looks like in text files :
p // p for present - 1st line
1 // roll number
Monte Cristo // full name
Black Michael // Fathers name
a // a for absent - 5th line
2 // roll number
Johnson // full name
Nikolas // Fathers name
How I try to update the file. (updating attendance for everyday)
datafile.open("data.txt", ios::ate | ios::out | ios::in);
if (!datafile)
{
cerr <<"File couldn't be opened";
exit (1);
}
for (int i=1 ; i<=numberofstudents ; i++)
{
long int offset = ( (i-1) * sizeof(students) );
system("cls");
cout <<"\t\tPresent : p \n\t\t Absent : a"<<endl;
cout <<"\nRoll #"<<i<<" : ";
cin >> ch1;
if (ch1 != 'p')
ch1 = 'a';
datafile.seekp(offset);
datafile <<ch1;
datafile.seekg(0);
}
I just want to add (append) characters 'p' or 'a' to the first or fifth line, I tried every possible way but I am unable to do it.
What you are doing is fairly common, but as you say it is inefficient if the size of data grows. Two solutions are to have fixed size records and index files.
For fixed-size records, in the file write the exact bytes of your data structure rather than a variable length text. This would mean you don't have a text file any more, but a binary file. You can then calculate the position to seek to easily.
To create an index file, write two files at once, one your variable size record file, and the other write a binary value with either the offset of the data from the start of the file. Since the index is a fixed size, you can seek to the index, read it, then seek to the position in the data file. If the new record will fit, you can update it in place, otherwise fill in with blanks and put the updated record at the end of the data file, then update the index file to point to the new location. This is basically how early PC databases worked.
Fixed size records are rather inflexible, and by the time you've implemented the index file system and tested it, now-a-days you probably would use a in-process database instead.
I came up with my own (easy & inefficient) logic to copy every line (except the line I want to update) to the another file.
I made my text file to be created like this :
=p // p for present - 1st line
1 // roll number
Monte Cristo // full name
Black Michael // Fathers name
=a // a for absent - 5th line
2 // roll number
Johnson // full name
Nikolas // Fathers name
Then I made the following code to update 1st and 5th line :
ifstream datafile("data.txt", ios ::in);
ofstream tempfile("temp.txt" , ios ::out);
string data, ch1;
while (getline(datafile,data))
{
if (data[0]=='=')
{
system("cls");
cout <<"\t\tPresent : p\n\t\tAbsent : a"<<endl;
cout <<"\nRoll #"<<i<<" : ";
cin >> ch1;
++i;
if (ch1 != "p")
ch1 = "a";
data=data+ch1; // Appending (updating) lines.
}
tempfile <<data <<endl; // If it was 1st or 5th line, it got updated
}
datafile.close(); tempfile.close();
remove("data.txt"); rename("temp.txt" , "data.txt");
But as you can see, this logic is inefficient. I will still wait for someone to inform me if I could somehow move my file pointer to exact location (1st and 5th line) and update them.
Cheers!
I'm completely new to C++, so please give me a change to learn!
Assuming I have a text file RoomDB.txt which stores data in the following format :
005:Room 1:Level 1:3-Jul-14:0900:3:Mathematics 101:Julia Lee
006:Room 2:Level 2:2-Jun-14:0800:2:English 101:Jared Loo
007:Room 3:Level 3:15-Apr-14:1800:3:Chinese 101:David Tay
008:Room 4:Level 4:15-Apr-14:1200:3:Science 101:Michelle Choo
How would I selectively display a particular line (or more) of data based on the fourth field (the date), such that it would look like this - (If i want to display only the lines in which the date is 15-Apr-14)
Booking ID Room No. Level No. Time Duration Subject Lecturer
----------------------------------------------------------------------------------------
007 Room 3 Level 3 1800 3 Chinese 101 David Tay
008 Room 4 Level 4 1200 3 Science 101 Michelle Choo
PS : Notice that the date is excluded from the desired output as it will be used as a criteria for choosing what data is to be displayed. My current code is as follows :
int main()
{
cout << "\nBooking ID Room No. Level No. Time Duration Subject Lecturer" << endl;
cout << "-------------------------------------------------------------------------------" << endl;
string array[50]; // creates array to hold names
short loop=0; //short for loop for input
string line; //this will contain the data read from the file
ifstream myfile ("RoomDB.txt"); //opening the file.
if (myfile.is_open()) //if the file is open
{
while (! myfile.eof() ) //while the end of file is NOT reached
{
getline (myfile,line); //get one line from the file
array[loop] = line;
cout << "At element " << loop << ", value is :" << array[loop] << endl;
loop++;
}
myfile.close(); //closing the file
}
else cout << "Unable to open file"; //if the file is not open output
}
This is a CSV like file with delimiter :, you could:
-read the file line by line using std::getline
-spliting the line by : using Boost String Algorithm.
-loading in a structure or collection for processing.
-output necessary info
Hello all this is my first post. I'm working on a homework assignment with the following parameters.
Piecework Workers are paid by the piece. Often worker who produce a
greater quantity of output are paid at a higher rate.
1 - 199 pieces completed $0.50 each
200 - 399 $0.55 each (for all pieces)
400 - 599 $0.60 each
600 or more $0.65 each
Input: For each worker, input the name and number of pieces completed.
Name Pieces
Johnny Begood 265
Sally Great 650
Sam Klutz 177
Pete Precise 400
Fannie Fantastic 399
Morrie Mellow 200
Output: Print an appropriate title and column headings. There should
be one detail line for each worker, which shows the name, number of
pieces, and the amount earned. Compute and print totals of the number
of pieces and the dollar amount earned.
Processing: For each person, compute the pay earned by multiplying the
number of pieces by the appropriate price. Accumulate the total
number of pieces and the total dollar amount paid.
Sample Program Output:
Piecework Weekly Report
Name Pieces Pay
Johnny Begood 265 145.75
Sally Great 650 422.50
Sam Klutz 177 88.5
Pete Precise 400 240.00
Fannie Fantastic 399 219.45
Morrie Mellow 200 110.00
Totals 2091 1226.20
You are required to code, compile, link, and run a sentinel-controlled
loop program that transforms the input to the output specifications as
shown in the above attachment. The input items should be entered into
a text file named piecework1.dat and the ouput file stored in
piecework1.out . The program filename is piecework1.cpp. Copies of
these three files should be e-mailed to me in their original form.
Read the name using a single variable as opposed to two different
variables. To accomplish this, you must use the getline(stream,
variable) function as discussed in class, except that you will replace
the cin with your textfile stream variable name. Do not forget to code
the compiler directive #include < string > at the top of your program
to acknowledge the utilization of the string variable, name . Your
nested if-else statement, accumulators, count-controlled loop, should
be properly designed to process the data correctly.
The code below will run, but does not produce any output. I think it needs something around line 57 like a count control to stop the loop.
something like (and this is just an example....which is why it is not in the code.)
count = 1;
while (count <=4)
Can someone review the code and tell me what kind of count I need to introduce, and if there are any other changes that need to be made.
Thanks.
//COS 502-90
//November 2, 2012
//This program uses a sentinel-controlled loop that transforms input to output.
#include <iostream>
#include <fstream>
#include <iomanip> //output formatting
#include <string> //string variables
using namespace std;
int main()
{
double pieces; //number of pieces made
double rate; //amout paid per amount produced
double pay; //amount earned
string name; //name of worker
ifstream inFile;
ofstream outFile;
//***********input statements****************************
inFile.open("Piecework1.txt"); //opens the input text file
outFile.open("piecework1.out"); //opens the output text file
outFile << setprecision(2) << showpoint;
outFile << name << setw(6) << "Pieces" << setw(12) << "Pay" << endl;
outFile << "_____" << setw(6) << "_____" << setw(12) << "_____" << endl;
getline(inFile, name, '*'); //priming read
inFile >> pieces >> pay >> rate; // ,,
while (name != "End of File") //while condition test
{ //begining of loop
pay = pieces * rate;
getline(inFile, name, '*'); //get next name
inFile >> pieces; //get next pieces
} //end of loop
inFile.close();
outFile.close();
return 0;
}
Can someone review the code and tell me what kind of count I need to introduce, and if there are any other changes that need to be made.
You need statements that direct output to your output file, just as the assignment said to do. The compiler can't read your mind, and it can't read your homework assignment either. It can only read your code.
You also have a problem with your input statements. The pay rates are not in the input file. All that's in the input file are the workers' names and the number of pieces they produced.