File pointer movement for getline - c++

I have got an input file with following data
2
100
2
10 90
150
3
70 10 80
Now, I am able to read till 4th line ( 10 90) but when reading 5th line(150), the file pointer seems to be stuck at 4th line. I have tried infile.clear() just incase. How do I make sure that file pointer is moving correctly or position it at next line? Appreciate your feedback.
-Amit
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main(void) {
int cases;
int total_credit=0;
int list_size=0;
string list_price;
//Read file "filename".
ifstream infile;
infile.open("A-large-practice.in",ifstream::in);
if(!infile.is_open()) {
cout << "\n The file cannot be opened" << endl;
return 1;
}
else {
cout<<"Reading from the file"<<endl;
infile >> cases;
cout << "Total Cases = " << cases << endl;
int j=0;
while (infile.good() && j < cases) {
total_credit=0;
list_size=0;
infile >> total_credit;
infile >> list_size;
cout << "Total Credit = " << total_credit << endl;
cout << "List Size = " << list_size << endl;
//cout << "Sum of total_credit and list_size" << sum_test << endl;
int array[list_size];
int i =0;
while(i < list_size) {
istringstream stream1;
string s;
getline(infile,s,' ');
stream1.str(s);
stream1 >> array[i];
//cout << "Here's what in file = " << s <<endl;
//array[i]=s;
i++;
}
cout << "List Price = " << array[0] << " Next = " << array[1] << endl;
int sum = array[0] + array[1];
cout << "Sum Total = " << sum << endl;
cout <<"Testing" << endl;
j++;
}
}
return 0;
}

The problem is that you're using ' ' (space) as your "line terminator" for getline. So when you're reading the numbers on line 4 into the string s, the first one will be "10" and the second will be "90\n150\n3\n70" -- that is, everything up to the next space. This is almost certinaly not what you want and is leading to your confusion about where you are in the file. The next number you read will be 10, leading you to think you're on line 4 when in fact you're on line 7.
edit
The easiest way to fix this is probably to not use getline at all and just read ints directly from the input:
while (i < list_size)
infile >> array[i++];
This ignores the newlines altogether, so the input might as well be all on one line or split between lines randomly, but as you have an initial number that tells you how many numbers to read, that's just fine.

Related

C++ reading command from .txt file

I want to create a little "calculator" but I dont know how can I create.
My problem is, I have an input file (.txt) with codes:
acc +40
acc -14
nop +386
jmp +262
acc -4
nop +25
...
the "acc" adds the number to my variable
the "jmp" is jump to the line (jmp +500 jump foward 500 line)
the "nop" dont do anything
and here is my code but not working (the acc is okay, but the jmp is not)
ifstream file("my.txt");
string cmd;
int num;
int var= 0;
int i = 0;
if(file.is_open())
{
while (file >> cmd >> num)
{
cout << "Var" << var<< endl;
cout << "Command: " << cmd << " Number: " << num<< " ----" << i <<" // Var: " << var<< endl;
++i;
if(cmd == "acc")
{
var= var+ num;
}
if(cmd == "jmp")
{
;
}
}
file.close();
}else {
cout << "error"<< endl;
cin.get();
}
This is a sample code. I hope everything here is in order. I did what Some programmer dude told you. Using vectors, you read all the lines into them and then just iterate.
#include <fstream>
#include <iostream>
#include <string> //addition
#include <vector> //addition
using namespace std;
int main() {
ifstream file("my.txt");
string cmd;
int num;
int var= 0;
int i = 0;
string my_string;//addition
vector<int> numbers;//addition
vector<string> commands;//addition
if(file.is_open())
{
/*this while function reads every line of the file and writes command to the vector of strings named "commands" and the number to the vector of integers named "numbers".*/
while (getline(file, my_string))//while you can read line from "file", read it and put in into string called "my_string".
{
cmd = my_string;
cmd.resize(3);//leaves only first three characters of the string.
commands.push_back(cmd);//adds this "cmd" string to vector "commands"
my_string.erase(0,4);//erases characters from 0 to 4, inclusive, from the string "my_string". So erases first 4 characters, so our command and the space after.
numbers.push_back(stoi(my_string));//adds my_string, converted to int, to vector "numbers". Stoi() converts string to int.
++i;
}
for(i = 0; i < commands.size(); i++)
{
cout << "Var " << var << endl;
if(commands[i] == "acc")
{
//remember about "+=", it's quicker this way :)
var += numbers[i];
}
cout << "Command: " << commands[i] << " Number: " << numbers[i] << " ----" << i <<" // Var: " << var << endl;
if(commands[i] == "jmp")
{
i+= numbers[i];
}
}
file.close();
}else {
cout << "error"<< endl;
cin.get();
}
}
Sorry in advance for any formatting issues. My first answer on stackoverflow...

String doesn't want to store a 2700 character word

I'm trying to make a program that prints all the numbers from 100-999. After that you get to choose how many numbers you want to find. Then you type the number's position and it will be outputed.
There is one problem. The string, named str, stops storing at the number 954.
Here's the code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
//Prints to myFile the numbers from 100 to 999 without a space in between. Like this: 100101102...999
ofstream myFile("numere.txt");
for(int i = 100; i <= 999; i++)
myFile << i;
//Makes the string str to store the line: 100101102103...999. But only stores until 954 (100101102..954)
ifstream myFileRead("numere.txt");
string str;
while(getline(myFileRead, str))
cout << str << endl;
//Ouputs the lenght that should be 2700 but is instead 2565
cout << endl;
cout << "String legth: " << str.size() << endl;
cout << endl;
int n, k;
cout << "Enter how many numbers do you want to find: ";
cin >> n;
for(int i = 1; i <= n; i++){
cout << "Enter number position(it starts from 0) : ";
cin >> k;
cout << "Here's the number on position " << k << ": " << str.at(k);
cout << endl;
}
system("pause>0");
}
Thanks for your attention. I’m looking forward to your reply.
C++ streams are buffered. When you use << to write to a file it is not immediately written to the file.
Try to close or flush the ofstream before you read from it:
myFile.close(); // or...
myFile.flush();
For more details I refer you to flush() and close().
PS: Actually it is rather rare that you need to close a fstream explicitly. You wouldn't need to do it when you used seperate functions for writing and reading:
void write_to_file() {
std::ofstream myFile("numere.txt");
//...
}
void read_from_file() {
std::istream myFile("numere.txt");
//...
}
Because the destructor of ofstream already closes the file.

get string array from text list c++

my text file was like
123456123456
Jason
uk
012456788
1000
456789456789
david
uk
012456788
1000
i'm trying to get the data from a text file and save it into arrays
however when i want to store the data from the text file into array it loop non-stop.
what should i do ?
the problem exiting in looping or the method i get the data from text file ?
code:
#include <iostream>
#include <fstream>
using namespace std;
typedef struct {
char acc_no[12];
char name[30];
char address[50];
char phone_no[12];
double balance;
} ACCOUNT;
//function prototype
void menu();
void read_data(ACCOUNT record[]);
int main() {
ACCOUNT record[31]; //Define array 'record' which have maximum size of 30
read_data(record);
}
//--------------------------------------------------------------------
void read_data(ACCOUNT record[]) {
ifstream openfile("list.txt"); //open text file
if (!openfile) {
cout << "Error opening input file\n";
return 0;
} else {
int loop = -1; //size of array
cout << "--------------Data From File--------------"<<endl;
while (!openfile.eof()) {
if (openfile.peek() == '\n')
openfile.ignore(256, '\n');
openfile.getline(record[++loop].acc_no, 12);
openfile.getline(record[loop].name, 30);
openfile.getline(record[loop].address, 50);
openfile.getline(record[loop].phone_no, 12);
openfile >> record[loop].balance;
}
openfile.close(); //close text file
for (int i = 0; i <= loop + 1; i++) {
cout << "Account " << endl;
cout << "Account No. : " << record[i].acc_no << endl;
cout << "Name : " << record[i].name << endl;
cout << "Address : " << record[i].address << endl;
cout << "Phone Number : " << record[i].phone_no << endl;
cout << "Balance : " << record[i].balance << endl;
}
}
}
UPDATE:
The OP didn't properly cite the correct format in his data file. This answer is only valid up until the last iteration.
Don't use .eof() - that's more applicable to when you want to open the file and read it by characters.
A better way would be to use the insertion operator >> as follows:
#define ARR_SIZE 31
ACCOUNT temp;
ACCOUNT record[ARR_SIZE];
int i=0;
while(i < ARR_SIZE) {
openfile >> temp.acc_no >> temp.name >> temp.address >> temp.phone_no >> temp.balance;
record[i] = temp;
i++;
}
Of course, even better is to use std::string to hold the values from the input file, in addition to using std::vectors instead of arrays.

Using C++ Fstream to output numbers from text file - Need help separating lines

I need to create a program that takes integers from a text file, and outputs them, including the number, lowest number, largest number, average, total, N amount of numbers, etc. I can do this just fine with the code below, but I also need to process the text per line. My sample file has 7 numbers delimited with tabs per row, with a total of 8 rows, but I am to assume that I do not know how many numbers per row, rows per file, etc. there are.
Also, for what it's worth, even though I know how to use vectors and arrays, the particular class that I'm in has not gotten to them, so I'd rather not use them.
Thanks.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
int num;
int count = 0;
int total = 0;
int average = 0;
string str = "";
int numLines = 0;
int lowNum = 1000000;
int highNum = -1000000;
ifstream fileIn;
fileIn.open("File2.txt");
if (!fileIn) {
cout << "nError opening file...Closing program.n";
fileIn.close();
}
else {
while (!fileIn.eof()) {
fileIn >> num;
cout << num << " ";
total += num;
count++;
if (num < lowNum) {
lowNum = num;
}
if (num > highNum) {
highNum = num;
}
}
average = total / count;
cout << "nnTotal is " << total << "." << endl;
cout << "Total amount of numbers is " << count << "." << endl;
cout << "Average is " << average << "." << endl;
cout << "Lowest number is " << lowNum << endl;
cout << "Highest number is " << highNum << endl;
fileIn.close();
return 0;
}
}
One way to deal with the individual lines is to skip leading whitespaces before reading each value and to set the stream into fail-state when a newline is reached. When the stream is good after skipping and reading a value, clearly, there was no newline. If there was a newline, deal with whatever needs to happen at the end of a line, reset the stream (if the failure wasn't due to reaching eof()) and carry on. For example, the code for a loop processing integers and keeping track of the current line could like this:
int line(1);
while (in) {
for (int value; in >> skip >> value; ) {
std::cout << "line=" << line << " value=" << value << '\n';
}
++line;
if (!in.eof()) {
in.clear();
}
}
This code uses the custom manipulator skip() which could be implemented like this:
std::istream& skip(std::istream& in) {
while (std::isspace(in.peek())) {
if (in.get() == '\n') {
in.setstate(std::ios_base::failbit);
}
}
return in;
}

C++ iteration, file i/o

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
int main()
{
//Input .txt file
ifstream inputFile ("input.txt");
try
{
int i = 1; //Line iterator
int vertices = 0;
int faces = 0;
string line;
while (getline(inputFile, line))
{
//Take number from line 4, set as variable "vertices"
if (i == 3)
{
getline (inputFile,line);
size_t last_index = line.find_last_not_of("0123456789");
string str = line.substr(last_index);
vertices = atoi(str.c_str()); //Convert to int
cout << "vertices " + str << endl;
}
//Take number from line 11, set as variable "triangles"
if (i == 11)
{
getline (inputFile,line);
size_t last_index = line.find_last_not_of("0123456789");
string str = line.substr(last_index);
faces = atoi(str.c_str()); //Convert to int
cout << "faces " + str << endl;
}
if (i == 13)
{
i++;
break;
}
cout << "line: " + i << endl; //Prints line number
i++;
}
} catch(const char* error) {
cout << "Cannot read file, please try again." << error;
}
return 0;
}
This program is simply trying to read file, take a number from a couple of lines and for each line print "line: " with respective line number. It looks like C++ iterates differently to Java?
For some reason this program outputs:
*ine:
ne:
vertices 752
e:
:
Cannot read mesh, please try again.
faces r
annot read mesh, please try again.
nnot read mesh, please try again.*
I have no idea why.
This line:
cout << "line: " + i << endl;
should be:
cout << "line: " << i << endl;
Your + is adding i to the string constant "line: ", which has the effect of knocking one character off the front each time round the loop (and eventually going off the end, leading to undefined behaviour).
You can't add objects to strings in C++ in the way you're attempting, but you can send multiple objects to cout by repeated use of <<.
You then have the same problem here:
cout << "vertices " + str << endl;
and here:
cout << "faces " + str << endl;