Hello friends ,
I got an important coursework to submit . Let me explain, the coursework consist of a file .. which we must sort, search and we must event create a y-sort algorithm.

After much struggle, i was able to use the stringtokensier to input the data from the file as it was seperated by a tab and there are many lines in the file.

e.g Name Surname Address Age
      Mark   Twain     Missippi  25
      Tom    Sawyer  Missippi  15 and so on .

The problem now is that i am unable to distribute the name to the structures . please help me! I have not sleep for 2 days, i don't know how to do that .. after so much of hard work i dont want to fail this module so please help.


Here my code:

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>



using namespace std;
      struct Person{
             string name;
             string surname;
             string address;
             string age;
             
             };
  
     
int main(int argc, char *argv[])
{              
        
              
        ifstream fin;
        fin.open("input.txt");
        char buf[100];
        string lineOfData;
        
        string arraytemp[4];
        
        int recordcounter=0;
        Person person_name[recordcounter];
        Person person_surname[recordcounter];
        Person person_address[recordcounter];
        Person person_age[recordcounter];      
      
if (fin.is_open())
{
  

        
        while(!fin.eof())
{              
        getline(fin,lineOfData, '\n');
        lineOfData+="\n";
      
       
         
         
        cout <<  "\n\n\n\n\n___________________\n\n";
        cout << lineOfData << "\n\n";
        cout << "size of line is: " << lineOfData.size() << "\n\n";
        
        char delims[] = "\t";
        for(int i=0; i<lineOfData.size(); i++)
        {
                
         buf[i] = lineOfData[i];  
                
        }
        
        
       
        char *result = NULL;
        result = strtok( buf, delims );
        for(int counter=0; result != NULL; counter++ )
        { 
               arraytemp[counter]=result;
                
                
                
               
               
        
        
                  
        
        cout << "\n\n result is: " << result << "\n";  
        result = strtok( NULL, delims ); 
        
        } 
        
        
}//for the while loop        
      
        
      
        
        
        
        
        
        
                         
            fin.close();     //this is for the file
            
}
    else cout << "Unable to open file";
        
      
        for(int i=0; i<4; i++)
        {
                cout << "\n Checking array \t" << arraytemp[i];
                
             
                
         //person_surname[recordcounter].surname=arraytemp[1]; <<<< PROBLEM IS HERE
         //person_address[recordcounter].address=arraytemp[2];
         //person_age[recordcounter].age=arraytemp[3];
          //recordcounter++;
               
                
                
        }
      cout << arraytemp[0];
      cout << person_name[0].name;
     
        
        
        
      
   
       
    cout << "\n\n\n\n\n\n\n";
    system("PAUSE");
    return EXIT_SUCCESS;
}

Thanks in advance friends.
Thanks Daniweb, If daniweb was not here .. dont know what would happen, this is my first post but i got lots of answers here , Thanks.

line 29: recordcounter must be a const integer if it is to be used to set the array size as shown in lines 30-33. That means it must be a value > 0.

const int recordcount = 255;
Person person[recordcounter];

lines 30-33: delete all but one those arrays because you only need one of them. The struct contains all the information you need about one person -- you don't have to have an array for each attribute (name, address, etc). Example: Person person[recordcounter]; line 40: don't write the loop using eof() like that because it will cause problems. Instead write that loop like this:

while ( getline(fin, lineOfData) )
{

}

You could make your code even easier by using the >> operator if the names do not contains embedded spaces

Person person[recordcounter];
int i;
while(i < recordcounter &&  fin >> person[i].name )
{
    fin >> person[i].surname >> person[i].address
         >> person[i]. age;
  ++i;
}

Another approach is to use a vector (declared in the header file <vector> ) instead of array of Person objects. You don't have to set the max size of a vector like you do an array

vector<Person> person;
Person p;
while(fin >> p.name )
{
    fin >> p.surname >> p.address
         >> p. age;
  person.push_back(p);
}

Hello friends,
Wow . what a team , you reply to me so fast and i really happy , you are doing a good work.
First of all, Thank you for you answer ancient dragon .

The eof you told me to remove works, thanks for that.

I do as you said but it has not solve my main problem , I will not be able to used the >> operator as the names contains embedded spaces. The problem here is that the file consists of many lines .. meaning many names, surnames , addresses and ages.

The problem is how to store each data to a struct and how to access these data so that i will be able to sort them later on. I have done lot and lot of research work on struct and i am unable to manage with this, i really need your help guys. This is the beginning of my coursework and i would really appreciate if you help me to store these data in a struct.


You told me to use:

fin >> p.surname >> p.address >> p. age;

but as far as i know this will store the details for only one person, right ?? what about the others, hope you understand where i am stuck.

Thank you friends.
Bye, hope to have an answer soon.

>>but as far as i know this will store the details for only one person, right ?? what about the others, hope you understand where i am stuck.
Yes it will be for only one person -- BUT ...... you failed to read, or maybe comprehend, what the very next line is doing. It is adding that person to the array. Each time that push_back() line is executed it will add another name structure to the array of structures so that by the time the file is finished reading the array will contain a structure for each of the names.

>>I will not be able to used the >> operator as the names contains embedded spaces.
You mean there can be spaces in the first name or spaces in the last name? None of the data you posted is of that format. Only spaces between the names, not within the names.

Hello friends,
Thanks for replying, you are right ,i have not understood the function of the push_back().

Another thing i have not understand, as you are using the fin operator, the program is reading directly from the file, you are not using the strtok(string tokeniser) then, isn't it ?

The data in the file are
e.g

Name          Surname       Address       Age
Azagen Jo    Mootoo         Mauritius     18
Tom            Sawyer        Missippi        15
Mark Paul    Twain           Missippi        25

and so on .

Maybe i forgot to tell someting , the data is seperated by a tab, that's why i used the strtok.

Eg. Azagen(space)Jo(tab)Mootoo(tab)Mauritius(tab)18(newline)
Tom(tab)Sawyer(tab).....

This is only a sample data by in reality the file (.txt) contains 500lines and about 20 columns of data, with consists of characters, integers and floating point.

Here i used a simple text file, to understand the logic and to see if the code is working.

Programmers always said that DIVIDE AND CONQUER is the best way to solve a problem.

You see, this is not an easy coursework for a first year student but still i am trying hard. I would be pleased if you could help me with this part, its only the beginning of the coursework.

I re-write the code, but its still not working.
I am cout the data ..(i am using the cout for testing, to see if the data has been stored in the struct).

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
//#include "StringTokenizer.h"


using namespace std;
      struct Person{
             string name;
             string surname;
             string address;
             string age;

             };


int main(int argc, char *argv[])
{              


        ifstream fin;
        fin.open("input.txt");
        char buf[100];
        string lineOfData;

        string arraytemp[4];

        const int recordcounter = 255;
        vector<Person> person;
        Person p;


if (fin.is_open())
{



while(getline(fin, lineOfData)) // do not write the loop using eof() like that because it will cause problems
{              
        getline(fin,lineOfData, 'n');
        lineOfData+="n";




     int i;

      fin >> p.name >> p.surname >> p.address >> p. age;

     i++;






        cout <<  "nnnnn___________________nn";
        cout << lineOfData << "nn";
        cout << "Size of line is: " << lineOfData.size() << "nn";

        char delims[] = "t";
        for(int i=0; i<lineOfData.size(); i++)
        {

         buf[i] = lineOfData[i];  

        }



        char *result = NULL;
        result = strtok( buf, delims );
        //for(int i=0; result != NULL; i++ )
        //{ 

       while(fin >> p.name)    


              fin >> p.name >> p.surname >> p.address >> p. age;              
              person.push_back(p);
       }



        //cout << "nn Result is: " << result << "n";  
        //result = strtok( NULL, delims ); 







 fin.close();   

}
    else cout << "Unable to open file";        


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




    cout << "Testing : " << i << "  ";
    cout << person[i].name << person[i].surname << person[i].address << person[i]. age;
    cout << "n";



    }








    cout << "nnnnnnn";
    system("PAUSE");
    return EXIT_SUCCESS;
}

Thank you Ancient Dragon.

>>Mark Paul Twain Missippi 25
That line is not in the format you specified. It contains middle name (Paul). So do you store the middle name in the firstname or lastname, or just ignore it altogether?

>>This is only a sample data by in reality the file (.txt) contains 500lines and ~20 columns of data, with consists of characters, integers and floating point.
Then you have a lot more work ahead of you because the program must read all the columns in order to get to the next line. Maybe it would be more efficient to read one whole line at a time into one std::string then split it up with stringstream.

Post one entire line from that file -- load it into notepad, copy a line or two into the clipboard, then paste it here. Also an explaination of what each column means.

Hello friends,
Just check the text file i upload and you will understand the problem, the name, surname, address and age was just a small file i created in order to test the program.

My problem here is that i must used this text file to sort, search and create a new algorithm (known as the Yop-sort). I think i will be able to manage with sorting and so on .. but i am unable to store these values in a struct, please help me friend .. its really important.


You said something about std::string, i came across that when i was doing my research by i was unable to implement it. If you can show me how to store these values in a struct(or any other way that will help me to sort, search later on) would be a great thing for me .

Thank you.

That is a UNICODE formatted text file which can not be read with standard fstream objects (that I know of). UNICODE files are not normal text files. The first two bytes are binary -1 and -2. So you first have to read the first two bytes to determine if it is in UNICODE format or not. The file you posted indicates it is UNICODE, and a hex dump of the file also confirmed that.

How did you generate that file? did your instructor give it to you for the class assignment or did you generate it yourself ?

Here is one way to read that file and read it into a structure. VC++ 2008 Express compier.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;

struct data
{
   int WorldRank;
   string Institution;
   string Region;
   string RegionalRank;
   string Country;
   string NationalRank;
   int ScoreOnAlumni;
   int ScoreOnAward;
   int ScoreOnHiCi;
   int ScoreOnNS;
   int ScoreOnSCI;
   int ScoreOnSize;
   int TotalScore;
};

ifstream& getaline(ifstream& in, char* line, size_t maxlinesize)
// read one line from a UNICODE formatted file and saves it into
// a standard ascii character array.
{
    char wc[sizeof(wchar_t)];
    size_t i = 0;
    while(i < maxlinesize && in.read(wc, sizeof(wc)) )
    {
        if( wc[0] == '\n')
            break;
        line[i++] = wc[0];
    }
    line[i] = 0;
    return in;
}

int main()
{
    vector<data> lst;
    ifstream in("..\\arw.txt", ios::binary);
    if( in.is_open() )
    {
        char line[255] = {0};
        in.read(line, 2);
        if(line[0] == -1 && line[1] == -2)
        {
            // unicode line
            // get a line
            getaline(in, line, sizeof(line)); // ignore the first line of titles
            while( getaline(in, line, sizeof(line)) )
            {
                // this is a tab deliminated file which means each column is deliminated
                // with a tab character.
                data dt;
                stringstream stream(line);
                string word;
                getline(stream,word,'\t');
                dt.WorldRank = atol(word.c_str());
                getline(stream,dt.Institution,'\t');
                getline(stream,dt.Region,'\t');
                getline(stream,dt.RegionalRank,'\t');
                getline(stream,dt.Country,'\t');
                getline(stream,dt.NationalRank,'\t');
                // etc. etc for the rest of the structure members

            }              
        }
        else
        {
            // ascii file
        }
        

    }

}

Hello,
Wow , i am amazed , are you a robot or what (lol) !! You write this code so fast, you are a genius !! oufff .. I am currently downloading vc++, i am using dev compiler at this time, i will try to compile it on dev and let you know, hope this work, i will never forget what you have done for me.

Thank you , i will let know if i got any problems.

Again Thank You Ancient Dragon and Dani Web Team.

Bye.

Hello,

I run the code .. there are not errors , but one thing i dont understand where is the

main int main(int argc, char *argv[])
{


and the system("PAUSE"),

I try to put the MAIN and the SYSTEM PAUSE and I compiled it on Dev C++ and it showing errors, i have never used VC++. Does this code run only on VC++ ? and one last thing friend , how will i know that the struct has stored on the values , let said for world rank , you have used some reserved words that i have never seen before .. Could you just give me an example, please.

Just write the line of code to access and to output all the value for world rank.

Thank You.

see line 41 of the code I posted. If you need the arguments just simply add them on that line.

I don't use system("PAUSE"). But you can add it anywhere you want.

>>how will i know that the struct has stored on the values
Add print stateuemts cout << "rank = " << dt.WorldRank

commented: Very kind, helpful and patient! +2

Hello friends ,
Thank you for the answer Ancient Dragon, sorry not to reply earlier , i didn't get much time, too many coursework , i just submitted part a ludo game in C (ouff) now i got time to continue with this sorting problem which i must submit on Monday 14th April.

I still got a problem, the code you send me works fine, but i find something .. i want to be sure that i wont have problem later on .. cause i am limited in time, on this internet this is the only forum which is replying me.. and thanks again Ancient Dragon, you have help me a lot.

The problem is that when i put the cout << (eg below) to see if the struct has stored the data ... it works ... but
.
.
.

cout << "\n\nrank = " << dt.WorldRank;
cout << "\n\n\nInstitution = " << dt.Institution;

.
.
.
(cont)

I observed the output of the file on screen and i found that columns which contains no data in the text file takes the value of rank

e.g the last few lines of the output were

ScoreOnHiCi = 401
ScoreOnSize = 401
TotalScore = 401

But in the text file, these part were blank.. my question is that, how will i be able to skip these numbers as i will deal with sorting, searching, hope you understand my point and one last question , do you think this coursework is easy or too hard, just to have an idea if i will get enough time to complete this coursework ??

Thanking you in advance.
Bye

Hello friends,
I really need your help .. yeah , your code is cool , i started to understand it when i play a bit with it. Can you please give me an answer for the question above .. i got another problem .. it seem to be simple but i am unable to modify your code.

You declare the WorldRank as an integer but this is not the case as after rank 100 the rank becames

101-152
101-152
101-152
101-152
101-152
101-152
101-152
101-152
101-152
101-152

something like this, which makes WorldRank not an integer .. i try to modify the code but it through an error .

can you please change the first line for me ..

stringstream stream(line);
string word;
getline(stream,word,'\t');
dt.WorldRank = atol(word.c_str());
getline(stream,dt.Institution,'\t');

its really important , i got only 3 days left to work on the yop sort .. i have manage to make the new algorithm but without being able to sort the file , i wont be able to implement the yop sort, please help me.

Finally, the ScoreAward is in float, when i change it to float .. meaning "float ScoreOnAward", its still ouputting the value in integer, maybe i must change something in this

dt.ScoreOnAward = atol(word.c_str());

but what ? i try to play with it but still no result. Please help me.


Thank you friends .

Hello Ancient Dragon,
Please do not consider post #13, as its working, i finally find the solution, but for #14, i got still have some problems, please help.

Bye

Hello Ancient Dragon.. can i have an answer today. please .

Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.