0

I need a solution for sorting of unix pwd file using C++ based on the last name. The format of the file is username, password, uid, gid, name, homedir, shell. All are seperated by colon delimiters. The name field contains first name follwed by last name both seperated by space I am able to sort the values using map and i am posting my code. Can some one suggest me improvements that I can do to my code please. Also I am unable to see the sorted lines in my file.

string line,item;
fstream myfile("pwd.txt");
vector<string> lines;
map<string,int> lastNames;
map<string,int>::iterator it;

if(myfile.is_open())
 {    
  char delim =':';
  int count =0;
  while(!myfile.eof())
  {
    count++;
    vector<string> tokens;
    getline(myfile,line);
    istringstream iss(line);

    lines.push_back(line);

    while(getline(iss,item,delim))
    {
        tokens.push_back(item);
    }
    cout<<tokens.size()<<endl;;
    size_t i =tokens[4].find(" ");
    string temp = tokens[4].substr(i,(tokens[4].size()-i));
    cout<<temp<<endl;

    lastNames.insert(pair<string,int>(temp,count));
    tokens.clear();

  }

    myfile.seekg(0,ios::beg);

    for(it=lastNames.begin();it!=lastNames.end();it++)
  {
         cout << (*it).first << " => " << (*it).second << endl;
         int value=lastNames[(*it).first ];
         myfile<<lines[value-1]<<endl;
         cout<<lines[value-1]<<endl;
         cout<<value<<endl;
  }

}

Also I am having problem writing to the file I am unable to see the sorted results.

my problem:

    Can someone please explain me why I am unable to see the written results in the file!

Thanks & Regards,

Mousey.

klutt
  • 30,332
  • 17
  • 55
  • 95
mousey
  • 11,601
  • 16
  • 52
  • 59
  • Define "very large". The best way to sort a 40MB file and a 4GB file are very different, even though both are arguably "very large" for a pwd file. – Anon. Jul 01 '10 at 04:16
  • Why do you need to do it in C? The command line `sort` utility can probably solve your problem in no time. – Carl Norum Jul 01 '10 at 04:16
  • assume the file is in order of few megabytes. I would also like to know how to sort it if its order of few giga bytes – mousey Jul 01 '10 at 04:17
  • @Carl Norum yeah I know the sort command but I am just trying it in C or C++ – mousey Jul 01 '10 at 04:18
  • Map doesnt work here because generally in PC most of the last name remains the same. So It doesnt work. Is there any other data structure which sorts ? – mousey Jul 02 '10 at 07:34
  • I edited my previous post and posted my written code. Can some one help me with improvements to the code please. – mousey Jul 07 '10 at 00:16
  • I am unable to rewrite the sorted results to my file. Can some one tell me what the problem is ? – mousey Jul 25 '10 at 05:49

2 Answers2

5

Since the format of the file is fixed

username, password, uid, gid, first name(space)lastname, homedir, shell

Maintain a std::map with key value as string (which will contain last name, and value as line number

Start reading the file line by line, extract the last name (Split the line by "," and then split fifth extracted part on space).

Store the name along with line number in map

When complete file has been read, just output the line numbers as mentioned in map. (Map contains lat names in sorted order)

For splitting a string Refer to

Split a string in C++?

Community
  • 1
  • 1
Pardeep
  • 929
  • 6
  • 14
  • how to sort the strings in a map ? just by changing line number ? Since I dont know the order – mousey Jul 01 '10 at 04:29
  • `std::map`'s are sorted containers. – Louis Marascio Jul 01 '10 at 04:41
  • @mousey, Bye default std::map stores elements in sorted order (on Key elements which in your case are strings). For more details on map ans its usage, refer to : http://www.cplusplus.com/reference/stl/map/ – Pardeep Jul 01 '10 at 04:48
  • @Pradeep Map should have unique names. There can be same last names right ? So now in the map I have list with last name and line number so do I need to go to that line and read it and paste it in the start ? – mousey Jul 01 '10 at 06:02
  • @mousey, You can try multimap which allows duplicate key values and will help you – Pardeep Jul 05 '10 at 09:47
  • @mousey: You could also concatenate the last name and UID and use that as your map key. As long as the UID is unique, that would give you unique keys for your map, and the entries would still be sorted by last name automatically by the `std::map`. – Josh Townzen Jul 07 '10 at 00:47
4

If it's only a few megabytes, you're can basically slurp it into memory and use the O(n log n) sorting algorithm of your choice to sort it, then write it out.

Basically, write a code snippet to compare two lines the way you want, and use that with your standard library sort routine to sort the data. Or write your own sort routine, whatever.

If you're interested in how you'd go about dealing with gigabytes of data, take a look at Wikipedia's article on External Sorting for a good jumping-off point.

Anon.
  • 58,739
  • 8
  • 81
  • 86