Read from file in c++ till end of line? - c++

How can i read data untill end of line?I have a text file "file.txt" with this
1 5 9 2 59 4 6
2 1 2
3 2 30 1 55
I have this code:
ifstream file("file.txt",ios::in);
while(!file.eof())
{
....//my functions(1)
while(?????)//Here i want to write :while (!end of file)
{
...//my functions(2)
}
}
in my functions(2) i use the data from the lines and it need to be Int ,not char

Don't use while(!file.eof()) as eof() will only be set after reading the end of the file. It does not indicate, that the next read will be the end of the file. You can use while(getline(...)) instead and combine with istringstream to read numbers.
#include <fstream>
#include <sstream>
using namespace std;
// ... ...
ifstream file("file.txt",ios::in);
if (file.good())
{
string str;
while(getline(file, str))
{
istringstream ss(str);
int num;
while(ss >> num)
{
// ... you now get a number ...
}
}
}
You need to read Why is iostream::eof inside a loop condition considered wrong?.

As for reading until the end of the line. there's std::getline.
You have another problem though, and that is that you loop while (!file.eof()) which will most likely not work as you expect. The reason is that the eofbit flag is not set until after you try to read from beyond the end of the file. Instead you should do e.g. while (std::getline(...)).

char eoln(fstream &stream) // C++ code Return End of Line
{
if (stream.eof()) return 1; // True end of file
long curpos; char ch;
curpos = stream.tellp(); // Get current position
stream.get(ch); // Get next char
stream.clear(); // Fix bug in VC 6.0
stream.seekp(curpos); // Return to prev position
if ((int)ch != 10) // if (ch) eq 10
return 0; // False not end of row (line)
else // (if have spaces?)
stream.get(ch); // Go to next row
return 1; // True end of row (line)
} // End function

If you want to write it as function in order to call some where, you can use a vector. This is a function which I use to read such file and return integers element wise.
vector<unsigned long long> Hash_file_read(){
int frames_sec = 25;
vector<unsigned long long> numbers;
ifstream my_file("E:\\Sanduni_projects\\testing\\Hash_file.txt", std::ifstream::binary);
if (my_file) {
//ifstream file;
string line;
for (int i = 0; i < frames_sec; i++){
getline(my_file, line);
numbers.push_back(stoull(line));
}
}
else{
cout << "File can not be opened" << endl;
}
return numbers;
}

Related

Reading in Floats from Text File and Counting the Columns [duplicate]

How can i read data untill end of line?I have a text file "file.txt" with this
1 5 9 2 59 4 6
2 1 2
3 2 30 1 55
I have this code:
ifstream file("file.txt",ios::in);
while(!file.eof())
{
....//my functions(1)
while(?????)//Here i want to write :while (!end of file)
{
...//my functions(2)
}
}
in my functions(2) i use the data from the lines and it need to be Int ,not char
Don't use while(!file.eof()) as eof() will only be set after reading the end of the file. It does not indicate, that the next read will be the end of the file. You can use while(getline(...)) instead and combine with istringstream to read numbers.
#include <fstream>
#include <sstream>
using namespace std;
// ... ...
ifstream file("file.txt",ios::in);
if (file.good())
{
string str;
while(getline(file, str))
{
istringstream ss(str);
int num;
while(ss >> num)
{
// ... you now get a number ...
}
}
}
You need to read Why is iostream::eof inside a loop condition considered wrong?.
As for reading until the end of the line. there's std::getline.
You have another problem though, and that is that you loop while (!file.eof()) which will most likely not work as you expect. The reason is that the eofbit flag is not set until after you try to read from beyond the end of the file. Instead you should do e.g. while (std::getline(...)).
char eoln(fstream &stream) // C++ code Return End of Line
{
if (stream.eof()) return 1; // True end of file
long curpos; char ch;
curpos = stream.tellp(); // Get current position
stream.get(ch); // Get next char
stream.clear(); // Fix bug in VC 6.0
stream.seekp(curpos); // Return to prev position
if ((int)ch != 10) // if (ch) eq 10
return 0; // False not end of row (line)
else // (if have spaces?)
stream.get(ch); // Go to next row
return 1; // True end of row (line)
} // End function
If you want to write it as function in order to call some where, you can use a vector. This is a function which I use to read such file and return integers element wise.
vector<unsigned long long> Hash_file_read(){
int frames_sec = 25;
vector<unsigned long long> numbers;
ifstream my_file("E:\\Sanduni_projects\\testing\\Hash_file.txt", std::ifstream::binary);
if (my_file) {
//ifstream file;
string line;
for (int i = 0; i < frames_sec; i++){
getline(my_file, line);
numbers.push_back(stoull(line));
}
}
else{
cout << "File can not be opened" << endl;
}
return numbers;
}

C++ check is any character in a floating point array from txt file

I am working on a program to read floating point number from an txt file and store in array, and I need to check are there any invalid input like character.
My code is:
int main() {
string line;
ifstream myfile("data.txt");
int size;
float* result;
if (myfile.is_open()) {
getline(myfile, line);
size = stoi(line);
result = new float[size];
for (int i = 0; i < size; i++) {
myfile >> result[i];
/*if ( (isdigit(arr[i])==0) ){
cout << "Invaild input." << endl;
return 0;
}*/
}
myfile.close();
}
else {
return 0;
}
}
The first line of the txt file is the size of the array and the second line is the contents like
5 //size
1 -2 9.2 4.7 -5.2 //content
How can I check that is there any character exist in the array like 1 -2 B 4.7 -5.2 //Invalid input ?
I try the isdigit function but it fail.
If you get an invalid input, reading will fail, and you can check this in the usual manner.
if (myfile >> result[i])
{
// Handle success.
}
else
{
// Handle failure.
}
I have given 2 solutions. One uses built in arrays and other uses std::vector.
Solution 1: Using built in array
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main()
{
std::string line;
std::ifstream inFile("input.txt");
//in case of using array, size must be fixed and predetermined
double arr[120] = {0.0}; //you can choose size according to your needs
if(inFile)
{
double i = 0;//this variable will be used to add element into the array
int count = 0;
while(getline(inFile, line, '\n'))
{
std::istringstream s(line);
//take input(from s to i) and then checks stream's eof flag status
while(s >> i || !s.eof()) {
//check if either failbit or badbit is set
if(s.fail())
{
//clear the error state to allow further operations on s
s.clear();
std::string temp;
s >> temp;
continue;
}
else
{
arr[count] = i;
++count;
//break out of the loop so we do go out of bounds
if(count >=120)//note 120 is the size of the array and you can change it according to your needs
{
break;
}
}
}
}
}
else
{
std::cout<<"file could not be read"<<std::endl;
}
inFile.close();
for(double i: arr)
{
std::cout<<"elem: "<<i<<std::endl;
}
return 0;
}
The output of solution 1 can be seen here.
Solution 2: Using std::vector
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main()
{
std::string line;;
std::ifstream inFile("input.txt");
std::vector<double> vec;
if(inFile)
{
double i = 0;//this variable will be used to add element into the vector
while(getline(inFile, line, '\n'))
{
std::istringstream s(line);
//take input(from s to i) and then checks stream's eof flag status
while(s >> i || !s.eof()) {
if(s.fail())
{
//clear the error state to allow further operations on s
s.clear();
std::string temp;
s >> temp;
continue;
}
else
{
vec.push_back(i);
}
}
}
}
else
{
std::cout<<"file could not be read"<<std::endl;
}
inFile.close();
for(double i: vec)
{
std::cout<<"elem: "<<i<<std::endl;
}
return 0;
}
The ouput of solution 2 can be seen here.
Important Note
The advantage of using std::vector over built in array(in this case) is that you don't have know the size of the vector beforehand. So it is preferable because you don't know how many integers are there in the input.txt file. std::vector can handle this correctly(dynamically). But when using built in arrays you must know/specify the size of the array beforehand. This in turn means you must know beforehand how many integers are there in the input.txt, which is not practical.

C++, reading chars into a vector<char> from a file, character by character

I am trying to read in the first 7 chars of a file named "board.txt" into a vector<'char> but I am having issues for some reason. I am not too familiar with C++ so any advice would be appreciated, here is the code I have so far
//rack
int charCount = 0;
char ch;
ifstream rackIn("board.txt");
while(rackIn.get(ch) && charCount < 7){
this->getMyRack().push_back(ch);
}
And here is the function getMyRack used in the code above:
vector<char> board::getMyRack(){
return this->myRack;
}
myRack is a char vector
I tried to test this in my main using this:
for (int i = 0; i < test->getMyRack().size(); ++i){
cout << test->getMyRack().at(i);
}
but it does not output anything, why are the chars i am reading in not being added into my char vectors?
Because you don't put char in your vector. Your function getMyRack() returns vector but not address of your vector. You can add method to your class board for adding char, for example:
void board::addChar(char c){
this->myRack.push_back(c);
}
And then call this function:
while(rackIn.get(ch) && charCount < 7){
this->addChar(ch);
}
Or change the return type of your function.
read line one or (how much lines required) from file to a string
create substring of 7 chars from beginning
std::ifstream file("board.txt");
std::string str;
// to read single line
std::getline(file, str);
// to read 7 chars
str= str.substr(0,7);
vector<char> char_buf;
for(size_t i =0; i <= str.size();i++)
{
char_buf.push_back(str[i])
}
// use the char_buf
easier or second way is use
#include<fstream> // for ifstream
#include <cstdlib> // for exit()
std::string file_name ="board.txt";
std::ifstream input_stream;
std::vector<char> char_buf;
input_stream.open(file_name);
if(input_stream.fail()) { exit(0);}
int char_no=0;
while(i<=7)
{
char c = input_stream.get();
char_buf.push_back(c);
i++;
}
// use char_buf
std::string str;
int char_count=0;
// Read the next line from File untill it reaches the 7.
while (std::getline(in, str)&& char_count!=7)
{
// Line contains string of length > 0 then save it in vector
if (str.size() > 0)
your_char_vector.push_back(str);
char_count++;
if(char_count==7)
break;
}

C++ reading from file puts three weird characters

When i read from a file string by string, >> operation gets first string but it starts with "i" . Assume that first string is "street", than it gets as "istreet".
Other strings are okay. I tried for different txt files. The result is same. First string starts with "i". What is the problem?
Here is my code :
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int cube(int x){ return (x*x*x);}
int main(){
int maxChar;
int lineLength=0;
int cost=0;
cout<<"Enter the max char per line... : ";
cin>>maxChar;
cout<<endl<<"Max char per line is : "<<maxChar<<endl;
fstream inFile("bla.txt",ios::in);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
while(!inFile.eof()) {
string word;
inFile >> word;
cout<<word<<endl;
cout<<word.length()<<endl;
if(word.length()+lineLength<=maxChar){
lineLength +=(word.length()+1);
}
else {
cost+=cube(maxChar-(lineLength-1));
lineLength=(word.length()+1);
}
}
}
You're seeing a UTF-8 Byte Order Mark (BOM). It was added by the application that created the file.
To detect and ignore the marker you could try this (untested) function:
bool SkipBOM(std::istream & in)
{
char test[4] = {0};
in.read(test, 3);
if (strcmp(test, "\xEF\xBB\xBF") == 0)
return true;
in.seekg(0);
return false;
}
With reference to the excellent answer by Mark Ransom above, adding this code skips the BOM (Byte Order Mark) on an existing stream. Call it after opening a file.
// Skips the Byte Order Mark (BOM) that defines UTF-8 in some text files.
void SkipBOM(std::ifstream &in)
{
char test[3] = {0};
in.read(test, 3);
if ((unsigned char)test[0] == 0xEF &&
(unsigned char)test[1] == 0xBB &&
(unsigned char)test[2] == 0xBF)
{
return;
}
in.seekg(0);
}
To use:
ifstream in(path);
SkipBOM(in);
string line;
while (getline(in, line))
{
// Process lines of input here.
}
Here is another two ideas.
if you are the one who create the files, save they length along with them, and when reading them, just cut all the prefix with this simple calculation: trueFileLength - savedFileLength = numOfByesToCut
create your own prefix when saving the files, and when reading search for it and delete all what you found before.

Reading text file per line in C++, with unknown line length

I have a text file, that is formatted somewhat like this:
1 3 4 5 6
6 7 8
4 12 16 17 18 19 20
20
0
A line can contain 1 to 10000 integers. What I need to do, is read all of them line by line.
Pseudocode like this:
line=0;
i=0;
while(!file.eof()){
while(!endLine){
array[0][i++]=file.readChar();
}
line++;i=0;
}
So, I have an array , into which I would like to read every line, and each line would consist of each of these integers.
The problem I'm having, is how to check if the end of a line has come.
Note, I can't use strings.
Yes, This is for a homework, but the main task for the assignment is to build a tree and then transform it. I can do that, but I've no idea how to read the integers from the file.
Probably something like this:
after reading an int, I manually skip spaces, tabs, carriage return and end of line (for this one you'll have to implement your logic).
To read an int I read it directly using the C++ functions of ifstream. I don't read it character by character and then recompose it as a string :-)
Note that I skip \r as "spaces. The end of line for me is \n.
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
std::ifstream file("example.txt");
std::vector<std::vector<int>> ints;
bool insertNewLine = true;
int oneInt;
//The good() here is used to check the status of
//the opening of file and for the failures of
//peek() and read() (used later to skip characters).
while (file.good() && file >> oneInt)
{
if (insertNewLine)
{
std::vector<int> vc;
ints.push_back(vc);
//With C++11 you can do this instead of the push_back
//ints.emplace_back(std::vector<int>());
insertNewLine = false;
}
ints.back().push_back(oneInt);
std::cout << oneInt << " ";
int ch;
while ((ch = file.peek()) != std::char_traits<char>::eof())
{
if (ch == ' '|| ch == '\t' || ch == '\r' || ch == '\n')
{
char ch2;
if (!file.read(&ch2, 1))
{
break;
}
if (ch == '\n' && !insertNewLine)
{
std::cout << std::endl;
insertNewLine = true;
}
}
else
{
break;
}
}
}
//Here we should probably check if we exited for eof (good)
//or for other file errors (bad! bad! bad!)
return 0;
}
There is a function called getline() which will read a whole line. Link
You need a function to read a value from a file or indicates an end of line or end of file condition, something like:
result_type GetNextValue (input_file, &value)
{
if next thing in file is a number, set value and return number_type
if next thing in file is an end of line, return end_of_line_type
if end of file found, return end_of_file_type
}
and then your array building loop becomes:
line = 0
item = 0
eof = false
while (!eof)
{
switch (GetNextValue (input_file, value))
{
case value_type:
array [line][item++] = value
case end_of_line_type:
line++;
item = 0;
case end_of_file_type:
eof = true
}
}
I'll leave the details to you as it's homework.
You could read the numbers in a char and check against carriage return. A snippet that I had just tried is given below:
ifstream ifile;
ifile.open("a.txt");
char ch;
while((ch = ifile.get()) != EOF)
{
std::cout<<ch<<"\n";
if (ch == '\n')
std::cout<<"Got New Line";
}
ifile.close();