Thread: Struct's

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    45

    Struct's

    Here's my problem with struct maybe someone can shed some light on it. I was working on comparing a sub string in a file to make sure it never repeated, each row/line was its own record and I was comparing the phone numbers some 258 chars out on the row. Prelude helped me with that and now it works!! But My problem now is to check the main file against a list of numbers that are in a different file.
    Code:
    #include "stdafx.h"
    #include "iostream.h"
    #include <cstring>
    #include <fstream>
    #include <functional>
    #include <set>
    #include <string>
    
    using namespace std;
    
    struct compare: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
           return strncmp(a.c_str()+258 , b.c_str()+258 , 12)<0;
      }
    };
    
    void DupRemover(const char *filename, const char *nodup)
    {
      ifstream in(filename);
      ofstream out(nodup);
      
      //ifstream dontcall("dnc.all");
      //string row;
      
      //set<string, compare> dnc_dup; 
      //while (getline(dontcall, row))
    //	      dnc_dup.insert(row);
        string line; 
        set<string, compare> rem_dup;
    
    while (getline(in, line,'\n'))	 
    		rem_dup.insert(line);
    	
    	set<string, compare>::const_iterator it = rem_dup.begin();
    	
      while (it != rem_dup.end())
      {
    	  out<< *it <<endl;
    	it++;
      }
    }
    
    int main (void)
    {
            char filename[12];
    	char nodup[12];
    	cout<<"Enter your processed file: ";
    	cin.getline (filename,11);
    	strncat (filename, ".all", 6);
    	cout << "Your File Name is " << filename << ".\n";
    	cout<<"Enter the new file name: ";
    	cin.getline(nodup,11);
    	strncat (nodup, ".all",11);
    	DupRemover(filename,nodup);
    	return(0);
    }
    The code I commented out was my answer to the problem but I couldn't figure how to have it search the one list to the other. Any help would be great.
    Sorry the post is so long.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well I suppose it really depends on how you're storing them. Basicly the concept is this:
    Code:
    for each item in N list or file:
        for each item in M list or file:
            see if this N list item is the same as this M list item
    You can break it down to a simpler explanation:
    Code:
    while you go through one list
        see if this item is in the other list
            if not add it there or do whatever you're doing
            if so ignore it or do whatever it is you're doing
    How you look to see if it's in the index list or whatever you're calling it depends entirely on how you store your list. If you're using a binary tree or something, lookup is fairly easy. If it's a simple linked list or what not, that's also easy, but not as efficient time wise.

    In effect, you make a function called something like "findThis", which takes an item to find and where to look for it, that returns some value which means something to you. (Something like 0 for found, or not found, and 1 for the other.) Then you call that function with the list to search in, and each element at a time from the second list.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Just some suggestions as quzah seems to have gotten you started on the searching part:

    Code:
    #include "iostream.h"
    You've got all the other up-to-date headers so I don't understand what you are doing with this one here. It should be <iostream> and not "iostream.h".



    Code:
    struct compare: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
           return strncmp(a.c_str()+258 , b.c_str()+258 , 12)<0;
      }
    };
    You should be able to replace the code in red above with a.compare(258,12,b,258,12). You are using string objects so why not use the string's own compare member function instead of needing to do the conversion to char* and then passing to the strncmp function... it's just a thought.


    Code:
    void DupRemover(const char *filename, const char *nodup)
    {
        ifstream in(filename);
        ofstream out(nodup);
    
        ...
    
    }
    
    ...
    
    char filename[12];
    char nodup[12];
    cout<<"Enter your processed file: ";
    cin.getline (filename,11);
    strncat (filename, ".all", 6);
    cout << "Your File Name is " << filename << ".\n";
    cout<<"Enter the new file name: ";
    cin.getline(nodup,11);
    strncat (nodup, ".all",11);
    DupRemover(filename,nodup);
    Again, you are already including the string header so why not use it? Replacing all the character arrays with string objects would make sense and be safer, i.e.:

    Code:
    void DupRemover(const string& filename,const string& nodup)
    {
        ifstream in(filename.c_str());
        ofstream out(nodup.c_str());
    
        ...
    
    }
    
    ...
    
    string filename;
    string nodup;
    cout<<"Enter your processed file: ";
    getline(cin,filename);
    filename += ".all";
    cout << "Your File Name is " << filename << ".\n";
    cout<<"Enter the new file name: ";
    getline(cin,nodup);
    nodup += ".all";
    DupRemover(filename,nodup);
    Making all the above changes, removing any references to strncmp and strncat function and any character arrays, means you can delete the #include <cstring> line as it will no longer be needed.

    Again, the above are only suggestions. Use them or not.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    Dec 2004
    Posts
    45
    hk_mp5kpdw the code suggestions make sense but I tried to implement them and it does not reproduce the correct results that I have gotten with the other code. Is there any other suggestions what about this part
    Code:
    set<string, compare> rem_dup;
    
    while (getline(in, line,'\n'))	 
    		rem_dup.insert(line);
    	
    	set<string, compare>::const_iterator it = rem_dup.begin();
    	
      while (it != rem_dup.end())
      {
    	  out<< *it <<endl;
    	it++;
      }
    One other thing how about the getline(cin,filename);
    I'm a little hazy, the program make you press the enter twice to go on in the program.
    Any help would be great thanks again

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by ajb268
    hk_mp5kpdw the code suggestions make sense but I tried to implement them and it does not reproduce the correct results that I have gotten with the other code.
    What do you mean by "does not reproduce the correct results"? Does the change to compare mean that duplicates are showing up in the set?

    Quote Originally Posted by ajb268
    One other thing how about the getline(cin,filename);
    I'm a little hazy, the program make you press the enter twice to go on in the program.
    What compiler are you using? If using MSVC++ 6.0 then you could be having issue with a known bug in the getline function that can be fixed by following the instructions here (go to Fix to <string> section). Or, you could try putting cin.ignore(1,'\n'); after any getline functions.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    45
    Thanks I fixed the getline bug.

    Other problem:
    What do you mean by "does not reproduce the correct results"? Does the change to compare mean that duplicates are showing up in the set?
    The answer is yes the code now doesn't change the file at all just copies it over to the nodup file with no changes.

  7. #7
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    So what does your compare struct look like? It should look like:

    Code:
    struct compare: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
           return a.compare(258,12,b,258,12) < 0;
      }
    };
    That should be functionally equivalent to your original:

    Code:
    struct compare: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
           return strncmp(a.c_str()+258 , b.c_str()+258 , 12) < 0;
      }
    };
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  8. #8
    Registered User
    Join Date
    Dec 2004
    Posts
    45
    This is my exact code from my program:
    Code:
    struct compare: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
    	 return a.compare(258,12,b,258,12)<0;
             //strncmp(a.c_str()+258 , b.c_str()+258 , 12)<0;
    	
      }
    };
    Do you have any suggestions?
    Last edited by ajb268; 01-05-2005 at 01:01 PM.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    6
    Hello,

    talking about structs, do u know how can I make a casting from a struct to WORD? I mean I have a bit field like:

    struct estructure
    {
    unsigned control : 1;
    unsigned pedal : 2;

    } layout

    and I want to cast it to a WORD variable. is it possible?

    Thanks

  10. #10
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Well, I tested both versions of the compare function object with a quick test program:

    Code:
    #include <iostream>
    #include <iomanip>
    #include <functional>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    struct compare1: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
           return a.compare(2,5,b,2,5) < 0;
      }
    };
    
    struct compare2: binary_function<string, string, bool> {
      bool operator()(const string& a, const string& b)
      {
           return strncmp(a.c_str()+2, b.c_str()+2, 5 ) < 0;
      }
    };
    
    int main()
    {
        string str1("Hello World"), str2("Hello World");
    
        // Test str1 = str2
        cout << boolalpha << compare1()(str1,str2) << endl;
        cout << boolalpha << compare2()(str1,str2) << endl;
    
        // Test str1 < str2
        str2 = "Hello Xorld";
        cout << boolalpha << compare1()(str1,str2) << endl;
        cout << boolalpha << compare2()(str1,str2) << endl;
    
        // Test str1 > str2
        str1 = "Hello Yorld";
        cout << boolalpha << compare1()(str1,str2) << endl;
        cout << boolalpha << compare2()(str1,str2) << endl;
    }
    My output:
    Code:
    false
    false
    true
    true
    false
    false
    So they both produce the same results and shouldn't be affecting the issue of duplicates and sorting within your nodup file. But... if you can't get the string::compare version working you can always fall back to the strncmp version for now.

    You could try running and compiling that test example and see if you get the same results as I do.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  11. #11
    Registered User
    Join Date
    Dec 2004
    Posts
    45
    This is the code I have calling the struct I guess, I'm not very clear on where it is calling it but here it is.

    Code:
    void DupRemover(const string& filename, const string& nodup)
    {
      ifstream in(filename.c_str());
      ofstream out(nodup.c_str());
      //ofstream fout("god.all");
      string line;
      
      set<string, compare> rem_dup;
    
      while (getline(in, line,'\n'))	 
    		rem_dup.insert(line);
    	
    	set<string, compare>::const_iterator it = rem_dup.begin();
    	
      while (it != rem_dup.end())
      {
    	  out<< *it <<endl;
    	it++;
      }
    }
    This doesn't look like your test at all so how would trying that decide if this code works or not?
    Is there something wrong here or should I just jump back to strncmp?

  12. #12
    Registered User
    Join Date
    Dec 2004
    Posts
    45
    The question is:
    struct estructure
    {
    unsigned control : 1;
    unsigned pedal : 2;

    } layout

    and I want to cast it to a WORD variable. is it possible?
    ]

    The answer might be here but I'm not sure myself.
    http://faq.cprogramming.com/cgi-bin/...&id=1073086407

  13. #13
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by michelpc
    Hello,

    talking about structs, do u know how can I make a casting from a struct to WORD? I mean I have a bit field like:

    struct estructure
    {
    unsigned control : 1;
    unsigned pedal : 2;

    } layout

    and I want to cast it to a WORD variable. is it possible?

    Thanks

    You can define your own casts to specific types for structs and their specific behavior. As an example:

    Code:
    struct a
    {
        unsigned p1 : 8;
        unsigned p2 : 8;
        unsigned p3 : 8;
        unsigned p4 : 8;
        operator int()
        {
            return p1 + p2 + p3 + p4;
        }
        operator double()
        {
            return (double)p1 + (double)p2 - (double)p3 - (double)p4;
        }
    };
    
    a a1;
    a1.p1 = 8;
    a1.p2 = 12;
    a1.p3 = 20;
    a1.p4 = 8;
    
    cout << (int)a1 << endl;
    cout << (double)a1 << endl;
    Output:

    Code:
    48
    -8
    Last edited by hk_mp5kpdw; 01-05-2005 at 12:46 PM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  14. #14
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by ajb268
    This is the code I have calling the struct I guess, I'm not very clear on where it is calling it but here it is.
    The struct is called whenever you call the set::insert member function although you do not directly see it being called.

    Quote Originally Posted by ajb268
    This doesn't look like your test at all so how would trying that decide if this code works or not?
    My test is simply something to show that both a strncmp version and a string::compare version produce the same results for the same input. My suggestion was for you to take that same test code, compile it, run it, and verify that you also get the same results that I do. If you got the same results, then I would suspect there may be something else we are not seeing that is causing the problem.

    Quote Originally Posted by ajb268
    Is there something wrong here or should I just jump back to strncmp?
    For the moment, I would go back to what works for you. But perhaps if you would be willing, you could again post your complete code and also (if you don't mind) the input file (as an attachment) that you are using to run your tests I could run the program and see if I get the same results that you are getting.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  15. #15
    Registered User
    Join Date
    Dec 2004
    Posts
    45
    I was going to repost what I had but I realized what I did I transposed the 258 to 285 that works now I'm working on my original problem of searching the file for do not call numbers and purging them from the file
    i.e..
    Code:
    void DncRemover(const string& filename, const string& dontcall,const string& nodup)
    {
    	string row;
    	string number;
    	ifstream file(filename.c_str());
    	ifstream dnc(dontcall.c_str());
    	//ofstream out(nodup.c_str());
    	ofstream trial("newfile.all");
    	while (getline(file,row))
    	{
    		while (getline(dnc,number))
    		{
    			if (row.compare(258,12,number,0,12)>0)
    				trial<<row<<endl;
    			else 
    				break;
    		}
    	}
    }
    This code however doesn't work I tried some of the others as a brute force method but I just get alot of repeated records. Well if you have any easy fix cool.
    Thanks again

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating array of structs
    By knirirr in forum C++ Programming
    Replies: 12
    Last Post: 06-18-2008, 08:30 AM
  2. Multidimentional structs + memcpy() == FAIL
    By Viper187 in forum C Programming
    Replies: 8
    Last Post: 06-18-2008, 02:46 AM
  3. packed structs
    By moi in forum C Programming
    Replies: 4
    Last Post: 08-20-2002, 01:46 PM
  4. ArrayLists + Inner Structs
    By ginoitalo in forum C# Programming
    Replies: 5
    Last Post: 05-09-2002, 05:09 AM
  5. Searching structs...
    By Sebastiani in forum C Programming
    Replies: 1
    Last Post: 08-25-2001, 12:38 PM