Reading Input Error - c++

I am working on NOV14 on COdechef contest problems. and i stuck at this problem.
http://www.codechef.com/NOV14/problems/RBTREE
My algorithm working well, but i cant take the input correctly. the problem is i don't know how many number of inputs are given. but i need to store in multiple variables.
Take a look at here..
5
Qb 4 5
Qr 4 5
Qi
Qb 4 5
Qr 4 5
where 5 is the number of test cases,
can i read every test cases into variables.
if i take First test case I can take Qb to one variable, 4 to other and 5 to another.
But the problem is How to read a line which start with Qi.

Well, first of all, if you write C++, you should use C++ streams. Here's the code for input (which you can adjust for your own needs):
#include <iostream>
#include <fstream>
int main() {
std::ifstream file;
file.open("data.in");
int lines = 0;
file >> lines;
std::string query_type;
for (int i = 0; i < lines; i++) {
file >> query_type;
if (query_type == "Qi") {
std::cout << query_type << std::endl;
} else {
int x = 0;
int y = 0;
file >> x >> y;
std::cout << query_type << " " << x << " " << y << std::endl;
}
}
file.close();
return 0;
}

You'll need to check what you've read at each step, and then determine whether or not you need to read the numbers in.
So read two characters, and if the characters you've read are "Q" and "i", you don't need to read any numbers, and you can just step on to the next line. Otherwise, you should read the two numbers before going to the next line.

Related

C++ Basic While Loop: Unknown Inputs and Value Increment

So I'm trying to write a program that reads unknown inputs from a data file that has a sentinel 0 or I guess an termination point for the loop.
Number of integers per line before 0 (int count).
Number of all integers in data file (int totalcount).
Number of lines in data file (int lines).
Two examples of unknown inputs from a data file:
Example One:
1 2 3 0 4 5 6 7 0
Example Two:
0 9 11 -11
1 1 0 0 2
0
Here is my program (without "count" because that is where my problem lies):
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
//If datafile is not 0, loop runs until datafile is 0.
while(datafile != 0)
{
//Counts all integers in the file except 0.
totalcount += 1;
cin >> datafile;
}
//Counts how many lines there are in a data file using sentinel 0 (not "/n").
if(datafile == 0)
lines += 1;
//Outputs.
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
}
return 0;
}
Please do not worry about technicality, efficiency, or anything else besides the logic/concept itself as I'm just trying to find the missing link in my knowledge to complete this assignment.
With that said, my expected outputs are as formatted:
"Line #" "Counts of integers per line" "Total counts of all integers in data file"
Using example one with my current code, I would have outputs (spacing is not exact and '.' is for blanks):
1......0......3
2......0......7
Correct expected outputs:
1......3......3
2......4......7
I would like any hints or explanation of how I can count the integers per line (before sentinel 0) and assign that value to "int count" without the value persisting to the next line.
I'm a student in an introductory C++ class so please show me a basic way of how I may go about this first and then any other advanced options as necessary for future applications.
Code of Conduct Personal Statement:
By participating, you are providing necessary knowledge for assignment completion, not completing the assignment itself. The example used is generated by me intended for concept demonstration purposes and is only a small part of the final assignment.
10/23/2016 9:56PM Update 1:
Currently attempting to use a "temp" variable to substract from "totalcount". I will update my code if attempt is successful.
totalcount is sum of counts. This is my suggestion
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
// Add count to totalcount and reset count each time reach 0
if (datafile == 0) {
totalcount += count;
lines += 1;
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
count = 0;
}
//otherwise increase count
else {
count++;
}
}
return 0;
}

Using fscanf to read from tabbed file with ints and floats in C++

I have looked for a day or so on StackOverflow and other sites, and I can't find a solution to my problem. There are some that are similar, but I can't seem to make them work.
I have a tab-delimited .txt file. One line contains a heading, and 500 lines after that each contain an integer, an integer, a float, an integer, and an integer, in that order. I have a function that is supposed to read the first and third values (the first integer and the float) from each line. It skips the first line. This is in a do-while loop, because I need to be able to process files of different lengths. However, it's getting stuck in the loop. I have it set to output the mean, but it just outputs zeros forever.
void HISTS::readMeans(int rnum) {
int r;
char skip[500];
int index = 0; int area = 0; double mean = 0; int min = 0; int max = 0;
FILE *datafile = fopen(fileName,"r");
if(datafile == NULL) cout << "No such file!\n";
else {
//ignore the first line of the file
r = fscanf(datafile,"%s\n",skip);
cout << skip << endl; //just to check
//this is the problematic code
do {
r = fscanf(datafile,"%d\t%d\t%f\t%d\t%d\n",&index,&area,&mean,&min,&max);
cout << mean << " ";
} while(feof(datafile) != 1)
}
fclose(datafile);
}
Here is a sample data file of the format I'm trying to read:
Area Mean Min Max
1 262144 202.448 160 687
2 262144 201.586 155 646
3 262144 201.803 156 771
Thanks!
Edit: I said I need to read the first and third value, and I know I'm reading all of them. Eventually I need to store the first and third value, but I cut that part for the sake of brevity. Not that this comment is brief.
You should do it C++ style,
#include <iostream>
#include <fstream>
int main() {
std::ifstream inf("file.txt");
if (!inf) { exit(1); }
int idx, area, min, max;
double mean;
while (inf >> idx >> area >> mean >> min >> max) {
if (inf.eof()) break;
std::cout << idx << " " << area << " " << mean << " " << min << " " << max << std::endl;
}
return 0;
}
It is :
1) Easy to read.
2) Less code, so less chance of error.
3) Correct handling of EOF.
Although I have left handling of first line, that is upto you.
fscanf returns the number of arguments read. Thus, if it returns less than 5 you should exit the loop.
OP ended up using operator>>, which is the correct way to do this in C++. However, for the interested C reader, there were a couple of issues in the code posted:
mean was declared as double but read using the wrong format specifier %f instead of %lf.
The first line wasn't completely read, but only the first token, Area.
A possible way to implement the desired task is as follows:
r = fscanf(datafile,"%[^\n]\n",skip);
// ^^^^^ read till newline
while ( (r = fscanf(datafile,"%d%d%lf%d%d",&index,&area,&mean,&min,&max)) == 5 ) {
// ^^ correct format specifier for double
// ...
}

C++ text file into multi-dimensional array problems

As part of a school project, I would like to get an inventory *.txt file into an array in C++ and eventually back to a *.txt file at a later part in the program.
The text file will start out with 10 rows that will represent grocery story items and will include three columns that represent the name, price, and quantity of the items. I have been able to read from the file, even add numbers in front of each row that is displayed. Now, I would like to get the text file into a string array so that the "employee" user can make changes to items one at a time and then I can dump that array back into a *.txt file.
The code below is what I have been trying so far. I can get the count of rows in the file, but can't seem to get the columns counted or the data in the rows displayed. When I run the program, I get what appear to be 10 empty lines after it displays the rows (10) and Cols(0).
The columns in the *.txt file are normally separated by a space. I tried a tab, and tried: while(getline(invFile, lines, '\t'); which just caused the console to display what I am guessing was a memory address and then crashed.
Unfortunately, we have not gotten very far into debugging programs, and from the look of the syllabus, I don't think that will be covered very thoroughly, so I don't know how to troubleshoot any further. I have spent the last couple of hours Google-ing, and have gotten to the point that I actually need to ask for help.
The project involves a lot more than this component, but I really am stuck on this part. I am not asking for someone to do this for me, but if anyone has any idea what I am doing wrong and can point me in the best direction to get a text file into a multi-dimensional array, I would really appreciate it.
Thank you.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <array>
int row = 0;
int col = 0;
using namespace std;
int main()
{
string lines;
int x;
string textArray[2][2];
ifstream invFile;
invFile.open("inventory.txt");
if(invFile.fail()){
cerr << "The file cannot be opened!";
exit(1);
}
cout << "\n" << endl;
while(invFile.good()) {
while(getline(invFile, lines)) {
istringstream streamA(lines);
col = 0;
while(streamA >> x) {
cout << x;
textArray[row][col] = x;
col++;
}
row++;
}
}
invFile.close();
cout << "Rows: " << row << endl;
cout << "Cols: " << col << endl;
cout << "\n" << endl;
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
cout << "Line: " << i << textArray[i][j] << ".";
}
cout << "\n";
}
return(0);
}
=============================
inventory.txt:
Apples 1.25 20
Oranges 1.75 20
Kiwi 2.50 15
Pineapples 5.50 20
Tomatoes 1.50 20
Onions 2.00 20
Corn 1.80 20
Carrots 2.30 20
Milk 4.50 20
Cheese 2.25 20
I would suggest that you create a struct or class to hold the data. From each line of text, extract the fields appropriately and them to your struct. Then, keep a list of those structs using std::vector.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <array>
#include <vector>
#include <cstdlib>
using namespace std;
struct Row
{
vector<string> columns;
};
int main()
{
string line;
vector<Row> rows;
ifstream invFile;
invFile.open("inventory.txt");
if(invFile.fail()){
cerr << "The file cannot be opened!";
exit(1);
}
cout << "\n" << endl;
while(invFile.good()) {
while(getline(invFile, line))
{
Row row;
istringstream streamA(line);
string col;
while ( streamA >> col )
{
row.columns.push_back(col);
}
rows.push_back(row);
}
}
invFile.close();
cout << "Rows: " << rows.size() << endl;
cout << "Cols: " << rows[0].columns.size() << endl;
cout << "\n" << endl;
for(int i=0; i<rows.size(); i++){
for(int j=0; j<rows[i].columns.size(); j++){
cout << "Line: " << i << " " << rows[i].columns[j] << "\n";
}
cout << "\n";
}
return(0);
}
I'd like to suggest you add some print lines in the important step -- which I think also is a fast&good "debug" method. So that you can find where you wrong easily.
For example in your code, seems textArray wasn't assigned, so add some print nearby:
while(getline(invFile, lines)) {
cout <<"lines: " << lines << endl; //test enter here
istringstream streamA(lines);
col = 0;
while(streamA >> x) {
cout << "x is" << x; //test if enter here
textArray[row][col] = x;
col++;
}
row++;
}
Through the output, the lines is ok but cout << "x is" << x; wasn't printed, which means the while(streamA >>x) condition is false, why?
Go to find the library function called, std::istringstream x is int type but col 1 value is Apples, operator << will return NULL, it's unreasonable assing Apples to an int, till now, found point 1. If have to use int or float to store the numbers, use some convert API like atoi, atof.
After change x from int to string, got segmentation falut, it's obviously that textArray[2][2] is not enough to store all the information. "Out of range" is the reason of segmentation fault, so make a large array to test continue until passed.
There's a couple ways you could do this. The easiest would be to just put something like 3,10 at the top of the file, and then you know three columns and 10 rows. Since your writing this after modification, you would just need to make sure that those numbers get written correctly.
If you want to learn some more advanced methods, then your life will be easier AFTER you learn a bunch more.
If you used a vector, using something like vector< vector<string> > you could just read to a stringstream and then split the line read and put it into the vector
fstream file(...);
string tempString;
vector< vector<string> > list;
// Get a full line
while(getline(file, tempString, '\n'){
// Create a StringStream and store tempString in it for further manipulation
stringstream ss;
ss << tempString;
vector<string> tempVec;
// Get each column from this row
while(getline(ss, tempString, '\t'){
// Put each column into a vector
tempVec.push_back(tempString);
}
// Put the entire vector into our list vector
list.push_back(tempVec);
}
The benefit of this second method is twofold. First, it's very easy. I'm guessing you don't know how it works, but some easy Google searches on keywords you don't know, and you'll find out fast enough. The second is it allows (theoretically) unlimited rows, and unconstrained columns. By that, I mean one row could have 20 columns, one could have 2, and there would be no wasted space.
Note that you should NOT use the skeleton code I showed before researching it. If you don't have at least a general idea of what is happening here, then you'll just cause problems for yourself later on. I'm not going to explain everything here, because other people have done that already. Also, since you're learning this in school, you'll get to these things eventually, so you'll just be getting ahead. The one main constraint would be if your project requires arrays, in which case, my first solution would be the best option.

I'm Having Trouble Skipping Certain Characters from an Input Text File (C++)

(I apologize that this is so low level compared to most of the questions I have seen on this website, but I have run out of ideas and I do not know who else to ask.)
I am working on a school project that requires me to read basketball statistics from a file named in06.txt. The file in06.txt looks exactly as follows:
5
P 17 24 9 31 28
R 4 5 1 10 7
A 9 2 3 6 8
S 3 4 0 5 4
I am required to read and store the first number, 5, into a variable called "games." From there, I must read the numbers from the second line and determine the high, the low, and the average. I must do the same thing for lines 3, 4, and 5. (FYI, the letters P, R, A, and S are there to indicate "Points," "Rebounds," "Assists," and "Steals.")
Since I only have been learning about programming for a few weeks, I do not want to overwhelm myself by jumping right into dealing with every aspect of the project. So, I am first working on determining the average from each line. My plan is to keep a running total of each line and then divide the running total by the number of games, which is 5 in this case.
This is my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
int games;
int points_high, points_low, points_total;
int rebounds_high, rebounds_low, rebounds_total;
int assists_high, assists_low, assists_total;
int steals_high, steals_low, steals_total;
double points_average, rebounds_average, assists_average, steals_average;
ifstream fin;
ofstream fout;
fin.open("in06.txt");
if( fin.fail() ) {
cout << "\nInput file opening failed.\n";
exit(1);
}
else
cout << "\nInput file was read successfully.\n";
int tempint1, tempint2, tempint3, tempint4;
char tempchar;
fin >> games;
fin.get(tempchar); // Takes the endl; from the text file.
fin.get(tempchar); // Takes the character P from the text file.
while( fin >> tempint1 ) {
points_total += tempint1;
}
fin.get(tempchar); // Takes the endl; from the text file.
fin.get(tempchar); // Takes the character R from the text file.
while( fin >> tempint2 ) {
rebounds_total += tempint2;
}
fin.get(tempchar); // Takes the endl; from the text file.
fin.get(tempchar); // Takes the character A from the text file.
while( fin >> tempint3 ) {
assists_total += tempint3;
}
fin.get(tempchar); // Takes the endl; from the text file.
fin.get(tempchar); // Takes the character S from the text file.
while( fin >> tempint4 ) {
steals_total += tempint4;
}
cout << "The total number of games is " << games << endl;
cout << "The value of total points is " << points_total << endl;
cout << "The value of total rebounds is " << rebounds_total << endl;
cout << "The value of total assists is " << assists_total << endl;
cout << "The value of total steals is " << steals_total << endl;
return 0;
}
And this is the (incorrect) output:
Input file was read successfully.
The total number of games is 5
The value of total points is 111
The value of total rebounds is 134522076
The value of total assists is 134515888
The value of total steals is 673677934
I have been reading about file input in my textbook for hours, hoping that I will find something that will indicate why my program is outputting the incorrect values. However, I have found nothing. I have also researched similar problems on this forum as well as other forums, but the solutions use methods that I have not yet learned about and thus, my teacher would not allow them in my project code. Some of the methods I saw were arrays and the getline function. We have not yet learned about either.
Note: My teacher does not want us to store every integer from the input file. He wants us to open the file a single time and store the number of games, and then use loops and if statements for determining the high, average, and low numbers from each line.
If anyone could help me out, I would GREATLY appreciate it!
Thanks!
You have all these variables declared:
int games;
int points_high, points_low, points_total;
int rebounds_high, rebounds_low, rebounds_total;
int assists_high, assists_low, assists_total;
int steals_high, steals_low, steals_total;
double points_average, rebounds_average, assists_average, steals_average;
And then you increment them:
points_total += tempint1;
Those variables were never initialzed to a known value (0), so they have garbage in them. You need to initialize them.
Besides what OldProgrammer said, you've approached the reading of integers incorrectly. A loop like this
while( fin >> tempint2 ) {
rebounds_total += tempint2;
}
will stop when an error occurs. That is, either it reaches EOF or the extraction encounters data that cannot be formatted as an integer - or in other words, good() returns false. It does not, as you seem to think, stop reading at the end of a line. Once an error flag is set, all further extractions will fail until you clear the flags. In your case, a loop starts reading after P, extracts five intergers, but then it encounters the R from the next line and errors out.
Change this to a loop that reads a fixed number of integers or alternatively, read a whole line using std::getline into a std::string, put it into a std::stringstream and read from there.
In any case, learn to write robust code. Check for success of extractions and count how many elements you get.
An example of a loop that reads at most 5 integers:
int i;
int counter = 0;
while (counter < 5 && file >> i) {
++counter;
// do something with i
}
if (counter < 5) {
// hm, got less than 5 ints...
}

Assign last number of a text file to a variable C++

I am doing a program that outputs a list of prime numbers with fstream.
I have this so far:
int export_list (int lim = 50)
{
int x;
last_in_txt = ????????????; // assigns last number on txt
ofstream file ("Primes.txt" , ios::app);
if (file.is_open()) // if it opens correctly
{
for (x = last_in_txt ; x < lim ; x++)
{
if (check_prime (x)) // returns 1 when x is prime, returns 0 when not
{
file<< x << " ";
}
}
cout << "Done!" << endl << pressenter;
cin.get();
}
else
{
cout << "Unable to open file" << endl << pressenter;
cin.get();
}
return(0);
}
So, as you can see, this should append a list of prime numbers to Primes.txt, starting with the prime 1234547.
Primes.txt looks like this:
2 3 5 7 11 13 17 19 23 29 31 37 (...) 1234543 1234547
My question is how do I assign 1234547 (which is the last number of the txt) to the variable last_in_txt?
Other (not so important) question:
Should I save the numbers the way I'm currently doing, or should I store each number in a separate line?
One simple way: keep reading and assign until the whole file is read.
For example,
int last_in_txt = 0;
{
ifstream infile("Prime.txt");
int k;
while(infile >> k) {
last_in_txt = k;
}
}
// Now last_in_txt is assigned properly, and Prime.txt is closed
This works well no matter the numbers in Prime.txt are separated by space characters (' ') or by newline characters ('\n').
My suggestion is that you write using binary format into the text file(using wb in C). In this case you will know how many bytes does the last number occupy and you will be able to use seekg and tellg to get it. If you use plain text format you will have to read char by char from the end and this is more error-prone and also slower.