File I/O end of line - c++

I am trying to read text from a file into an array and then output the contents of each array index to the output file. I need the data to be read/stored until it reaches the end of line, at which point it should re-start reading/storing and re-using the array for temporary storage only to be output to the output file.
I cannot use the getline function because the idea is that later I will incorporate the use of some model classes to store the individual words as member variables of the classes. I will need to have the words separated to know which words get saved as which variables. For this reason I need to be able to just identify the corresponding index position and get it's contents.
I know my syntax is incorrect so I was hoping someone knew a correct syntax for recognizing the end of line.
this is what I've tried so far:
ifstream fin;
//open file...
char next[20]; //creating an word array to hold the characters of a word.
fin >> next;
while (!fin == '\n') //<------ THIS IS WHAT I THINK THE PROBLEM IS.
//I KNOW ITS INCORRECT BUT DO NOT KNOW THE CORRECT WAY.
{
//input words, store to array, and output to file
fin >> next;
}

You should use a std::string instead of a char array to handle words of any size. Streams also have an implicit conversion to void* (bool in C++11 or later) to test if the stream is still valid.
std::ifstream fin(filename);
std::string word;
while(fin >> word) {
//do something with word
}

Related

How to read a file line by line without using the string class?

So in my c++ class, we're not allowed to use the string class right now. To substitute strings, we're using character arrays.
The assignment requires that i read from a file that contains a sentence on each line. The first line of the file is an integer that tells how many lines are in the file.
My first problem is that reading in the integer into a variable and using that variable in an array causes an error saying that the variable must be constant.
How can I get past that? I need a 2D array to count how many characters each sentence has. I want to initialize my array as char FileSentences[numberOfLines][81]. It's been decided that the sentence character cap will be 80 characters long, so the width of each row has to be 81 to account for the \0.
My second problem comes from how I'm reading in the integer. Since the first line in the file is an integer, I'm reading it like:
int numberOfLines;
ifstream fin;
fin.open("TestTextFile.txt");
fin >> numberOfLines;
This works and it sets the variable numberOfLines to the correct value. However, when I call fin.getline, the next thing it will read in is a blank. If I call fin.getline again, it is the first sentence of the file. Is there another way to read in the integer to prevent that or should I just set a blank sentence in memory to hold the first fin.getline value and then proceed to reading sentences into my array?
For the first problem, use a std::vector.
// Define a typedef for a line.
typedef char Line[81];
// Read the number of lines.
fin >> numberOfLines;
// Define a vector for the lines.
std::vector<Line> lines(numberOfLines);
For the second problem, use ifstream::ignore() to ignore the rest of the line.
fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Make sure to add
#include <limits>
to use std::numeric_limits.
I need a 2D array to count how many characters each sentence has. I
want to initialize my array as char FileSentences[numberOfLines][81].
Easy solution is to allocate what you need:
typedef char LINE[81];
LINE* FileSentences = new LINE[numberOfLines];
After you are done iterating on FileSentences, free the memory as follows:
delete [] FileSentences;

C++ Reading data from a file line by line

I am new to programming and I have this question. I have this file that I am opening
ifstream fin;
FILE * pFile;
pFile = fopen (fname,"r");
The file has 3 data each line. The first is an integer, the second is an alphabet and the third is an address(like computer memory address). How do I extract these line by line into 3 variables that I can process, and then repeat it with next line and so.
You should know that there are preferred C++ methods for manipulation of files over C stdio methods:
Using standard predefined streams: std::ofstream for output and std::ifstream for input.
Formatted/Unformatted I/O such as operator<<(), operator>>(), read() and write().
In-memory I/O for manipulation of extracted data.
What you need for this particular case is input stream functionality along with formatted input. The formatted input will be done through operator>>().
But before you get to that, you have to instantiate a file stream. Since you're using input, std::ifstream will be used:
std::ifstream in("your/path.txt");
The next thing to do is to create the three variables whose values you will extract into the stream. Since you know the types beforehand, the types you will need is an integer, character, and string respectively:
int num;
char letter;
std::string address;
The next thing to do is to use operator>>() to obtain the first valid value from the stream. The way it works is that the function analyses the type of the righthand operand and determines if the characters extracted from the file stream will create a valid value after parsing. When the stream hits whitespace, the new line character or the EOF (end-of-file) character (or a character that doesn't match that of the operand's type), extraction will stop.
What makes IOStreams powerful is that it allows chaining of expressions. So you are able to do this:
in >> num >> letter >> address;
which is equivalent to:
in >> num;
in >> letter;
in >> address;
This is all that is needed for this simple case. In more complex situations, loops and in-memory I/O might be needed for successful extractions.

storing text to string from a file that contains spaces

So I've been doing algorithms in C++ for about 3 months now as a hobby. I've never had a problem I couldn't solve by googleing up until now. I'm trying to read from a text file that will be converted into a hash table, but when i try and capture the data from a file it ends at a space. here's the code
#include <iostream>
#include <fstream>
int main()
{
using namespace std;
ifstream file("this.hash");
file >> noskipws;
string thing;
file >> thing;
cout << thing << endl;
return 0;
}
I'm aware of the noskipws flag i just don't know how to properly implement it
When using the formatted input operator for std::string it always stops at what the stream considers to be whitespace. Using the std::locale's character classification facet std::ctype<char> you can redefine what space means. It's a bit involved, though.
If you want to read up to a specific separator, you can use std::getline(), possibly specifying the separator you are interested in, e.g.:
std::string value;
if (std::getline(in, value, ',')) { ... }
reads character until it finds a comma or the end of the file is reached and stores the characters up to the separator in value.
If you just want to read the entire file, one way to do is to use
std::ifstream in(file.c_str());
std::string all((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
I think the best tool for what you're trying to do is get, getline or read. Now those all use char buffers rather than std::strings, so need a bit more thought, but they're quite straightforward really. (edit: std::getline( file, string ), as pointed out by Dietmar Kühl, uses c++ strings rather than character buffers, so I would actually recommend that. Then you won't need to worry about maximum line lengths)
Here's an example which will loop through the entire file:
#include <iostream>
int main () {
char buffer[1024]; // line length is limited to 1023 bytes
std::ifstream file( "this.hash" );
while( file.good( ) ) {
file.getline( buffer, sizeof( buffer ) );
std::string line( buffer ); // convert to c++ string for convenience
// do something with the line
}
return 0;
}
(note that line length is limited to 1023 bytes, and if a line is longer it will be broken into 2 reads. When it's a true newline, you'll see a \n character at the end of the string)
Of course, if you a maximum length for your file in advance, you can just set the buffer accordingly and do away with the loop. If the buffer needs to be very big (more than a couple of kilobytes), you should probably use new char[size] and delete[] instead of the static array, to avoid stack overflows.
and here's a reference page: http://www.cplusplus.com/reference/fstream/ifstream/

C++ Reading an multiline file with lines with arbitary lengths and format without using a stringstream

I have an input stream with the following lines:
# <int> <int>
<some_data_type> <some_data_type> <some_data_type> ..... <some_data_type>
<some_data_type_1> <some_data_type_2> <some_data_type_3> <some_data_type_1> <some_data_type_2> <some_data_type_3> .... <some_data_type_1> <some_data_type_2> <some_data_type_3>
In the above stream all three lines are different and have to be parsed differently. Currently,I am using a reading method as follows:
void reader( std::istream & is, DataStructure & d ){
std::string line;
getline(is,line);
std::stringstream s(line);
//parse line 1
getline(is,line);
std::stringstream line2(line);
//parse line 2
getline(is,line);
std::stringstream line3(line);
//parse line 3
}
Now the idea is not to make use of std::stringstream at all, as a line can arbitarily large and we donot want to load everything into memory twice. So, it would be better if it was possible to read from the input stream directly into the user given datastructure d.
An idea is to make use of std::istream_iterator but unfortunately the different lines have different parsing needs. For example, in the last line, three elements from the stream together constitute a single data element.
The only idea that seems plausible to me at this moment is to handle the stream buffer directly. It would be great if anyone could recommend a better way of doing this.
NOTE: Cannot make use of a tertiary data structure like std::stringstream. It is essential to read from the stream directly into the user provided data structure.
EDIT: Please note we are only allowed a single pass over the file.
Now the idea is not to make use of std::stringstream at all, as a line
can arbitarily large and we donot want to load everything into memory
twice. So, it would be better if it was possible to read from the
input stream directly into the user given datastructure d.
Olaf explained the extraction operator above but then we have a new requirement:
This will only work for the first line, where it is known there is a
fixed number of elements.
and
(2) Unfortunately, I have no discriminator beyond my knowledge that each instance of the data
structure needs to be instantiated with information stored in three
different lines. All three lines have different lengths and different
data elements. Also, I cannot change the format.
plus
(3) All information is treated as unsigned integer.
Now the next issue is that we don't know what the data structure actually is, so given what has come before it appears to be dynamic in some fashion. Because we can treat the data as unsigned int then we can use the extraction operator possibly, but read into a dynamic member:
vector<unsigned int> myUInts;
...
inFile >> currentUInt;
myUInts.push_back(currentUInt);
But then the issue of where to stop comes into play. Is it at the end of the first line, the third? If you need to read an arbitrary number of unsigned ints, whilst still checking for a new line then you will need to process white space as well:
inFile.unsetf(ios_base::skipws);
How you actually handle that is beyond what I can say at the moment without some clearer requirements. But I would guess it will be in the form:
inFile >> myMember;
char next = infile.peek()
//skip whitespace and check for new line
//Repeat until data structure filled, and repeat for each data structure.
Then do not use std::getline() at all. Define an istream operator for your types and use these directly
std::istream &operator >>(std::istream &f, DataStructure &d)
{
f >> d.member1 >> d.member2 >> ...;
return f;
}
void reader(std::istream & is, DataStructure &d)
{
is >> d;
}
There's no need fiddling with an std::istream_iterator or directly manipulating the stream buffer.

C++ Populate a vector of strings from a space-delimited text file

I have a space delimited text file, from which I need to extract individual words to populate a vector<string>.
I've tried playing around with strtok, but I understand this is not working because strtok returns a char pointer. Any way to extract the words from the file, and fill the string vector with them? Thanks!
There are "fancier" ways, but in my opinion the following's most understandable (and useful as a basis for variations) for beginners:
if (std::ifstream input(filename))
{
std::vector<std::string> words;
std::string word;
while (input >> word)
words.push_back(word);
}
Consider using an ifstream to read the file.
Then you can use the >> operator to move the next word into the string.