search for a number from one txt file in another .txt file

Hi

I have a .txt file contains two cols .

number and state e.g :

number state

372 close
408 close
509 close

and I have another file contains numbers and correspoing values e.g:

number value
1 0.345
2 0.234
3 0.236
. .
. .
15832

I want to serach for the numbers from the first file in the second file . for example search for (372,408 and so on ) in the second file , and if found take
13 values from the found number (+6 , -6) assign them to 1 e.g

372 0.345 1
373 0.234 1
374 0.453 1
375 0.323 1
376 0.231 1
377 0.232 1
378 0.314 1
381 0.345 1
382 0.123 1
383 0.543 1
384 0.345 1

any idea how can I do this ?
Last edited on
Here's some psuedo-code you get you started:

1. read the first file (the number/state one) line by line, save the numbers in std::vector<double> with push_back as they're read in; you don't mention any further uses for state so that can be read into a dummy variable and discarded

2. read the second file (the number/value one) line by line, save the numbers in std::vector<std::pair<double,double>>, each element corresponding to a (number, value) pair

3. set up a struct:
1
2
3
4
5
6
7
8
9
struct result
{
	double _file1_num;
	double _file2_val;
	double _file2_num;
	result(const double& file1_num, const double& file2_val, const double& file2_num)
	: _file1_num(file1_num), _file2_val(file2_val), _file2_num(file2_num){}
}
//also overload the << operator if required; 


4. for each number in vector<double> (from 1), search vector<pair<double, double>> (from 2) by first element of pair. If found, run the ctor for struct result 13 times through a loop, push_back each resultant struct result object into a pre-declared std::vector<result>
Thanks , now I'm trying to read the number/state file into std::vector<double> , but it is only read the first number in file , state is not important at this stage as I get the numbers associated with them

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
#include <iostream>
   #include <fstream>
   #include <string>
   #include <vector>
     using namespace std;

    int main () 

{


     double  numbers;
     std::vector<double> frames;
      ifstream myfile1 ("output.txt");

    if(!myfile1.is_open())
{


    std::cerr << "Error opening file";
     exit(EXIT_FAILURE);

}
   
       while ( myfile1>>numbers)
       {
  
        frames.push_back(numbers);
       }

 cout << "Read " << frames.size()<< " names successfully\n";


return 0;

}
you don't mention any further uses for state so that can be read into a dummy variable and discarded

the state variable is not read and discarded and so the file read fails after the first number. Try something on the lines of:
1
2
3
4
5
6
7
8
std::string dummy;
while ( myfile1>>numbers>>dummy)
{
  	if(myfile1)//checks file is still good, usually avoids last number being read twice
	{
        	frames.push_back(numbers);
	}
}
Hi.


I have done ;

1. . read the first file (the number/state one) line by line, save the numbers in std::vector<double>

2. read the second file (the number/value one) line by line, save the numbers in std::vector<std::pair<double,double>> as shown below .


I need help with the last part (4) . How can i search for number in vector<double> (from 1), search vector<pair<double, double>> (from 2) by first element of pair. If found, run the ctor for struct result 13 times through a loop ?


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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    #include <iostream>
   #include <fstream>
   #include <string>
   #include <vector>
     using namespace std;

    int main () 

{


     double  numbers,value,frame_number;
     std::vector<double> frames;
      std::vector<std::pair<double,double> >Frame_value;

     ifstream myfile1 ("number_state.txt");
     ifstream myfile2("number_value.txt");


//read number state file and save numbers into frames vector
    if(!myfile1.is_open())
{


    std::cerr << "Error opening file";
     exit(EXIT_FAILURE);

}

    std::string dummy;
     while ( myfile1>>numbers>>dummy)
{
  	if(myfile1)//checks file is still good, usually avoids last number being read twice
	{
        	frames.push_back(numbers);
	}
}

myfile1.close();

// printout frames vector
  for(int i=0;i<frames.size();i++)


{
      cout << "Read " << frames[i]<<endl;

}

// open second file and read frame , number , value into >Frame_value; vector 
    if(!myfile2.is_open())
{

    std::cerr << "Error opening file";
     exit(EXIT_FAILURE);
}

  while ( myfile2>>EAR_Frames>>EAR)
{
  	if(myfile2)//checks file is still good, usually avoids last number being read twice
	{
        	Frame_value.push_back(std::make_pair(frame_number,value));
	}
}

myfile2.close();
  for(int i=0;i<Frame_value.size();i++)


{
      cout << "Read " <<Frame_value[i].first<<"    "<<Frame_value[i].second<<endl;

}






system("PAUSE");

return 0;

}

Last edited on
line 58: file is being read into variables EAR_Frames, EAR but on line 62 you're making pair with (frame_number, value). Maybe you changed the name of the variables at some point, but double-check this
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
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>

constexpr auto RANGE = 6;

struct Result
{
	double _number;
	double _value;
	double _frame_number;
	Result(const double& number, const double& value, const double& frame_number)
	: _number(number), _value(value), _frame_number(frame_number){}
};
int main()
{
    std::vector<double> frames;
    std::vector<std::pair<double, double>> Frame_value;
    std::vector<Result> results;

    std::vector<double>::const_iterator itr_double = frames.begin();
    std::vector<std::pair<double, double>>::iterator itr_pair = Frame_value.begin();
    do
    {
        if((*(itr_double)) == ((*(itr_pair)).first))
        {
            for (auto j = -1* RANGE; j <= RANGE; j++)
            {
                Result temp((*(itr_double))+j, ((*(itr_pair)).second), (*(itr_pair)).first);
                results.push_back(std::move(temp));
            }
        }
            itr_double++;
            itr_pair++;
    } while (itr_double != frames.end() && itr_pair != Frame_value.end());
}
Last edited on
sorry , my mistake about the variable names .


is the code , if found a match between the numbers in frames vector and numbers

frame_value vector , take +6,-6 values from frame_value vector and giving them value of (1) in a separate field ?

the code I write saves both files into vectors , but whenn I put it with the structure it doesn't work

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <tuple>
#include <algorithm>

constexpr auto RANGE = 6;

struct Result
{
	double _number;
	double _value;
	double _frame_number;
	Result(const double& number, const double& value, const double& frame_number)
	: _number(number), _value(value), _frame_number(frame_number){}
};





using namespace std;

    int main () 

{

    std::vector<double> frames;
    std::vector<std::pair<double, double> >Frame_value;
 
  //  std::vector<Result> results;

   
    double  numbers,value,frame_number;

     ifstream myfile1 ("annotations.txt");
     ifstream myfile2("EAR.txt");


    if(!myfile1.is_open())
{


    std::cerr << "Error opening file";
     exit(EXIT_FAILURE);

}

    std::string dummy;
     while ( myfile1>>numbers>>dummy)
{
  	if(myfile1)//checks file is still good, usually avoids last number being read twice
	{
        	frames.push_back(numbers);
	}
}


  for(int i=0;i<frames.size();i++)


{
      cout << "Read " << frames[i]<<endl;

}




    if(!myfile2.is_open())
{

    std::cerr << "Error opening file";
     exit(EXIT_FAILURE);
}

  while ( myfile2>>frame_number>>value)
{
  	if(myfile2)//checks file is still good, usually avoids last number being read twice
	{
        	Frame_value.push_back(std::make_pair(frame_number,value));
	}
}


  for(int i=0;i<Frame_value.size();i++)


{
      cout << "Read " << Frame_value[i].first<<"    "<<Frame_value[i].second<<endl;

}

 std::vector<double> frames;
    std::vector<std::pair<double, double>> Frame_value;
    std::vector<Result> results;

    std::vector<double>::const_iterator itr_double = frames.begin();
    std::vector<std::pair<double, double>>::iterator itr_pair = Frame_value.begin();
    do
    {
        if((*(itr_double)) == ((*(itr_pair)).first))
        {
            for (auto j = -1* RANGE; j <= RANGE; j++)
            {
                Result temp((*(itr_double))+j, ((*(itr_pair)).second), (*(itr_pair)).first);
                results.push_back(std::move(temp));
            }
        }
            itr_double++;
            itr_pair++;
    } while (itr_double != frames.end() && itr_pair != Frame_value.end());



system("PAUSE");

return 0;

}


Last edited on
it doesn't work

very cryptic, can you give some more details ... what doesn't work, in what way does it not work etc? Also, can you post myfile1, myfile2 somewhere?
Here are the files :

myfile1 :

https://drive.google.com/file/d/0B03WnxRSaChVc3lDNVJwMjRreHM/view?usp=sharing


myfile2 :

https://drive.google.com/file/d/0B03WnxRSaChVaFM0RHJ4TG1TUnM/view?usp=sharing


when I compile the code above , these error shows :

is there are any error is the code structure ?




U:\test.cpp:5:17: tuple: No such file or directory
U:\test.cpp:8: error: expected constructor, destructor, or type conversion before "auto"
U:\test.cpp:8: error: expected `,' or `;' before "auto"

U:\test.cpp: In function `int main()':
U:\test.cpp:95: error: redeclaration of `std::vector<double, std::allocator<double> > frames'
U:\test.cpp:29: error: `std::vector<double, std::allocator<double> > frames' previously declared here
U:\test.cpp:96: error: `>>' should be `> >' within a nested template argument list
U:\test.cpp:96: error: redeclaration of `std::vector<std::pair<double, double>, std::allocator<std::pair<double, double> > > Frame_value'
U:\test.cpp:30: error: `std::vector<std::pair<double, double>, std::allocator<std::pair<double, double> > > Frame_value' previously declared here

U:\test.cpp:100: error: `>>' should be `> >' within a nested template argument list

U:\test.cpp:105: error: ISO C++ forbids declaration of `j' with no type
U:\test.cpp:105: error: `RANGE' undeclared (first use this function)
U:\test.cpp:105: error: (Each undeclared identifier is reported only once for each function it appears in.)
U:\test.cpp:108: error: `move' is not a member of `std'

Execution terminated
Last edited on
1
2
U:\test.cpp:5:17: tuple: No such file or directory
U:\test.cpp:96: error: `>>' should be `> >' within a nested template argument list

These suggest your compiler is not C++11 compliant. So the first thing you need to do is upgrade your compiler to one that is C++11 compliant if you want to use the program below. Code::Blocks IDE comes with a C++11 (even C++14) compliant compiler and would be a good choice. Once you've got it installed go to Settings -> Compiler -> Compiler Flags and tick the " ... follow the C++11 ..." option
The other error messages like 'redeclaration of variables' are obvious. Finally, you need to #include <algorithm> for std::move()
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <tuple>
#include <algorithm>

constexpr auto RANGE = 6;

struct Result
{
	double m_number;
	double m_value;
	double m_frame_number;
	Result(const double& number, const double& value, const double& frame_number)
	: m_number(number), m_value(value), m_frame_number(frame_number){}
};
std::ostream& operator << (std::ostream& os, const Result& r)
{
    os << r.m_number << " " << r.m_value << " " << r.m_frame_number << '\n';
    return os;
}
int main ()
{

    std::vector<double> frames;
    std::vector<std::pair<double, double> >Frame_value;
    std::ifstream myfile1 ("D:\\input.txt");
    std::ifstream myfile2("D:\\test.txt");

    if(myfile1)
    {
        double numbers{};
        std::string dummy{};
        while ( myfile1>>numbers>>dummy)
        {
            if(myfile1)
            {
                frames.push_back(numbers);
            }
        }
    }
    else
    {
        std::cerr << "Error opening file";
    }

    if(myfile2)
    {
        double  value{},frame_number{};
        while ( myfile2>>frame_number>>value)
        {
            if(myfile2)
            {
                Frame_value.push_back(std::make_pair(frame_number,value));
            }
        }
    }
    else
    {
        std::cerr << "Error opening file";
    }
    std::vector<Result> results;

    for (auto itr_double = frames.begin(); itr_double != frames.end(); ++itr_double)
    {
        for (auto itr_pair = Frame_value.begin(); itr_pair != Frame_value.end(); ++itr_pair)
        {
            if((*(itr_double)) == ((*(itr_pair)).first))
            {
                for (auto j = -1* RANGE; j <= RANGE; j++)
                {
                    Result temp((*(itr_double))+j, ((*(itr_pair)).second), (*(itr_pair)).first);
                    results.push_back(std::move(temp));
                }
            }
        }
    }
    for (auto& elem : results)
    {
        std::cout << elem;
    }
}

Output
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
374 0.74397 380
375 0.74397 380
376 0.74397 380
377 0.74397 380
378 0.74397 380
379 0.74397 380
380 0.74397 380
381 0.74397 380
382 0.74397 380
383 0.74397 380
384 0.74397 380
385 0.74397 380
386 0.74397 380
375 0.754458 381
376 0.754458 381
377 0.754458 381
378 0.754458 381
379 0.754458 381
380 0.754458 381
381 0.754458 381
382 0.754458 381
383 0.754458 381
384 0.754458 381
385 0.754458 381
386 0.754458 381
387 0.754458 381
468 0.729842 474
469 0.729842 474
470 0.729842 474
471 0.729842 474
472 0.729842 474
473 0.729842 474
474 0.729842 474
475 0.729842 474
476 0.729842 474
477 0.729842 474
478 0.729842 474
479 0.729842 474
480 0.729842 474
469 0.74033 475
470 0.74033 475
471 0.74033 475
472 0.74033 475
473 0.74033 475
474 0.74033 475
475 0.74033 475
476 0.74033 475
477 0.74033 475
478 0.74033 475
479 0.74033 475
480 0.74033 475
481 0.74033 475
470 0.750818 476
471 0.750818 476
472 0.750818 476
473 0.750818 476
474 0.750818 476
475 0.750818 476
476 0.750818 476
477 0.750818 476
478 0.750818 476
479 0.750818 476
480 0.750818 476
481 0.750818 476
482 0.750818 476
765 0.844778 771
766 0.844778 771
767 0.844778 771
768 0.844778 771
769 0.844778 771
770 0.844778 771
771 0.844778 771
772 0.844778 771
773 0.844778 771
774 0.844778 771
775 0.844778 771
776 0.844778 771
777 0.844778 771
766 0.855266 772
767 0.855266 772
768 0.855266 772
769 0.855266 772
770 0.855266 772
771 0.855266 772
772 0.855266 772
773 0.855266 772
774 0.855266 772
775 0.855266 772
776 0.855266 772
777 0.855266 772
778 0.855266 772

Process returned 0 (0x0)   execution time : 0.188 s
Press any key to continue.

closed account (48T7M4Gy)
<map>'s are an ideal way to make the join on the 'number' being the key and might be useful here. Use <multimap>'s for multiple values against the key. this quick program makes the join. To get the 13 values requires manipulation of the iterator(s) but isn't difficult.

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 <string>
#include <map>

int main ()
{
    int number = 0;
    double value = 0;
    std::string state;
    
    std::map<int, std::string> map_f1;
    std::map<int, double> map_f2;
    std::map<int,double>::iterator it2;
    
    std::ifstream file1 ("mapping_file1.txt");
    std::ifstream file2 ("mapping_file2.txt");
    
    if ( file1.is_open() and file2.is_open() )
    {
        while ( file1 >> number >> state )
            map_f1[number] = state;
        file1.close();
        
        while ( file2 >> number >> value )
            map_f2[number] = value;
        file2.close();
        
        for(auto it1 = map_f1.begin(); it1 != map_f1.end(); it1++)
        {
            it2 = map_f2.find( it1 -> first);
            if (it2 != map_f2.end())
                std::cout << it1 -> first << ' ' << it1 -> second << ' ' << it2 -> first << ' ' << it2 -> second << '\n';
        }
    }
    else
        std::cout << "Unable to open file1 and/or file2\n";
    
    return 0;
}
Last edited on
Thanks very much @ kemort and gunnerfunner for helping me .

but I have one notice ,if the number found in the second file (test.txt ) it should take

asociated values for each number , not all of them the same value as the value of the

found match number :


for example : if 380 is found in the second file the values should be as below , where the values are corresponding to each numer in test.txt:

374 0.681042
375 0.69153
376 0.702018
377 0.712506
378 0.722994
379 0.733482
380 0.74397
381 0.754458
382 0.764946
383 0.775434
384 0.785922
385 0.79641
386 0.806898


secondly , why the search for match is stops after number 772 , what about othe numbers ?
closed account (48T7M4Gy)
if 380 is found in the second file the values should be as below

The reason why it's not showing the results you want is because you have to program it. For instance if the two key values match on 380 then you will have to write the extra few lines to find (if they exist) the values in the second file for key values it2 = 380-1, 380 -2, ... 380-6 and 380+1, 308+2, ... 380+6 It won't happen unless you program it.

why the search for match is stops after number 772

The reason for this is there is no entry in sample file 2 with a key value of 772


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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <fstream>
#include <string>
#include <map>

int main ()
{
    int number = 0;
    double value = 0;
    std::string state;
    int key = 0;
    
    std::map<int, std::string> map_f1;
    std::map<int, double> map_f2;
    std::map<int,double>::iterator it2, it3;
    
    std::ifstream file1 ("mapping_file1.txt");
    std::ifstream file2 ("mapping_file2.txt");
    
    if ( file1.is_open() and file2.is_open() )
    {
        while ( file1 >> number >> state )
            map_f1[number] = state;
        file1.close();
        
        while ( file2 >> number >> value )
            map_f2[number] = value;
        file2.close();
        
        for(auto it1 = map_f1.begin(); it1 != map_f1.end(); it1++)
        {
            it2 = map_f2.find( it1 -> first);
            if (it2 != map_f2.end())
            {
                // Display linked item
                std::cout << it1 -> first << ' ' << it1 -> second << ' ' << it2 -> first << ' ' << it2 -> second << '\n';
            
                // Display previous 6 and following 6
                key = it2 -> first;
                for( int i = key - 6; i < key + 6; i++)
                {
                    it3 = map_f2.find(i);
                    if (it3 != map_f2.end())
                    {
                        std::cout << '\t' << it3 -> first << ' ' << it3 -> second << '\n';
                    }
                }
            }
        }
    }
    else
        std::cout << "Unable to open file1 and/or file2\n";
    
    return 0;
}
380 close 380 0.74397
	374 0.681042
	375 0.69153
	376 0.702018
	377 0.712506
	378 0.722994
	379 0.733482
	380 0.74397
	381 0.754458
	382 0.764946
	383 0.775434
	384 0.785922
	385 0.79641
381 close 381 0.754458
	375 0.69153
	376 0.702018
	377 0.712506
	378 0.722994
	379 0.733482
	380 0.74397
	381 0.754458
	382 0.764946
	383 0.775434
	384 0.785922
	385 0.79641
	386 0.806898
474 close 474 0.729842
	468 0.666914
	469 0.677402
	470 0.68789
	471 0.698378
	472 0.708866
	473 0.719354
	474 0.729842
	475 0.74033
	476 0.750818
	477 0.761306
	478 0.771794
	479 0.782282
475 close 475 0.74033
	469 0.677402
	470 0.68789
	471 0.698378
	472 0.708866
	473 0.719354
	474 0.729842
	475 0.74033
	476 0.750818
	477 0.761306
	478 0.771794
	479 0.782282
	480 0.79277
476 close 476 0.750818
	470 0.68789
	471 0.698378
	472 0.708866
	473 0.719354
	474 0.729842
	475 0.74033
	476 0.750818
	477 0.761306
	478 0.771794
	479 0.782282
	480 0.79277
	481 0.803258
771 close 771 0.844778
	765 0.78185
	766 0.792338
	767 0.802826
	768 0.813314
	769 0.823802
	770 0.83429
	771 0.844778
	772 0.855266
	773 0.865754
	774 0.876242
	775 0.88673
	776 0.897218
772 close 772 0.855266
	766 0.792338
	767 0.802826
	768 0.813314
	769 0.823802
	770 0.83429
	771 0.844778
	772 0.855266
	773 0.865754
	774 0.876242
	775 0.88673
	776 0.897218
	777 0.907706
Program ended with exit code: 0
Last edited on
I tried to display the numbers in the second file with their (13) values , that doesn't have match in the first file , but I didn't displayed them .


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

 for(auto it1 = map_f1.begin(); it1 != map_f1.end(); it1++)
        {
            it2 = map_f2.find( it1 -> first);
            if (it2 != map_f2.end())
            {
                // Display linked item
                std::cout << it1 -> first << ' ' << it1 -> second << ' ' << it2 -> first << ' ' << it2 -> second << '\n';

                // Display previous 6 and following 6
                key = it2 -> first;
                for( int i = key - 6; i < key + 7; i++)
                {
                    it3 = map_f2.find(i);
                    if (it3 != map_f2.end())
                    {
                        std::cout << '\t' << it3 -> first <<  " " << it3 -> second << "  " <<std::endl;


                    }


                    else
                    {
                        std::cout << '\t' << it3 -> first <<  " " << it3 -> second << "   " <<std::endl;
                    }
                }
            }
        }
Last edited on
closed account (48T7M4Gy)
@tofi

By the look of it both gunfunner and I have shown you a way to solve the problem as you have described it. One is using <vector>'s and one uses <map>'s and except for indexing differences the answers are the same.

Why don't you show us what your latest program is including the input and the output and what you expected but didn't get. maybe then a definitive answer can be given because on face value it appears to be just a cut and paste exercise you are confronting. If it's as simple as that then just cut and paste the lot - trouble is there is no learning involved but that's up to you.

If your requirement is different than your original description then you will have to clarify it. :)
@kemort

Thanks for helping me .

The example you provided works as I described it . I just now need to output the numbers that is doesn't

have match from mapping_file1.txt to mapping_file2.txt same way (6 before and 6 after ) .

for example the number ( 800 in mapping_file2.txt doesn't have match in mapping_file1.txt )



794,795,796,797,798,799,800,801,802,803,805,805,806

Regards

Last edited on
Topic archived. No new replies allowed.