Thread: assigning values in file to an array

  1. #1
    Registered User
    Join Date
    Jul 2003
    Posts
    5

    Unhappy assigning values in file to an array

    Hi there,

    I'm doing something quite complicated and as a beginner it's baffling me. I need to create a bar chart based on values read in from a file. For example, say the file contains grades of university students between 0 and 100%. I need to store the results in an array, as well as their frequency (as in, how many times a specific grade has been scored). My idea was a two dimensional array- grades and their frequency. But can anyone help me out with some syntax? How to assign contents from a file to a two dimensional array, and how would i declare the array without knowing it's initial values?

    ANy help much appreciated.

    Thanks
    Divinyl

  2. #2
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    What is the format of the file? If there is a definitive, regular format, it shouldn't be too hard. You could just call fgetc() and retrieve characters one at a time, until you hit a bracket. Then start storing characters in a string, and stop when you hit another bracket. Convert the string to a number using atoi().

    One tip, instead of using two dimensional arrays, you could use structs. They're more descriptive of the array. Ie:

    Code:
    struct gradeStruct
    {
    int grade;
    int freq;
    }
    
    gradeStruct grades[50];
    
    grades[0].grade=GetGradeFromFile();
    grades[0].freq=GetFreqFromFile();
    All you have to do is makes those two functions, and a suitable loop.

    So, post the format of the file, and I'll have a look.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  3. #3
    Registered User
    Join Date
    Jul 2003
    Posts
    5
    Thank you for replying. Yes, the struct is more clear than an array.

    The file just contains a long list of 100 different numbers, from 0 - 100. I.e. the grades of 100 students. Like this:

    22
    67
    89
    40

    and so on...

    But there is no reference to frequencies, so i guess i have to do some sort of count...each time a number occurs, add the to an int variable. Any ideas on where i might put this count and the syntax?

    Thanks again

  4. #4
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    One of the easiest ways may be to convert the grade input (string) to an integer, and use that as an offset in the array. Ie:

    Code:
    int grades[100];
    char *temp;
    int nOffset;
    
    memset((LPVOID)&grades,0,100*sizeof(int));
    
    for (int i=0;i<100;i++)
    {
    temp=GetGrade();
    nOffset=atoi(temp)-1;
    grades[nOffset]++;
    }
    Or something like that.

    EDIT: Coding errors
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>memset((LPVOID)&grades,0,100*sizeof(int));
    Yak! This is better:
    >>int grades[100] = {0};

    If you're doing this:
    >>grades[nOffset]++;
    make sure that nOffset is within the array bounds first.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    It's the same in assembler though isn't it Hammer? I admit, it looks a lot better.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  7. #7
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    something like this should work...
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string temp;
        int grades[100]={0};
        int counter=0;
        ifstream file("c:/temp/temp.txt");
        
        while(!file.eof() )
        {
            getline(file, temp);
            grades[counter++] = atoi( temp.c_str() );
        }
        file.close();
        
        for (int index=0; index < counter; index++)
            cout << grades[index] << '\t';
        cout << endl << endl;
        
        int freq[100] = {0};
        for (int x=0; x < 100; x++)
        {
            int temp = grades[x];
            if (temp > 0)
                    freq[temp] += 1;
        }
        
        for(int y=0; y < 100; y++)
            if (freq[y] > 0)
                    cout << "There were " << freq[y] << " students who got " << y << '%' << endl;
                    
        system("PAUSE");
    }

  8. #8
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    You can halve the memory required by incrementing the count directly into the grades array. Change your code to this:

    Code:
    while(!file.eof() )
        {
            getline(file, temp);
            grades[atoi( temp.c_str() )]++;
        }
    Maybe a bit of code to check validity of input, nothing too complex. Doing it my way, you reduce the code a lot.

    Another tip, you declare temp twice, once as a string, once as an int. You should change the name.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  9. #9
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    I see your point but the original post ask for

    I need to store the results in an array, as well as their frequency.
    your way only stores the frequency.

    I fully agree that my code is far from complete, it's just a quick and simple example to give the guy an idea of how to do it

  10. #10
    Registered User
    Join Date
    Oct 2002
    Posts
    291
    Maybe this code is a bit better...
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        string temp;
        int grades[100]={0};
        int freq[100] = {0};
        int counter=0;
        ifstream file("c:/temp/temp.txt");
        
        while(!file.eof() )
        {
            getline(file, temp);
            grades[counter++] = atoi( temp.c_str() );
            freq[atoi( temp.c_str() )]++;
    
        }
    
        for (int index=0; index < counter; index++)
            cout << grades[index] << '\t';
        cout << endl << endl;
        
        for(int y=0; y < 100; y++)
            if (freq[y] > 0)
                    cout << "There were " << freq[y] << " students who got " << y << '%' << endl;
        
        file.close();    
        system("PAUSE");
    }
    I'll leave check validity of input up to others.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  3. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  4. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM