skiping duplicate entries in a program

I am trying to write a program that alphabetizes names in a file. The program is supposed to skip any blank lines as well as any duplicate names. I can make it skip empty lines but not duplicates. I am trying to use a two Boolean search loop but for some reason its not really working. If anyone could help that would be great. Thanks.

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

#include <cctype>

//case converision lowercase
class toLower {public: char operator()(char c) const {return tolower(c);}};

int main()
{
  // Open file
  ifstream fin;
  string fileName;
  cout << "What file would you like to use for input? ";
  getline(cin, fileName);
  fin.open(fileName.c_str());
  if (!fin.good()) throw "I/O error";

  const int MAX_NAMES = 10;
  int nNames = 0;
  string name[MAX_NAMES];
  
  int i = 0;
  int k = 0;

  // save each line to list array
  while(i < 10)
  {
    if (!fin.good()) break;
    string aName;
    getline(fin, aName);
    
      
    // skip any blank lines and duplicate entries
    if (aName.length() > 0 ) 
    {

      string temp2 = aName;
      transform(temp2.begin(), temp2.end(), temp2.begin(), toLower());
 
      bool duplicate = false;
      for (i = 0; i < nNames; i++)
      {
        
        if (temp2 == name[i])
        {
          duplicate = true;
          break;               
        }  
     
      }
      if (nNames < MAX_NAMES)
        name[nNames++] = aName;
    }
    
    

  }

  for (i = 0; i < nNames; i++)
  {
    string temp2 = name[i];

    
    int j;
    for (j = i + 1; j < nNames; j++)
    {
      if (name[i] == name[j])
      {
        name[--nNames];
      }
    } 
  }

  // sort alphabateically
  for (i = 0; i < nNames; i++)
  {
    int j;
    for (j = i + 1; j < nNames; j++)
    {
      if (name[i] > name[j])
      {
        string temp = name[i];
        name[i] = name[j]; 
        name[j] = temp;
      }
    }
  }
 



  // Print to screen
  for(i = 0; i < nNames; i++)
  {
    cout << name[i] << endl;
  }
   
  fin.close();

  return 0;
}
  
Where's the declaration for name ? Did u mean aName
The declaration for name is on line 24 and aName is on line 33.
only thing i changed was i added a FileExists function to check to see if the file you are trying to open exists before you actually go to open it, this way the program will not freeze up if you type a filename that doesnt exist.
and i believe the problem lies in your loops, personally they are confusing to me. please explain their purpose individually a little more and i might be of more help.

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
125
126
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h> // needed for FileExists function
#include <cctype>

using namespace std;

bool FileExists(string strFilename)
{
    struct stat stFileInfo;
    bool fileisreal;
    int nStat;
    // Attempt to get the file attributes
    nStat = stat(strFilename.c_str(),&stFileInfo);
    if(nStat == 0) fileisreal = true;
    else fileisreal = false;
    return fileisreal;
}

//case converision lowercase
class toLower {public: char operator()(char c) const {return tolower(c);}};

int main()
{
  // Open file
  ifstream fin;
  cout << "What file would you like to use for input? ";
  string fileName;
  start:
      getline(cin, fileName);
      bool fileisreal=FileExists(fileName);
      if (fileisreal==true)
      {
          fin.open(fileName.c_str());
      }
  else goto start;
  if (!fin.good()) throw "I/O error";

  const int MAX_NAMES = 10;
  int nNames = 0;
  string name[MAX_NAMES];

  int i = 0;
  int k = 0;

  // save each line to list array
  while(i < 10)
  {
    if (!fin.good()) break;
    string aName;
    getline(fin, aName);


    // skip any blank lines and duplicate entries
    if (aName.length() > 0 )
    {

      string temp2 = aName;
      transform(temp2.begin(), temp2.end(), temp2.begin(), toLower());

      bool duplicate = false;
      for (i = 0; i < nNames; i++)
      {

        if (temp2 == name[i])
        {
          duplicate = true;  // duplicate isnt used anywhere but here..? shouldn't you be testing this somewhere else?
          break;             // i tried the program without the break; and still got same results.
        }

      }
      if (nNames < MAX_NAMES)
        name[nNames++] = aName;
    }



  }

  for (i = 0; i < nNames; i++)
  {
    string temp2 = name[i];


    int j;
    for (j = i + 1; j < nNames; j++)
    {
      if (name[i] == name[j])
      {
        name[--nNames];
      }
    }
  }

  // sort alphabateically
  for (i = 0; i < nNames; i++)
  {
    int j;
    for (j = i + 1; j < nNames; j++)
    {
      if (name[i] > name[j])
      {
        string temp = name[i];
        name[i] = name[j];
        name[j] = temp;
      }
    }
  }




  // Print to screen
  for(i = 0; i < nNames; i++)
  {
    cout << name[i] << endl;
  }

  fin.close();

  return 0;
}

Sure. i found a mistake in the program (in the original posting) lines 63-76 was not supposed to be their (i was experimenting). I also think the problem lies in the loop as well. I wrote some things in the code. Thanks for you help.

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

#include <cctype>

//case converision lowercase
class toLower {public: char operator()(char c) const {return tolower(c);}};

int main()
{
  // Open file
  ifstream fin;
  string fileName;
  cout << "What file would you like to use for input? ";
  getline(cin, fileName);
  fin.open(fileName.c_str());
  if (!fin.good()) throw "I/O error";

  const int MAX_NAMES = 10;
  int nNames = 0;
  string name[MAX_NAMES];
  
  int i = 0;
  int k = 0;

  // save each line to list array
  while(i < 10) // did only 10 loops for up to 10 names
  {
    if (!fin.good()) break;
    string aName;
    getline(fin, aName);  // gets a new value every loop 
    
    
    if (aName.length() > 0 ) // Skip any blank lines in the file
    {
      
      // Over here i am taking a temporary value of aName so i can compare lower case values in case
      //  some of the names in the file are uppercase 
      string temp2 = aName;    
      transform(temp2.begin(), temp2.end(), temp2.begin(), toLower());
 
   // here is where the problem lies (i think). what i am trying to do is search through previous values
      // so I did a for loop so it can search through pervious values stored into name[i]  and if it
      // matches it will break the loop and hopefully not store the duplicate value into name[i]
      // im not sure why bool is used in here... but they used bool in the book i am using  
     // also I am not sure if i am comparing the lowercase values correctly.
     // So when I run the program what it is supposed to do in theory its not doing. The problem I
     //   think is that it's not  comparing the values correctly. When i run the program it sorts 
     //  everything in alphabetical order and skips over blank lines  but continues to leave duplicates.  
     
      bool duplicate = false;
      for (i = 0; i < nNames; i++)
      {
        
        if (temp2 == name[i])  
        {
          duplicate = true;
          break;               
        }  
     
      }
      if (nNames < MAX_NAMES)       
        name[nNames++] = aName;   // this if statement checks if nNames has reached MAX_NAMES 
                                // and if it hasn't it stores the value aName into it and adds 1 to 
                               // nNames. 
    }
    i++;    

  }

  // sort alphabateically
  for (i = 0; i < nNames; i++)
  {
    int j;
    for (j = i + 1; j < nNames; j++)
    {
      if (name[i] > name[j])                // checks to see if the value for name[i] is greater than the 
      {                                     // value for name[j] and if it is it rearanges it so it isn't.
        string temp = name[i];
        name[i] = name[j]; 
        name[j] = temp;
      }
    }
  }

  // Just goes through the array and Prints to screen their values.
  for(i = 0; i < nNames; i++)
  {
    cout << name[i] << endl;
  }
  fin.close();

  return 0;
}



Last edited on
yay, i think i fixed it. the break; for the loop to check for duplicates wasnt placed in the correct place. this still may have bugs, but it seems to 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
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

#include <cctype>

//case converision lowercase
class toLower {public: char operator()(char c) const {return tolower(c);}};

int main()
{
  // Open file
  ifstream fin;
  string fileName;
  cout << "What file would you like to use for input? ";
  getline(cin, fileName);
  fin.open(fileName.c_str());
  if (!fin.good()) throw "I/O error";

  const int MAX_NAMES = 10;
  int nNames = 0;
  string name[MAX_NAMES];

  int i = 0;
  int k = 0;

  // save each line to list array
  while(i < 10) // did only 10 loops for up to 10 names
  {
    if (!fin.good()) break;
    string aName;
    getline(fin, aName);  // gets a new value every loop


    if (aName.length() > 0 ) // Skip any blank lines in the file
    {

      // Over here i am taking a temporary value of aName so i can compare lower case values in case
      //  some of the names in the file are uppercase
      string temp2 = aName;
      transform(temp2.begin(), temp2.end(), temp2.begin(), toLower());

   // here is where the problem lies (i think). what i am trying to do is search through previous values
      // so I did a for loop so it can search through pervious values stored into name[i]  and if it
      // matches it will break the loop and hopefully not store the duplicate value into name[i]
      // im not sure why bool is used in here... but they used bool in the book i am using
     // also I am not sure if i am comparing the lowercase values correctly.
     // So when I run the program what it is supposed to do in theory its not doing. The problem I
     //   think is that it's not  comparing the values correctly. When i run the program it sorts
     //  everything in alphabetical order and skips over blank lines  but continues to leave duplicates.

      bool duplicate = false;
      for (i = 0; i < nNames; i++)
      {

        if (temp2 == name[i])
        {
          duplicate = true;
        }
      }
      if (duplicate==true) break;      /* this is what i changed -- metl wolf */
      if (nNames < MAX_NAMES)
      name[nNames++] = aName;   // this if statement checks if nNames has reached MAX_NAMES
                                // and if it hasn't it stores the value aName into it and adds 1 to
                               // nNames.
    }
    i++;

  }

  // sort alphabateically
  for (i = 0; i < nNames; i++)
  {
    int j;
    for (j = i + 1; j < nNames; j++)
    {
      if (name[i] > name[j])                // checks to see if the value for name[i] is greater than the
      {                                     // value for name[j] and if it is it rearanges it so it isn't.
        string temp = name[i];
        name[i] = name[j];
        name[j] = temp;
      }
    }
  }

  // Just goes through the array and Prints to screen their values.
  for(i = 0; i < nNames; i++)
  {
    cout << name[i] << endl;
  }
  fin.close();

  return 0;
}
Last edited on
Wow great.. it works thanks for your help!! There are some problems though it is not correctly leaving out different cases such as Z and z and also if you have a same name in a row ( such as x and then x in the next line) it will just break the entire loop and fail to get other names in the file.
Last edited on
Topic archived. No new replies allowed.