Why does tellp() give -1? - c++

I'm trying to learn about fstream and here is the code that I'm running on VS2019:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main() {
//cout << "lOOKING IN FILE";
string s;
fstream dictionary("C:/Users/source/repos/Test2/Test2/Text.txt");
if (!dictionary) // were there any errors on opening?
exit(-1);
while (dictionary >> s) cout << s << '\n'; // Print all names in file
dictionary.seekp(0, ios::beg); // Go back to beginning of file
cout << dictionary.tellp() << endl;
dictionary >> s;
cout << s; // Print the first name
return 0;
}
The output is:
abc
acb
cab
-1
cab
Why does tellp give -1 and not go to beginning of file?

You need to clear the state of the stream.
Once the state of a stream have changed from good (i.e. when it reaches end-of-file or there's a failure) then you can't operate on the stream again without clearing the state.

Related

Create a vector of strings from file c++

I am trying to input three pieces of information from a .txt file.
First column is the course mark.
Second column is the course code.
Third column(s) is the course name.
I would like to store these as 3 vectors of strings.
Would using stringstream be a good option here? and maybe iterators?
The .txt file is like
65.6 10071 Mathematics 1
66.7 10101 Dynamics
60.0 10121 Quantum Physics and Relativity
66.9 10191 Introduction to Astrophysics and Cosmology
... ... ...
and my code so far is
#include<iostream>
#include<iomanip>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<string>
#include<iterator>
#include<sstream>
#include<vector>
//Main Function
int main()
{
//Define variables
std::string course_mark, course_code, course_name;
std::vector<std::string> course_mark_vector;
std::vector<std::string> course_code_vector;
std::vector<std::string> course_name_vector;
std::string data_file[100];
// Ask user to enter filename
std::cout<<"Enter data filename: ";
std::cin>>data_file;
int i{0};
// Open file and check if successful
std::fstream course_stream(data_file);
if(course_stream.is_open()) {
while (!course_stream.eof()) //while the end of file is NOT reached
{
//I have 2
getline(course_stream, course_mark, ' ');
course_mark_vector.push_back(course_mark);
getline(course_stream, course_code, ' ');
course_code_vector.push_back(course_code);
getline(course_stream, course_name, '\n');
course_name_vector.push_back(course_name);
i += 1; //increment number of lines
}
course_stream.close(); //closing the file
std::cout << "Number of entries: " << i-1 << std::endl;
}
else{
std::cout << "Unable to open file. Please run again" << std::endl;
return 1;
}
Any help would be greatly appreciated
Would using stringstream be a good option here?
Yes.
and maybe iterators?
There is no need for iterators in this case.
Try this:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
//Main Function
int main()
{
//Define variables
std::string course_mark, course_code, course_name, data_file, line;
std::vector<std::string> course_mark_vector, course_code_vector, course_name_vector;
int i = 0;
// Ask user to enter filename
std::cout << "Enter data filename: ";
std::cin >> data_file;
// Open file and check if successful
std::ifstream course_stream(data_file);
if (!course_stream.is_open())
{
std::cout << "Unable to open file. Please run again" << std::endl;
return 1;
}
while (std::getline(course_stream, line)) //while the end of file is NOT reached
{
std::istringstream iss(line);
iss >> course_mark;
course_mark_vector.push_back(course_mark);
iss >> course_code;
course_code_vector.push_back(course_code);
std::getline(iss >> std::ws, course_name);
course_name_vector.push_back(course_name);
++i; //increment number of lines
}
course_stream.close(); //closing the file
std::cout << "Number of entries: " << i << std::endl;
return 0;
}
Demo

Program that reads and writes integers to a file

Hello and thank you in advance. This is a very simple question but one that is getting on my nerves. What I want is just to ask for an integer to write to a file and then display every integer. I've learned how to either write to or display from a file and I've been successful at it but when I try to do both at a time it just asks me for the integer and don't display the numbers.
I think it may be a problem related to fstream or to the position of the pointer.
Here is the program:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <fstream>
using std::cout;
using std::cin;
using std::fstream;
using std::endl;
int a;
int x;
int main() {
fstream in;
in.open("op.txt", std::ios::app);
cout << "Write an integer" << endl;
cin >> x;
in << " " << x;
while (in >> a) {
cout << a << endl;
cout << in.tellg();
}
in.close();
return 0;
}
There are a few things that are need to be fixed:
in.open("op.txt",std::ios::in | std::ios::out | std::ios::app);
here is why you need to do std::ios::in and out
the second problem is when you are switching between writing and reading from the file like you stated the problem is with the position of the read pointer
in.seekg(0, std::ios::beg);//before the while loop;
this sets the read position to 0 so the program can read from the file from the beginning.here

Program failing to open file from variable

I know i'm making a stupid mistake somewhere and even though i've been reading old questions i'm unable to catch it. I'm hoping someone would point me in the right direction. As you can probably tell i'm new to C++.
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main()
{
//local variables
string answer, filePath, wordtest;
fstream openFile;
***stuff removed for space reasons***
cout << "Enter the full file path" << endl;
getline(cin, filePath);
openFile.open(filePath, ios::in); //Open file
while (openFile.peek() != EOF)
{
cin >> wordtest;
cout << wordtest;
//getline(cin, wordtest);
{
//wordCount = wordCount + 1;
}
}
openFile.close();
openFile.clear(std::ios_base::goodbit);
cout << "Loaded file and read " << wordCount << " words";
}
You are neither reading nor writing to openFile.
You need to use operator<< or operator>> with openFile.

Numbering Lines in a File With C++

I wrote a quick C++ program that asks the user for a input text file and an output text file. The program is then supposed to number the lines in the file on the left margin. However, I cannot seem to get it working properly, it compiles fine but does not number the lines like it is supposed to. I believe it is a logical error on my part. I am also not too familiar with file i/o in C++ as I am just learning it now using old school textbooks.
Here is the file:
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>
using namespace std;
int main(void)
{int i = 0 , num = 1;
string inputFileName;
string outputFileName;
string s;
ifstream fileIn;
ofstream fileOut;
char ch;
cout<<"Enter name of input file: ";
cin>>inputFileName;
cout<<"Enter name of output file: ";
cin>>outputFileName;
fileIn.open(inputFileName.data());
fileOut.open(outputFileName.data());
assert(fileIn.is_open() );
assert(fileOut.is_open() );
while (!(fileIn.eof()))
{ch=fileIn.get();
if (ch=='\n') num++;
fileOut << num << "\n";
s.insert(i,1,ch); //insert character at position i
i++;
}
fileOut << s;
fileIn.close();
fileOut.close();
return 0;
}
If anyone could point me in thr right direction or give me some tips I would be eternally grateful.
int i = 0;
string line;
while (getline(infile, line))
{
outfile << (i++) << " " << line << "\n";
}

Cant get correct output in program

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
fstream file("file.txt");
file << "this is new line" << endl;
file.flush();
string c;
file >> c;
cout << c << endl;
file.close();
}
when i run this output is empty, if i remove line file << "this is new line" << endl; I'm getting correct output, why ?
By writing to the file, you are moving the internal file pointer to the end of it. This means the the next time you read, you will be at the end of the file, and so nothing will be read.
Look at seek() for moving the file pointer.