boost filename extension with multiple "." - c++

I have filenames like this : 09.04.201115_09_ch_4.txt
I would like to extract the filestem only. I tried using boost filesystem path, but it has problems with the multiple dots in the filename. (I didn't come up with the naming).
Is there a way around that? Can I get only the filename without the extension? My code looks like this:
std::string stringtmp = path.parent_path().string() +"/"+path.stem().string()+".png" ;
Ok here's the code (it's using the ROOT framework):
#include "TH1F.h"
#include "TH2F.h"
#include "TF1.h"
#include "TSpectrum.h"
#include "TCanvas.h"
#include "TVirtualFitter.h"
#include "TMath.h"
#include "TGraph.h"
#include <fstream>
#include <iostream>
#include "TApplication.h"
#include "TImage.h"
#include <string>
#include <sstream>
#include "TStyle.h"
#include "TROOT.h"
#include "TGraph2D.h"
#include "boost/filesystem.hpp"
Int_t npeaks = 10;
Double_t fpeaks(Double_t *x, Double_t *par) {
Double_t result = par[0] + par[1]*x[0];
for (Int_t p=0;p<npeaks;p++) {
Double_t norm = par[3*p+2];
Double_t mean = par[3*p+3];
Double_t sigma = par[3*p+4];
result += norm*TMath::Gaus(x[0],mean,sigma);
}
return result;
}
void graph(std::string name, bool big){
Float_t x[5001],y[5001];
std::ifstream in;
TCanvas *c1 = new TCanvas("c1","c1",10,10,1000,500);
if(!big){
in.open(name.c_str());
for(Int_t i = 0 ; i< 5001 ;i++){
in >> x[i] >> y[i];
}
c1->cd(1);
TGraph *gr = new TGraph(5001,x,y);
gr->SetMinimum(-60.);
//gr->GetYAxis()->SetMinimum(-70.);
// gr->GetYAxis()->SetTitle("dB");
gr->Draw("A*");
TH1F *h = gr->GetHistogram();
for(Int_t i = 0 ; i< 5001 ;i++){
if(y[i]>= -60.)
h->SetBinContent(i,y[i]);
}
//c1->cd(2);
h->SetYTitle("Intensity in dB");
h->SetXTitle("#lambda in nm");
h->SetTitle("Sectrum");
h->Draw();
TSpectrum *s = new TSpectrum(1000);
Int_t nfound = s->Search(h,1,"new");
std::cout <<"Found " << nfound << " candiate peaks to fit\n";
c1->Update();
//estimate linear background
Double_t par[3000];
TF1 *fline = new TF1("fline","pol1",842,852);
h->Fit("fline","qn");
//c1->cd(2);
par[0] = fline->GetParameter(0);
par[1] = fline->GetParameter(1);
//loop on all found peaks. Eliminate peaks at the background level
Float_t *xpeaks = s->GetPositionX();
for (Int_t p=0;p<nfound;p++) {
Float_t xp = xpeaks[p];
Int_t bin = h->GetXaxis()->FindBin(xp);
Float_t yp = h->GetBinContent(bin);
if (yp-TMath::Sqrt(yp) < fline->Eval(xp)) continue;
par[3*npeaks+2] = yp;
par[3*npeaks+3] = xp;
par[3*npeaks+4] = 3;
npeaks++;
}
c1->Update();
TImage *img = TImage::Create();
img->FromPad(c1);
std::stringstream _name;
_name << name << ".png";
_name >> name;
boost::filesystem::path path(name);
std::string stringtmp = path.parent_path().string() +"/"+path.stem().string()+".png" ;
std::cout <<"\n \n stem \n \n"<<stringtmp<< '\t' << path.stem().string() << std::endl;
img->WriteImage(stringtmp.c_str());
return;
}
The output looks like this:
Warning in : Deleting canvas with same name: c1
Found 39 candiate peaks to fit
stem
29/12.04.201115_09_ch_4.txt.png 12.04.201115_09_ch_4.txt

This works for me:
#include <ostream>
#include <iostream>
#include <boost/filesystem.hpp>
int main()
{
boost::filesystem::path const p("C:\\Code\\09.04.201115_09_ch_4.txt");
// prints "C:\Code\09.04.201115_09_ch_4.txt"
std::cout << p << '\n';
// prints "09.04.201115_09_ch_4.txt"
std::cout << p.filename() << '\n';
// prints "09.04.201115_09_ch_4"
std::cout << p.stem() << std::endl;
}
So, essentially all you need is p.stem(); if that doesn't work for you, you'll need to post a compilable repro.

Related

My function does not always work because of the second argument

My trouble is that my function not always work, and i don't know why.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <string>
using namespace std;
void fill_zeros(std::string& fill_zeros_str, int fill_zeros_num){
if (fill_zeros_str.length()<fill_zeros_num){
int i = 0;
for (i=0;i<=((int)fill_zeros_num)-((int)fill_zeros_str.length());i++){
fill_zeros_str = "0"+fill_zeros_str;
}
}
}
int main(){
string testString = to_string(2);
fill_zeros(testString,7);
cout << testString << "\n";
return 0;
}
The second argument of fill_zeros (fill_zeros_num) does not work all the time, and I don't know why.
Because in
for (i=0;i<=((int)fill_zeros_num)-((int)fill_zeros_str.length());i++)
the length of fill_zeros_str changes as you add zeros(decrease by one), and you are also adding one to i(so, the start is adding by one, and the end is decreasing by one). So the best way is to define a length at the beginning of the function to store the string length.
Your loop is modifying the std::string on each iteration, which affects its length(). The loop is re-evaluating the length() on each iteration.
You need to calculate the number of zeros wanted and save that value to a local variable first, and then use that variable in your loop. Also, your loop needs to use < instead of <=.
Try this:
void fill_zeros(std::string& str, size_t min_length){
if (str.length() < min_length){
size_t fill_zeros_num = min_length - str.length();
for (size_t i = 0; i < fill_zeros_num; ++i){
str = "0" + str;
// or: str.insert(0, "0");
// or: str.insert(0, '0');
// or: str.insert(str.begin(), '0');
}
}
}
Live Demo
However, there is a much simpler way to implement fill_zeros() that doesn't involve using a manual loop at all:
void fill_zeros(std::string& str, size_t min_length){
if (str.length() < min_length){
str = std::string(min_length - str.length(), '0') + str;
// or: str.insert(0, std::string(min_length - str.length(), '0'));
// or: str.insert(str.begin(), std::string(min_length - str.length(), '0'));
// or: str.insert(0, min_length - str.length(), '0');
// or: str.insert(str.begin(), min_length - str.length(), '0');
}
}
Live Demo
Alternatively:
#include <sstream>
#include <iomanip>
void fill_zeros(std::string& str, size_t min_length){
if (str.length() < min_length){
std::ostringstream oss;
oss << std::setw(min_length) << std::setfill('0') << str;
str = oss.str();
}
}
Live Demo
In which case, you could simply get rid of fill_zeros() altogether and apply the I/O manipulators directly to std::cout in main() instead:
#include <iostream>
#include <iomanip>
int main(){
std::cout << std::setw(7) << std::setfill('0') << 2 << "\n";
return 0;
}
Live Demo

C++ Sorting Filenames In A Directory

I wanted to have some advice about the code I have.
I managed to get what I wanted done, but I do not think it is the "proper" way of doing it in the programmers' world.
Could you help me improve the code by any means and also if there are any better ways of doing this please share them as well.
I have files named in the format:
501.236.pcd
501.372.pcd
...
612.248.pcd etc.
I wanted to put the filenames in ascending order according to the filenames using C++.
This is the code I use:
#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
#include <sstream>
using namespace std;
using namespace boost::filesystem;
int main()
{
vector <string> str,parsed_str;
path p("./fake_pcd");
string delimiter = ".";
string token,parsed_filename;
size_t pos = 0;
int int_filename;
vector <int> int_dir;
//insert filenames in the directory to a string vector
for (auto i = directory_iterator(p); i != directory_iterator(); i++)
{
if (!is_directory(i->path())) //we eliminate directories in a list
{
str.insert(str.end(),i->path().filename().string());
}
else
continue;
}
//parse each string element in the vector, split from each delimiter
//add each token together and convert to integer
//put inside a integer vector
parsed_str = str;
for (std::vector<string>::iterator i=parsed_str.begin(); i != parsed_str.end(); ++i)
{
cout << *i << endl;
while ((pos = i->find(delimiter)) != string::npos) {
token = i->substr(0,pos);
parsed_filename += token;
i->erase(0, pos + delimiter.length());
}
int_filename = stoi(parsed_filename);
int_dir.push_back(int_filename);
parsed_filename = "";
}
cout << endl;
parsed_str.clear();
sort(int_dir.begin(), int_dir.end());
//print the sorted integers
for(vector<int>::const_iterator i=int_dir.begin(); i != int_dir.end(); i++) {
cout << *i << endl;
}
//convert sorted integers to string and put them back into string vector
for (auto &x : int_dir) {
stringstream ss;
ss << x;
string y;
ss >> y;
parsed_str.push_back(y);
}
cout << endl;
//change the strings so that they are like the original filenames
for(vector<string>::iterator i=parsed_str.begin(); i != parsed_str.end(); i++) {
*i = i->substr(0,3) + "." + i->substr(3,3) + ".pcd";
cout << *i << endl;
}
}
This is the output, first part is in the order the directory_iterator gets it, the second part is the filenames sorted in integers, and the last part is where I change the integers back into strings in the original filename format.
612.948.pcd
612.247.pcd
501.567.pcd
501.346.pcd
501.236.pcd
512.567.pcd
613.008.pcd
502.567.pcd
612.237.pcd
612.248.pcd
501236
501346
501567
502567
512567
612237
612247
612248
612948
613008
501.236.pcd
501.346.pcd
501.567.pcd
502.567.pcd
512.567.pcd
612.237.pcd
612.247.pcd
612.248.pcd
612.948.pcd
613.008.pcd
Taking a few hints from e.g. Filtering folders in Boost Filesystem and in the interest of total overkill:
Live On Coliru Using Boost (also On Wandbox.org)
#include <boost/range/adaptors.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/filesystem.hpp>
#include <iostream>
#include <optional>
#include <set>
namespace fs = boost::filesystem;
namespace {
using Path = fs::path;
struct Ranked {
std::optional<int> rank;
Path path;
explicit operator bool() const { return rank.has_value(); }
bool operator<(Ranked const& rhs) const { return rank < rhs.rank; }
};
static Ranked rank(Path const& p) {
if (p.extension() == ".pcd") {
auto stem = p.stem().native();
std::string digits;
using namespace boost::spirit::x3;
if (phrase_parse(begin(stem), end(stem), +digit >> eoi, punct, digits))
return { std::stoul(digits), p };
}
return { {}, p };
}
}
int main() {
using namespace boost::adaptors;
auto dir = boost::make_iterator_range(fs::directory_iterator("."), {})
| transformed(std::mem_fn(&fs::directory_entry::path))
| transformed(rank)
;
std::multiset<Ranked> index(begin(dir), end(dir));
for (auto& [rank, path] : index) {
std::cout << rank.value_or(-1) << "\t" << path << "\n";
}
}
Prints:
-1 "./main.cpp"
-1 "./a.out"
501008 "./501.008.pcd"
501236 "./501.236.pcd"
501237 "./501.237.pcd"
501247 "./501.247.pcd"
501248 "./501.248.pcd"
501346 "./501.346.pcd"
501567 "./501.567.pcd"
501948 "./501.948.pcd"
502008 "./502.008.pcd"
502236 "./502.236.pcd"
502237 "./502.237.pcd"
502247 "./502.247.pcd"
502248 "./502.248.pcd"
502346 "./502.346.pcd"
502567 "./502.567.pcd"
502948 "./502.948.pcd"
512008 "./512.008.pcd"
512236 "./512.236.pcd"
512237 "./512.237.pcd"
512247 "./512.247.pcd"
512248 "./512.248.pcd"
512346 "./512.346.pcd"
512567 "./512.567.pcd"
512948 "./512.948.pcd"
612008 "./612.008.pcd"
612236 "./612.236.pcd"
612237 "./612.237.pcd"
612247 "./612.247.pcd"
612248 "./612.248.pcd"
612346 "./612.346.pcd"
612567 "./612.567.pcd"
612948 "./612.948.pcd"
613008 "./613.008.pcd"
613236 "./613.236.pcd"
613237 "./613.237.pcd"
613247 "./613.247.pcd"
613248 "./613.248.pcd"
613346 "./613.346.pcd"
613567 "./613.567.pcd"
613948 "./613.948.pcd"
BONUS: No-Boost Solution
As the filesystem library has been standardized and using Rangev3:
Live On Wandbox
#include <filesystem>
#include <iostream>
#include <map>
#include <optional>
#include <range/v3/action/remove_if.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/subrange.hpp>
#include <range/v3/view/transform.hpp>
namespace fs = std::filesystem;
namespace {
using namespace ranges;
using Ranked = std::pair<std::optional<int>, fs::path>;
bool has_rank(Ranked const& v) { return v.first.has_value(); }
static Ranked ranking(fs::path const& p) {
if (p.extension() == ".pcd") {
auto stem = p.stem().native();
auto non_digit = [](uint8_t ch) { return !std::isdigit(ch); };
stem |= actions::remove_if(non_digit);
return { std::stoul(stem), p };
}
return { {}, p };
}
}
int main() {
using It = fs::directory_iterator;
for (auto&& [rank, path] : subrange(It("."), It())
| views::transform(std::mem_fn(&fs::directory_entry::path))
| views::transform(ranking)
| views::filter(has_rank)
| to<std::multimap>())
{
std::cout << rank.value_or(-1) << "\t" << path << "\n";
}
}
Prints e.g.
501236 "./501.236.pcd"
501346 "./501.346.pcd"
501567 "./501.567.pcd"
502567 "./502.567.pcd"

C++ function with pointer argument

I am writing a C++ program that outputs data to a file, generates a python script and calls pyplot to make the plotting.
However, when I pass the arguments in terms of the pointers, it can be compiled properly, but cannot run. It returns error. When I use Xcode debug mode and execute it step by step, it gives correct result by chance but not always. Sometimes it also returns an error.
I doubt that it might be caused by some memory allocation problem, but I cannot identify what is exactly the problem.
My codes are as following:
1) main
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include "PyCPlot.h"
using namespace std;
double pi = 3.1415926;
int main(int argc, const char * argv[]) {
int nline = 100;
double * np_list = new double(nline);
double * pack_fraction_np = new double (nline);
for (int i=0; i<nline; i++){
np_list[i] = double(i)/double(nline)*2*pi;
pack_fraction_np[i] = cos(np_list[i]);
}
PyCPlot_data_fout("RandomPacking", nline, np_list, pack_fraction_np);
PyCPlot_pythonscript("RandomPacking", "Random Packing");
PyCPlot_pyplot("RandomPacking", "Random Packing");
return 0;
}
2) head file
#ifndef PyCPlot_h
#define PyCPlot_h
#include <iostream>
#include <cmath>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
int PyCPlot_data_fout(string datafilename, int nline, double * x, double *y){
ofstream fout;
fout.open(datafilename+".txt");
fout << nline << endl;
for (int i=0; i<nline; i++){
fout << x[i] << " " << y[i] << endl;
}
fout.close();
return 0;
}
int PyCPlot_pythonscript(string datafilename, string plttitle){
string strhead = "import numpy as np\nimport matplotlib.pyplot as plt\n";
string strpltfig = "plt.figure()\n";
string strpltplt = "plt.plot(xlist, ylist)\n";
string strplttit = "plt.title('"+plttitle+"')\n";
string strpltshw = "plt.show()\n";
string strfileopen ="f = open('"+datafilename+".txt', 'r')\n";
string strreadline ="size = map(int, f.readline().split())\n";
string strpltlist ="xlist = np.zeros((size))\nylist = np.zeros((size))\n";
string strfor = "for i in range(size[0]):\n xlist[i], ylist[i] = map(float, f.readline().split())\n";
ofstream pyout;
pyout.open("PyCPlot_"+datafilename+".py");
pyout << strhead << strfileopen << strreadline << strpltlist << strfor;
pyout << strpltfig << strpltplt << strplttit << strpltshw;
pyout.close();
return 0;
}
int PyCPlot_pyplot(string datafilename, string plttitle){
string strsystemsh ="source ~/.bashrc; python PyCPlot_"+datafilename+".py";
system(strsystemsh.c_str());
return 0;
}
#endif /* PyCPlot_h */
When it is ran, I get below error message
malloc: *** error for object 0x1002002e8: incorrect checksum for freed object - object was probably modified after being freed.
You want to pass an array, so pass an actual array which can be sized at runtime (std::vector), not some random pointer that hopefully will be pointing to the first element of an array (and in this case, it doesn't)
Your mistake is using new double(x) instead of new double[x]. The former allocates a single double with a value equal to x, and the latter allocates an array of double of size x and returns a pointer to the first element, but, as I've said, you wouldn't have that problem at all had you actually used std::vector and not dabbled with pointers like the early 90s style (not to mention, you wouldn't have a memory leak had you used std::vector).
You're doing a few things which are not right or seem strange.
The code new double(nline) will allocate a single double with the value of nline, which doesn't seem what you intend.
It looks like you intend to dynamically allocate an array of double. Actually from the code you've shown there's no reason you can't do a simple array as the size is known at compile time.
This code below:
double * np_list = new double(nline);
double * pack_fraction_np = new double (nline);
Could be replaced with:
double np_list[nline];
double pack_fraction_np[nline];
The following lines allocate a single double for np_list and pack_fraction_np:
double * np_list = new double(nline);
double * pack_fraction_np = new double (nline);
As a result, when you will enter your loop, you will write data to invalid memory blocks. You have to use square brackets to define an array (I do not get any error; using clang++).
Consider to use the std::vectorclass. Here is an example (your example) with std::pair of double nested in a std::vector:
PyCPlot.h
#ifndef PyCPlot_h
#define PyCPlot_h
#include <iostream>
#include <cmath>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <vector>
#include <utility>
using namespace std;
int PyCPlot_data_fout(string datafilename, std::vector<std::pair<double, double>>& v){
ofstream fout;
fout.open(datafilename+".txt");
fout << v.size() << endl;
for (int i=0; i < v.size(); i++){
fout << v[i].first << " " << v[i].second << endl;
}
fout.close();
return 0;
}
int PyCPlot_pythonscript(string datafilename, string plttitle){
string strhead = "import numpy as np\nimport matplotlib.pyplot as plt\n";
string strpltfig = "plt.figure()\n";
string strpltplt = "plt.plot(xlist, ylist)\n";
string strplttit = "plt.title('"+plttitle+"')\n";
string strpltshw = "plt.show()\n";
string strfileopen ="f = open('"+datafilename+".txt', 'r')\n";
string strreadline ="size = map(int, f.readline().split())\n";
string strpltlist ="xlist = np.zeros((size))\nylist = np.zeros((size))\n";
string strfor = "for i in range(size[0]):\n xlist[i], ylist[i] = map(float, f.readline().split())\n";
ofstream pyout;
pyout.open("PyCPlot_"+datafilename+".py");
pyout << strhead << strfileopen << strreadline << strpltlist << strfor;
pyout << strpltfig << strpltplt << strplttit << strpltshw;
pyout.close();
return 0;
}
int PyCPlot_pyplot(string datafilename, string plttitle){
string strsystemsh ="source ~/.bashrc; python PyCPlot_"+datafilename+".py";
system(strsystemsh.c_str());
return 0;
}
#endif /* PyCPlot_h */
PyCPlot.cpp
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include "PyCPlot.h"
using namespace std;
double pi = 3.1415926;
int main(int argc, const char * argv[]) {
int nline = 100;
std::vector<std::pair<double, double>> v;
v.reserve(nline);
double a;
for (int i=0; i < nline; i++){
a = double(i)/double(nline)*2*pi;
v.push_back(std::make_pair(a, cos(a)));
}
PyCPlot_data_fout("RandomPacking", v);
PyCPlot_pythonscript("RandomPacking", "Random Packing");
PyCPlot_pyplot("RandomPacking", "Random Packing");
return 0;
}

Randomized Parameters Using System()?

I am attempting to try some randomized parameters for minisat while calling the program using system(). I've never done anything like this before and have to admit I am pretty lost.
For example I can do like:
system("minisat -luby -rinc=1.5 <dataset here>")
How can I randomize it to be -luby or -no-luby and randomize the 1.5 value for -rinc?
system is only a normal function that receive a c-style string as the parameter. You can construct the string by yourself.
bool luby = true;
double rinc = 1.5;
system((std::string("minisat -")+(luby?"luby":"no-luby")+" -rinc="+std::to_string(rinc)).c_str());
You need construct the command dynamically with variables.
bool luby = true; // if you want -no-luby, set it to be false
double rinc = 1.5; // set it to be other values
char command[1024];
std::string luby_str = (luby ? "luby" : "no-luby");
std::snprintf(command, sizeof(command), "minisat -%s -rinc=%f", luby_str.c_str(), rinc);
system(command);
Just as #RemyLebeau pointing out, the C++ style should be better.
std::string command;
std::ostringstream os;
os << "minisat -" << luby_str << " -rinc=" << rinc;
system(command.c_str());
Here, you can try using a random string command generator like this, to create a randomized command:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <random>
#include <string>
std::string getCommand()
{
std::string result = "minisat ";
srand(time(0));
int lubyflag = rand() % 2; //Not the best way to generate random nums
//better to use something from <random>
if (lubyflag == 1)
{
result += "-luby ";
} else
{
result += "-no-luby ";
}
double lower_bound = 0; //Now were using <random>
double upper_bound = 2; //Or whatever range
std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
std::default_random_engine re;
double rinc_double = unif(re);
result += "-rinc=" + rinc_double;
return result;
}
int main()
{
std::string command = getCommand();
system(command.c_str());
}
If you want all control, do this:
bool flaga = false;
double valueb = 1.5;
system(std::string("ministat " + ((flaga) ? "-luby " : "-no-luby ") +
"rinc= " + std::to_string(valueb)).c_str());

Several links errors in my project: LNK2019, LNK2005

I tried every solution for those errors in google, but found no answer for this problem.
The project is really big, but here is one of the files:
cpp file:
#include"Cluster.h"
Cluster::Cluster()
{}
Cluster::~Cluster() //close files and reomve dynamically-allocated memory
{
Splittedfile.close();
clustring.close();
Linefile.close();
delete[] protein;
delete[] NextProtein;
}
void spllitFile()
{
// check length of the file, and set length of NumOfSeq
Linefile.seekg(0, Linefile.end);
long sizeOfFile = Linefile.tellg();
NumOfProteins = sizeOfFile - 20;
//from the begining of LineFile:
//read 1 protein from LineFile & write it to Splittedfile.
//Each loop is advaced with:
// /n to Splittedfile & another 1 character "slide" in LineFile.
Linefile.seekg(ios_base::beg);
char* CopyProtein = new char[20]; // allocate buffer for reading 1 protein
long startPlaceOfRead = 0;
while (!(Linefile.eof()))
{
if ((startPlaceOfRead != 0) || (((sizeOfFile - startPlaceOfRead) < 20.0)))
Splittedfile << "\n";
Linefile.seekg(startPlaceOfRead);//to next protein - one for enter. one for back
if ((sizeOfFile - startPlaceOfRead) < 20.0) break;//if not enough for 1 protein
Linefile.read(CopyProtein, 20); // read 1 protein from infile
Splittedfile.write(CopyProtein, 20);// write to outfile
startPlaceOfRead++;
}
delete[] CopyProtein; // release dynamically-allocated memory
}
void buildClustrs()
{
Form Form;
char X[] = "XXXXXXXXXXXXXXXXXXXX‎‎‎‎««««««««";
int removed = 0;
for (int first = 0; first <= NumOfProteins; first++)//for the 1st
{
Splittedfile.seekg(0);
Splittedfile.seekg(first * 20 + 2 * first, ios_base::beg);
//int ThisPlace = Splittedfile.tellg();
Splittedfile.read(protein, 20);
if (strcmp(X, protein) == 0) continue; // 0= EQUAL
clustring << "\n\n\n";
clustring.write(protein, 20);
cout << "protein number " << first << " written as a lonely cluster " << endl; // WHEN FOUND belonging only-printing!
//remove this protein
Splittedfile.seekg(-20, Splittedfile.cur);
Splittedfile << "XXXXXXXXXXXXXXXXXXXX";
removed++;
for (int Allother = first + 1; Allother <= NumOfProteins; Allother++) //the following protein
{
Splittedfile.seekg(Allother * 20 + 2 * Allother);
Splittedfile.read(NextProtein, 20); // READ next protein, -read -go on automaticly-
if (strcmp(X, NextProtein) == 0) continue;
if ( (Form.Compare2Proteins (protein, NextProtein) ) !=-1)//>=60%
{
clustring << "\n";
clustring.write(NextProtein, 20);// write to clustring second protein in cluster
cout << "protein number " << Allother << " written to cluster " << first << endl; // WHEN FOUND belonging only-printing!
//remove this protein
Splittedfile.seekg(-20, Splittedfile.cur);//to next protein
Splittedfile << "XXXXXXXXXXXXXXXXXXXX";
removed++;
}
}
}
}
Header file:
#pragma once
#include <iostream>
#include <string.h>
#include <fstream>
#include <sstream>
#include <tchar.h>
#include <string.h>
#include "Main.h"
#include "Form.h"
using namespace std;
class Cluster
{
public:
Cluster();
~Cluster();
void spllitFile();
void buildClustrs();
};
Screenshot with the errors:
I add more headers files, it may assist, beacuse I see no one know where the problem exactly is. thank you.
form.h:
#pragma once
#include <string>
#include <tchar.h>
#include <string.h>
using namespace std;
char *formString[6] = { "111100", "111010", "101110", "110110", "111001", "110101" };
class Form
{
public:
Form();
~Form();
//void spllitBySizeOfForm(int sizeOfForm, char protein[20], int i);
int Compare2Proteins(char *protein1, char *Nextprotein);
char* stringXform(char str[6], char form[6]);
};
HashEntry.h:
#pragma once
#include <string>
#include <tchar.h>
#include <string.h>
using namespace std;
class HashEntry
{
public:
HashEntry(int key, int value);
int getValue();
int getKey();
};
HashMap.h:
#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <tchar.h>
#include <string.h>
#include "HashEntry.h"
using namespace std;
const int TABLE_SIZE = 20;
class HashMap
{
public:
HashMap::HashMap();//
HashMap::~HashMap();
int get(int key); // get value. for example: B--> get 0.
void put(int key, int value);//build entry AND put value in it.
void PutHmap(); // Put values to HashMap. get it by Hmap.get
};
main.h:
#pragma once
#include <iostream>
#include <string.h>
#include <fstream>
#include <sstream>
#include <tchar.h>
#include <string.h>
#include "Cluster.h"
using namespace std;
long NumOfProteins = 0;
char* protein = new char[20]; // allocate memory for file content
char* NextProtein = new char[20]; // allocate memory for file content
fstream Splittedfile;
fstream newClusering;
ofstream clustring;
ifstream Linefile;
class Main
{
public:
//void position(char form[6], char str[6])
};