Getting data from multiple text file

Hi everyone, I'm having a problem with a program i need for a project. What I'm trying to do is to get some datas from multpile file. The program has to open the file, "read" it and when finds the words Isp or Ivac has to take the number that appears on that string. The txt file will look like this:
.(a lot of other stuff)
.
.
Ivac, M/SEC 3213 2134
Isp, M/SEC 551.6 1406.4
.
.
.
Ivac, M/SEC 751.6 1606.4
Isp, M/SEC 731.6 1566.4

I need to get both set of values for each file and then save them on a single text file. What I've done so far is the following program
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{ string isp,ivac;
char filename[10],FILENAME[10];
isp=("Isp");
for (int i=0;i<=100;i++)
{
sprintf(filename, "%d_%d.out",i,i-100);
fstream in(filename,ios::in);
if(in.is_open()){
cout<<"";
}
else{
cerr<<"error opening file";
}
string what="";
while(getline(in,what))
{ if(what=="Isp,")
{sprintf(FILENAME,"isp_ivac.txt");
ofstream out(FILENAME, ios::out);
out<< isp <<" "<< ivac <<endl;
}
if(what=="Ivac,")
{sprintf(FILENAME,"isp_ivac.txt");
ofstream out(FILENAME, ios::out);
out<< ivac <<endl;
}
}
getchar();
}
I'm having trouble both with the calling of the differents file (they are a series of file, the first one is 0_100.out the second is 1_99.out and so on until 100_0.out) and the finding and saving of the values.
I deeply appreciate any help
Thanks
Do you need to write a program to do this? If it's for an educational project, then fine.

The processing of the files is identical, so you may want to move that common code to a function that adds the matching lines to a container of lines.

If it's not for a project, you'd be better of using existing tools. Unix has lots of stuff for goinf this sort of processing.
well it's for my thesis, from next week i'll be dealing with thousands of those .out file(which by the way are read as if they were txt files), and since i started the first part (creating the file to give in input to a third program) in c++ i thought i'd do the collecting with c++, thuogh i don't really mind how to do it, so if you were to suggest anything else it's fine by me
You can use grep to filter the lines you're interested and append those lines to a results file.

e.g. grep "^Isp," *.txt >> out/results.txt for Isp entries.

If you're using Windows, you may want to use Cygwin to do all this.
hi, pardon me if I haven't replied earlier, i was busy with a couple of finals, the problem is I have no idea hot to program in unix/Cygwin. So if the command you suggest me is c++ my compiler (dev-c++) doesn't recognize it, otherwise i don't know ho to write the rest of the program. Anyway as of now I'm stuck with the searching part. I changed the program in the following:
using namespace std;

int main()
{ string isp,ivac;
char filename[10],FILENAME[10];
for (int i=0;i<=100;i++)
{
sprintf(filename, "%d_%d.out",i,100-i);
ifstream fin(filename,ios::in);
if(fin.is_open()){
cout<<"";
}
else{
cerr<<"error opening file";
return -1;
}
string what="";
while(! fin.eof())
{ getline (fin,what);
if (what.find("Isp,") || what.find("Ivac,"))
{ofstream out("isp_ivac.txt", ios::app);
out<<what<<endl;
out.close();
}
}

}
return 0;
}
the problem is that insetad of writing me only the line with the isp or ivac valuem it writes me the entire file. (It would be a plus if the program were able to copy only the integer part of the string Ivac, M/SEC 3213 2134)
thanks again
It would help if you used code tags to format the code in your post. I've reposted it below with tags.

Anyway, I don't think the code does anything.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>

using namespace std;

int main()
{
        string isp,ivac;
        char filename[10],FILENAME[10];
        for (int i=0;i<=100;i++)
        {
                sprintf(filename, "%d_%d.out",i,100-i);
                ifstream fin(filename,ios::in);
                if(fin.is_open())
                {
                        cout<<"";
                }
                else
                {
                        cerr<<"error opening file";
                        return -1;
                }

                string what="";
                while(! fin.eof())
                {
                        getline (fin,what);
                        if (what.find("Isp,") || what.find("Ivac,"))
                        {
                                ofstream out("isp_ivac.txt", ios::app);
                                out<<what<<endl;
                                out.close();
                        }
                }
        }

        return 0;
}


You algorithm should be something like:
- read next line
- if end-of-line reached, terminate
- if line doesn't begin with Isp or Ivac repeat from the beginning
- write line out
- repeat from beginning

I hope that helps.

BTW, learning a few Unix commands for text processing is time well spent.
sorry i just read it i had to post it between tags. By the way, the code works, the problem is that it prints me the whole file i receive in input, one after the oter. What i don't know how to write is the condition if line doesn't begin with Isp or Ivac go on/repeat/go to the next line.
To be more precise
1
2
3
4
5
6
7
8
9
10
while(! fin.eof())
                {
                        getline (fin,what);
                        if (what.find("Isp,") || what.find("Ivac,"))
                        {
                                ofstream out("isp_ivac.txt", ios::app);
                                out<<what<<endl;
                                out.close();
                        }
                }

this should do the third condition kbw posted, I know that what.find isn't supposed to do that, i just don't know how to work it out
Last edited on
Mmh ok i kinda worked it out but still i don't know how to simply get the numbers instead of the entire line, altought it's not "beautiful" but works
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
            if (what[0]==' ')
              {if (what[1]=='I')
               {if (what[2]=='s')
                 {if (what[3]=='p')
                  {ofstream out("isp_ivac.txt", ios::app);
                   cerr<<what<<endl;
                   out<<what<<endl;
                  }
                 }
               }   
              }
              if (what[0]==' ')
              {if (what[1]=='I')
               {if (what[2]=='v')
                 {if (what[3]=='a')
                  {ofstream out("isp_ivac.txt", ios::app);
                   cerr<<what<<endl;
                   out<<what<<endl;
                  }
                 }
               }   
              }

now i'm wondering how do i get rid of the part written before the numbers, i.e.
Ivac, M/SEC 3213 2134
Isp, M/SEC 551.6 1406.4
how do i get rid of Ivac, M/SEC?
Last edited on
I've looked at your stuff again, and I was wrong, it wasn't far off.

Anyway, I've tweaked it a bit and this ought to do.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include <cstring>

int main()
{
	std::ofstream os("isp_ivac.txt");

	for (int i = 0; i <= 100; i++)
	{
		char filename[10];
		sprintf(filename, "%d_%d.out", i, 100-i);
		std::ifstream is(filename);
		if (!is)
		{
			std::cerr << "Cannot open: " << filename << std::endl;
			continue;
		}

		while (is)
		{
			std::string line;
			getline(is, line);

                        if (strncmp(line.c_str(), "Isp,", 4) == 0)
                                os << line << std::endl;
                        if (strncmp(line.c_str(), "Ivac,", 5) == 0)
                                os << line << std::endl;
                }
        }

        return 0;
}
thanks a lot, your script is undoubtedly better than mine. I have a couple of question, how come you use this writing
std:: before defining a variable or before endl?
P.s. I solved my other problem by using substr(since i already know the length of the part i have to skip), like this:
1
2
3
4
if (strncmp(line.c_str(), " Isp,", 4) == 0)
                               {line2=line.substr(14,30); os << line2 << std::endl;}
                        if (strncmp(line.c_str(), " Ivac,", 5) == 0)
                               {line2=line.substr(14,30); os << line2 << std::endl;}

Thanks a lot for your help, i can finally start working om my thesis
I prefer to use namespace names rather than relying on using namespace. In a large application that uses many libraries, it can become confusing about which namespace things are coming from.

I cheated and used strncmp rather than string.substr. Again, personal preference.
Last edited on
well doesn't matter, i just needed something which would be able to put all the data in a txt file in order to be able to load it with matlab, btw i tried to use strncmp but it gave me problem (well i didn't know I had to use string.c_str())) anyway once again thanks a lot
Topic archived. No new replies allowed.