In the following example,
ifstream myFile;
myFile.open("example.txt", ios::binary);
cout << myFile.rdbuf() << endl;
myFile.close();
The contents of the file will be printed, in its entirety on one line. You can also do it like this:
ifstream myFile;
myFile.open("example.txt", ios::binary);
unsigned char character = myFile.get();
while(myFile){
cout << "one character = ";
cout << character;
character = myFile.get(); //gets each individual character, 1 at a time
}
myFile.close();
And it will print the contents of the file, one character at a time. However, if you try to do the methods one after the other (in any order), only one method will actually print anything. Could someone explain why, in the following example, the call to rdbuf() won't print the contents of the file?
ifstream myFile;
myFile.open("example.txt", ios::binary);
unsigned char character = myFile.get();
while(myFile){
cout << "one character = ";
cout << character;
character = myFile.get(); //gets each individual character, 1 at a time
}
cout << myFile.rdbuf() << endl;
myFile.close();
Thank you!
As you read in from a stream, the read position is incremented. After reading in an entire file character by character, the read position is at the end of file. In this case, rdbuf() (the read buffer) has nothing further of interest.
If you wanted to print the file again using rdbuf() you can set the read position with myFile.seekg(0, std::ios::beg); prior to attempting to print. In this specific example an error bit may already be set, so you may need to do a myFile.clear() before moving the read pointer.
Related
I want to read a text file in c++ using ifstream to know the number of words, characters, lines.
unsigned int wordNum = 0;
unsigned int lineNum = 0;
unsigned int charNum = 0;
char check;
ifstream in("example_2_4.txt");
char temp[30];
if (!in.is_open()) {
cout << "File opening error!" << endl;
}
while (!in.eof()){
in.getline(temp, 30);
wordNum += countWord(temp);
charNum += countChar(temp);
lineNum++;
in.clear();
}
The problem is that eof() does not work since there exists a line that exceeds 30 characters.
I've changed !in.eof() to in>>check and it works well but it reads a character so I can't count all characters in line.
I shouldn't use string class and can't change buffer size.
Is there any proper way to check eof?
I'm not entirely sure what you are asking, but ifstream::getline() sets the failbit when it tries to read a string that's too long. In your case, the eof bit will never be set (even though you are clearing all the bits anyway).
You can simply do:
while (in)
and in addition to not clearing any of the flags.
If you want to be able to read a line that is longer than the buffer you can store it in, you need to read the file some other way, perhaps using ifstream::get() instead.
in.getline(temp, 30); returns istream& so moving it in the while loop to here while(in.getline(temp, 30)) will return false when it reaches the end of file or a read error.
Try this:
string line;
ifstream myfile ("example_2_4.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
wordNum += countWord(line);
charNum += countChar(line);
lineNum++;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
Given your constraints, I would suggest:
Read the file character by character.
End the loop when the EOF is reached.
Increment the number of characters.
Check whether the character marks the end of a word. If so, increment the word cound.
Check whether the character is a newline. If so, increment the number of lines.
int c;
while ( (c = in.get()) != EOF )
{
++charNum;
if (isspace(c) )
{
++wordNum;
}
if ( c == '\n' )
{
++lineNum;
}
}
This code always prints the last line of the file. I expected it to print all the text, one line at a time, from the file. Any idea why it doesn't work?
string filename;
cout << "File to read: ";
cin >> filename;
ifstream afile;
afile.open(filename.c_str());
string line;
while(!afile.eof()) {
getline(afile, line);
cout << line;
}
afile.close();
Trying it this way does the same thing:
for (string line; getline(afile, line);) {
cout << line;
}
Maybe this is an issue with my terminal? This works...
for (string line; getline(afile, line);) {
cout << line << endl;
}
The problem is that only the last line is printed. Correct?
I suggest that you add std::endl in your while loop. It can make the issue more clear. Sometimes the output can be confusing.
You can also check the line-delimiting character in your input file. '\n' is the default delimiter for getline. If a different character is used, specify it as getline's 3rd parameter.
From cplusplus.com:
If the delimiter is found, it is extracted and discarded, i.e. it is
not stored and the next input operation will begin after it.
Since your original code snippet doesn't insert any extra newlines itself, there is nothing making the output to the terminal go to the next line. When the output runs out of horizontal space what happens next is up to the terminal. I'm not sure what terminal you're using but in your case, it just wraps the cursor back to the first character on that line without a linefeed. On a windows command shell, it just wraps around to the next line.
Also note that:
while(!afile.eof()) {
getline(afile, line);
cout << line;
}
is a common antipattern. As already pointed out, more appropriate would be:
while(getline(afile, line)) {
cout << line << '\n';
}
The file stream only becomes false after you've reached eof and try to read from it.
I'm just learning about text file input/output. I have outputted a file which contains a header and 10 rows of data underneath it.
I now want to read this back to the main function. This works for me if I leave out the header in the text file, but if I leave the header in, I get an infinite loop.
How can I skip the 1st line (the header line) in reading this data back, or if possible, read back the header as well as the data?
Here is what I have so far:
void fileRead(int x2[], double y2[], int& n, char filename)
{
ifstream fin ("pendulum.txt"); // fin is an input file stream
if(!fin) //same as fin.fail()
{
cerr << "Failure to open pendulum.txt for input" << endl;
exit(1);
}
int j = 0, dummy = 0; //index of the first value j and dummy value
while(!fin.eof()) //loop while not end of file
{
fin >> dummy >> x2[j] >> y2[j];
cout << setw(5) << fixed << j
<< setw(12) << scientific << x2[j] << " "
<< setw(12) << y2[j] << endl; //print a copy on screen
j += 1;
}
fin.close(); //close the input file
}
You can first read the header of the file then the real contents you want as follows:
string line;
getline(fin, line);//just skip the line contents if you do not want header
while (fin >> dummy >> x2[j] >> y2[j] )
{ //^^if you do not always have a dummy at the beginning of line
//you can remove dummy when you read the rest of the file
//do something
}
Your best bet would be to use
fin.ignore(10000,'\n');
http://www.cplusplus.com/reference/istream/istream/ignore/
This will ignore the first 10000 character in the file, or ignore the characters until a newline is reached. The 10000 is fairly arbitrary and should be a number that will always be longer than the maximum line length.
man, this gentleman over there helped me quite a lot. You see, everyone says to use getline(); to skip one line, but the problem is that sometimes you dont want to store anything in a buffer, so ignore() makes much more sense to me. Well so I would like to back up our fella's answer by adding that, you could use " numeric_limits::max()" which will make it have no limit, it will ignore until it finds the delimiter...
`
#include <iostream>
#include <fstream>
#include <limits>
using std::streamsize;
int main() {
ifstream fin ("pendulum.txt");
fin.ignore(numeric_limits<streamsize>::max(),'\n');
}
`
http://www.cplusplus.com/reference/limits/numeric_limits/
I'm trying to read character by character from a text file until EOF, put them into a character array, so that I can manipulate it after. Compiled with g++ without errors, and when run, I'm prompted for the input file but then it just hangs.
int main (int argc, char *argv[]) {
string filename;
ifstream infile;
char *cp, c[1024];
memset (c, 0, sizeof(c));
cp = c;
cout << "Enter file name: " << endl;
cin >> filename;
//open file
infile.open( filename.c_str() );
//if file can't open
if(!infile) {
cerr << "Error: file could not be opened" << endl;
exit(1);
}
while (!infile.eof()); {
infile.get(c, sizeof(infile));
// get character from file and store in array c[]
}
}//end main
You should try the istream::read() method rather than get(). This will help resolve any buffer overruns:
unsigned int chars_read = 0;
//...
// Read in the file.
if (!infile.read(c, sizeof(c))
{
// Handle the read error here.
// Also check for EOF here too.
}
// Obtain the number of characters actually read.
chars_read = infile.gcount();
First off, you don't want to test for eof()! Somehow I start to feel like Don Quixote having found my windmills. However, I do know that you need to check that the input was successful after trying to read it because before attempting to read the stream can't know whether it will be successful.
You program actually doesn't hang! It just waits for you to enter sizeof(infile) characters or end the input (e.g., using Ctrl-D on UNIXes and Ctrl-Z on Windows). Of course, this may look remarkable like a hanging program. You can verify that this is, indeed, the problem by using a smaller size, e.g., 4. Of course, sizeof(infile) is nearly as good as a small random number: It is the size of an object of type std::ifstream and who can tell what that is? You probably meant to use sizeof(c) to make sure that the call to get(c, n) won't write more character than can fit into c.
Try this:
int cont = 0;
while(infile.good()) {
c[cont++] = infile.get();
}
Here is the code snippet:
int main()
{
char ch=26;
ofstream fout;
fout.open("key.txt");
if (fout.is_open())
{
for(int i=0; i<256; i++)
{
ch=i;
fout << ch;
cout<<ch;
}
fout.close();
}
else
cout << "Unable to open file";
string line;
ifstream fout1 ("key.txt");
if (fout1.is_open())
{
while (fout1)
{
fout1.get(ch);
cout <<" "<< (int)ch<<" "<<ch<<"\t ";
}
fout1.close();
}
else
cout << "Unable to open file";
return 0;
}
I found out that while reading 26th character it stops program. If it is escaped then all others are read. Note I am using Code Blocks IDE.
The reason why you can't read the 26th character is because its value is 26. And that is interpreted in textfiles as an end-of-file marker. You must open your file as binary ,then it will work.
In the code shown, I suggest you close the output file first, before opening it for reading. This will make sure that any characters in the buffer is flushed to disk. Also, after reading you might want to flush cout as well, if the program doesn't end there.
Also note that some characters are not printable, or do weird things when printed (like jumping to the beginning of the line, or deleting whats already being printed).