How can I split a file? - c++

I was trying a code for splitting a file
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
int dim,k=1;
double x,y,x1,y1;
vector<double> AUX1[0],AUX2[0];
string file="ne_1417.dat",number;
ifstream IN(file);
while(IN >> x >> y)
{
AUX1.push_back(x);
AUX2.push_back(y);
}
IN.close();
dim=AUX1.size();
number=to_string(k);
ofstream OUT(number+file);
for(int i=0;i<dim;i++)
{
OUT<<AUX1[i]<<" "<<AUX2[i]<<endl;
if((AUX1[i+1]-AUX1[i])>50.){
k++;
number=to_string(k);
OUT.close();
ofstream OUT(number+file);
}
}
return 0;
}
I get the number of files I want but only the first file is full of data, the others are empty and I can't understand why =(
I need help, please <3

The problem is a matter of scoping and variable shadowing.
You have a variable named OUT in the function scope, defined before the writing loop. Then inside the if you define a new and totally different variable named OUT as well. When the scope of the block ends, so does the life-time of the new variable, and it is destructed.
You should not define a new variable, but rather reopen the existing file:
if((AUX1[i+1]-AUX1[i])>50.){
k++;
number=to_string(k);
OUT.close();
OUT.open(number+file); // Open the new file
}
All of the large compilers should be able to detect the variable shadowing and issue warnings about it. If you don't get such a warning then you need to enable more warnings (I recommend -Wall -Wextra -Wpedantic for GCC and Clang, and /W4 for VC++).

Related

I can't read from a file

I wrote a code to make "text1.txt" file. It worked correctly, then I've been trying to read from the file, but every time is_open() function doesn't return true. Even so I copied other codes in the way exactly they are in different compilers, but it never works. How will I solve this:(
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream file1("text1.txt");
string str;
if(file1.is_open()){
while(getline( file1, str)){
cout<<str;
}
}
else
cout<<"the file is not open"<<endl;
return 0;
}
How are you running your program?
The most common cause of this I've seen is that you're running your program inside an IDE (like Visual Studio), and your current directory isn't where you think it is.
Try putting in the full path to the file and see if your problem disappears.

In C++, close a static file stream inside a class member function

I have a C++ program (developed in Visual C++ 2017) that need to output a lot of lines to files. Below are simplified version just to illustrate the problem.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <filesystem>
#include <algorithm>
#include <numeric>
#include <fstream>
using namespace std;
class Test{
public:
void output(int a){
static ofstream out("a.txt", fstream::in | fstream::out | fstream::app);
out<<a<<"\n";
}
};
int main()
{
Test t;
for(int i = 0; i < 10; i++){
t.output(i);
}
t.~Test();
remove("a.txt");
}
The remove("a.txt") never works. I understand that the text file is never properly closed. I explicitly call the t.~Test() in hope it will close the static ofstream but it seems id does not work.
The reason to make the ofstream static is it significantly improve the performance of my production code since I assume it just open the file one time and use it instead of open and close the file for each call
I know the design is bad, but this is from legacy code and I am reluctant to change the function signature.
Is there a simple way to make this work without changing the "out" function signature? Thanks
The life-time of a local static variable is the life-time of the program itself. It will not be destructed until the program exits.
One possible way to go around your problem could be to use a member variable in the class instead. Open the stream in the constructor, and close it in the destructor. If multiple objects of the class needs to share the stream them make it a static member variable which is opened by its definition (remember that static member variables might need separate declaration and definition).

How to read doubles from a string in c++ using istringstream

I am new to programming c++. I am trying to read 75 doubles that are inside of a string that I read from a file. I am trying to use istringstream.
This is what I have so far:
Header File:
#ifndef READPOINTS_H_INCLUDE
#define READPOINTS_H_INCLUDE
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std::istringstream;
.....
istringstream linestr;
CPP FILE:
#include
void ReadPoints::grabPoin(const string& read_line, vector<doubles> PointVector){
linestr(read_line);
for(int i = 0; i < 75; i++){
linestr >> value
pointVector.push_back(value);
}
}
When I compile this code I get the following error:
ReadPoints.cpp: In member function ‘bool ReadPoints::grabPoint(const string&, std::vector&)’:
ReadPoints.cpp:48:19: error: no match for call to ‘(std::istringstream {aka std::basic_istringstream}) (const string&)’
linestr(read_line);
Can anyone explain what is wrong and why I am getting the no match for call?
Don't place a definition inside a header. Currently, you've got istringstream linestr;: place this in exactly one *.cpp file, and then in your header, extern std::istringstream linestr (the latter is called a declaration, which is different to a definition). However, this stringstream is best defined in the function itself anyway.
Replace linestr(read_line) in your *.cpp with std::istringstream line_str{ read_line } and remove these two lines from your header file: using namespace std::istringstream; and istringstream linestr;.
Your code should now look like this:
void ReadPoints::grabPoin(const string& read_line, vector<doubles> PointVector){
std::istringstream linestr{ read_line }; // if that doesn't work, use linestr(read_line) instead... note the () and {} have different meanings
for(int i = 0; i < 75; i++){
linestr >> value
pointVector.push_back(value);
}
}
Here's a couple of other tips:
Never place a using directive inside a header (that is, using namespace)
Avoid using directives at all costs. If you don't want to type std::istringstream, place it inside your *.cpp files (yes, each of them), as using std::istringstream.
If you must use a using directive, you need to do it like so: using namespace std;.
Both of these will help you to avoid namespace pollution, which makes calling the right functions difficult.

Passing an ifstream variable between members of the same object, C++

Goal: Using the class variable so that an ifstream declared in an object's member can be used by the following member of the same object, without having to use function header parameter passing.
Problem: The local ifstream of the created object test isn't being re-used in the second member of that object. I must be setting it up wrong, how do I fix this?
Classes and files feel like climbing a mountain to me right now, but I can't even find the first foothold - getting the blasted variable to work! I looked around the net for too long but all examples are convoluted, I just want to have something basic working to start tinkering with. I'm dead sure it's something stupidly easy that I'm missing, really frustrating >:[
main.cpp
#include "file.h
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
file test;
test.file_pass();
return 0;
}
file.h
#ifndef FILE_H
#define FILE_H
#include <fstream>
#include <iostream>
using namespace std;
class file
{
public:
file();
void file_pass();
//private:
ifstream stream;
};
#endif
file.cpp
#include "file.h"
//**********************************
//This will read the file.
file::file()
{
ifstream stream("Word Test.txt");
}
//**********************************
//This will output the file.
void file::file_pass()
{
//ifstream stream("Word Test.txt"); //if line activated, program works fine of course.
string line;
while(getline(stream, line))
cout << line << endl;
}
Here you are creating a new local variable with the same name as the class member:
file::file()
{
ifstream stream("Word Test.txt");
}
Instead you can use this to initialize the class member in the constructor:
file::file() : stream("Word Test.txt")
{
}

Undefined reference to a function when linking with g++

I am trying to link several object files and I am getting 3 undefined reference to a function errors.
inputtest.cpp
//test of input methods
#include <iostream>
#include <string>
#include <fstream>
#include <string>
#include <vector>
#include "Vector.h"
#include "Particle.h"
#include "read_particle_input.h"
#include "User_input.h"
#include "Particle_vector.h"
using namespace std;
using namespace berger_DEM;
int main() {
Particle_vector particles;
User_input input_data;
read_particle_input(particles, input_data);
cout <<endl<< particles.getpart(1).rho()<<endl<<particles.getpart(1).radius()<<endl;
return 0;
}
I am linking it with 5 object files with the names found in the ".h" files(just .o files compiled from .cpp files of the same name). One of the errors I receive is
undefined reference to 'berger_DEM::read_particle_input(berger_DEM::Particle_vector&, berger_DEM::User_input&)
note that this function has a prototype in read_particle_input.h and is implemented in read_particle_input.o. I am also getting two other undefined references, but I believe they are the same issue and if i can solve this one, the same solution should work for those two.
prototype:
namespace berger_DEM
{
void read_particle_input(Particle_vector&,User_input&);
}
implementation:
//method to read in particle_input.dat
void read_particle_input(Particle_vector & particles, User_input & input_data)
{
//define local variables
Vector velocity_in;
Vector position_in;
double radius_in;
double rho_in;
//open file and define file pointer
std::ifstream particle_input ("particle_input.dat");
//go through each line in particle_input.dat and define each particle
if (particle_input.is_open()) {
for(int i=0;i<input_data.num_particles();i++) {
//read one line from particle_input.dat
particle_input >> position_in;
particle_input >> radius_in;
particle_input >> rho_in;
particle_input >> velocity_in;
//set particle properties and position/velocity
particles.getpart(i).setrho(rho_in);
particles.getpart(i).setradius(radius_in);
particles.getpart(i).move(position_in);
particles.getpart(i).accelerate(velocity_in);
}
}
//close file
particle_input.close();
}
I've been looking all over for someone who had the same issue, but I was unable to find anything.
Thanks for the help.
Your implementation is missing the class scope.
change
void read_particle_input(Particle_vector & particles, User_input & input_data)
{
//define local variables
to
void berger_DEM::read_particle_input(Particle_vector & particles, User_input & input_data)
{
//define local variables
In implementation file it should be defined as,
void berger_DEM::read_particle_input(Particle_vector& particles, User_input& input_data);
{// ^^^^^^^^^^^ specify that 'read_particle_input' is part of the namespace
//...
}