Temporarily Converting Strings Cases

Hi, my name is Patrick.

I've been stuck on this problem for 3 hours now and if anyone could help or point me in the right direction I would greatly appreciate it.

PROGRAM: This program below is designed to read strings from a txt file, sort them alphabetically, skipping any blank lines, ignore duplicates, and ignore different cases.

ISSUE: I am supposed to not permanently convert the name case, instead compare lowercase (or uppercase) versions of the text for sorting purposes.
How can I compare lowercase or uppercase versions of the text without permanently converting the name case?

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
127
128
129
130
131
132

#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>

using namespace std;

#include <cctype>
// required for conversion to lowercase
class toLower {public: char operator () (char c) const {return tolower(c) ; }};

struct Student
{
  string name;

};



void printStudents(Student* student, int nStudents)
{
  int i;
  for (i = 0; i < nStudents; i++)
  {
   cout << student[i].name << endl;
  }
}


void convertString(Student* student, int nStudents)
{
  int i;
  for (i = 0; i < nStudents; i++)

  transform(student[i].name.begin() , student[i].name.end(), student[i].name.begin(), toLower());
}



int main()
{

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

   const int MAX_STUDENTS = 8;
   int nStudents = 0;
   Student student[MAX_STUDENTS];
   Student aStudent;


   while(fin.good())
  {
 
   getline(fin, aStudent.name);
 

   if (nStudents < MAX_STUDENTS && !aStudent.name.length() == 0)
     {

    student[nStudents++] = aStudent;

       convertString(student, nStudents); // converts to lowercase

       bool b;
       int i;
       
        for (i = 0; i < nStudents; i++)
        {

          for (int j = i; j < nStudents; j++)
           {
             if(j != i)
              {
                if(student[i].name == student[j].name)
                 {
                   b = true;
                  }
               }
                if(b == true) 
                 {
                   Student aStudent = student[--nStudents];

                  }
             }
           b = false;
         }
  
      }

}

    

   


  fin.close();

   for (int i = 0; i < nStudents; i++)
   {

    for (int j = i + 1; j < nStudents; j++)
    {
      

      if (student[i].name > student[j].name)
      {
        
         
         Student temp = student[i];
         student[i] = student[j];
         student[j] = temp;

       }

     }
   }


  printStudents(student, nStudents);




}
Last edited on
Use a temporary variable as the target.

convertString would look like this:
1
2
3
4
void convertString(Student &student_to, const Student &student_from)
{
  transform(student_from.name.begin() , student_from.name.end(), student_to.name.begin(), toLower());
}


Btw: you don't need to convert all elements each time. Just the last one.
You don't need two nested loops. Plus you can do both within the loop after you extracted the name: sort and exclude with a single loop
I am supposed to not permanently convert the name case, instead compare lowercase (or uppercase) versions of the text for sorting purposes.

I'm a bit confused. You compare what with what?

Anyway, if you're not supposed to permanently convert them, then don't.
You only need them to be converted when you sort them, right?
If so, use std::sort() and feed it your custom comparison function/functor.
http://cplusplus.com/reference/algorithm/sort/

Edit: I also advise that you use std::list<Student> or std::vector<Student> instead of a Student[] C array. That way, you no longer need to worry about the size.
Last edited on
Thanks so much for the help.

I ended up fixing it by making copies of the strings and comparing them with each other

Here is the code block that I fixed...

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

        for (i = 0; i < nStudents; i++)
        {

          for (int j = i; j < nStudents; j++)
           {
             if(j != i)
              {
     
                string copy = student[i].name;
                string copy2 = student[j].name;
                transform(copy.begin() , copy.end(), copy.begin(), toLower());
                transform(copy2.begin() , copy2.end(), copy2.begin(), toLower());
                if(copy == copy2)
                   {
                    b = true;
                   }
               
                if(b == true) 
                   {
                    Student aStudent = student[--nStudents];
  
                   }
                if (copy > copy2)
                    {   
                     Student temp = student[i];
                     student[i] = student[j];
                     student[j] = temp;
                    }
                }
              
             }
            b = false;
          }
  
      }

  } 
Topic archived. No new replies allowed.