counting and output, with arrays and functions

This is a discussion on counting and output, with arrays and functions within the C++ Programming forums, part of the General Programming Boards category; Ok, yet another question from me. I am having troubles now with my program counting runes from a text file ...

  1. #1
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094

    counting and output, with arrays and functions

    Ok, yet another question from me. I am having troubles now with my program counting runes from a text file (I will show a example of that file) and, if I uncomment the line calling my output function, it will output what ever is in the array, but when it hits the bottom I get a "TodesRunes.exe has encountered a problem and needs to close. We are sorry for the inconvenience."

    Also, since it does output before it crashes, I noticed that it is not counting the items from the file.

    The line of T's was to see if it was dying before or after that.

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    void loadfile(ifstream& file);
    
    void counter(int aiRunes1[], string sRuneNames[], int iNumOfRunes, ifstream& file);
    
    void output(int aiRunes1[], string sRuneNames[], int iNumOfRunes);
    
    int main ()
    {
        cout<<"Welcome to TodesRunes 1.1!"<<endl;
        const int iNumOfRunes = 33;
        int aiRunes1[iNumOfRunes] = {0};
        string sRuneNames[iNumOfRunes] = {"El", "Eld", "Tir", "Nef", "Eth", "Ith",
                                          "Tal", "Ral", "Ort", "Thul", "Amn", "Sol",
                                          "Shael", "Dol", "Hel", "Io", "Lum", "Ko",
                                          "Fal", "Lem", "Pul", "Um", "Mal", "Ist",
                                          "Gul", "Vex", "Ohm", "Lo", "Sur", "Ber",
                                          "Jah", "Cham", "Zod"};
        
    
        ifstream file;     //ATMA dump
        loadfile(file);    //loads the ATMA dump
        counter(aiRunes1, sRuneNames, iNumOfRunes, file);
        output(aiRunes1, sRuneNames, iNumOfRunes);
        cout<<"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT";
        cin.get();
    }
    
    void loadfile(ifstream& file)
    {
        file.open( "runes.txt");
        if (!file.is_open())
            file.open( "rune.txt");;
        while(!file.is_open())
        {
            string filename;
            cout<<"TodesRunes could not find your ATMA dump,"<<endl
                <<"please specify the path to the txt file."<<endl;
            getline(cin,filename);
            file.open(filename.c_str());
        }        
    }
    
    void counter(int aiRunes1[], string sRuneNames[], int iNumOfRunes, ifstream& file)
    {   
        int iCounter = 0;
        string sLine;
        while (getline( file , sLine ))
    	{
            if (sLine.empty() || (sLine == "\r")) continue;
            int colon_pos = sLine.find(':');
            string sRune = sLine.substr(colon_pos+2,sLine.size()-colon_pos-7);
            while(iCounter<=iNumOfRunes)
            {
                if(sRune==sRuneNames[iCounter])
                {
                    aiRunes1[iCounter]++;
                    iCounter=iNumOfRunes+1;
                }
                else
                {
                    iCounter++;
                }
            }
        }
    }
    
    void output(int aiRunes1[], string sRuneNames[], int iNumOfRunes)
    {
        int iCounter = 0;
        while(iCounter<=iNumOfRunes)
        {
            cout<<sRuneNames[iCounter]<<": "<<aiRunes1[iCounter]<<endl;
            iCounter++;
        }
    }
    runes.txt
    Code:
    12: Tir Rune
    
    13: Eth Rune
    
    14: El Rune
    
    15: Eth Rune
    
    16: Amn Rune
    
    17: Ral Rune
    
    18: Tir Rune
    
    19: El Rune
    
    20: Ral Rune
    
    21: El Rune
    
    22: Ort Rune
    
    23: Eth Rune
    The file I am using is actually ~26mb, in my last version of the program (before the rewrite) it took ~5 seconds to load the file in my program and parse it, this program it looks like it is done instantly.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,852
    > while(iCounter<=iNumOfRunes)
    You step off the end of the array with this kind of code - use <, not <=
    Also, there's nothing in your counter() function which resets iCounter to begin a new search for a new rune.

    Certainly, I'd prefer a for loop rather than a while loop in your output() function.

  3. #3
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094
    Ok, I switched my <= and put in <, then I changed the while loops at the bottom to for loops, still I am getting nothing counted. But, it is not terminating.

    Thank you for your help so far.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,852
    So run the code inside the debugger, run one statement at a time (single step) and examine how the variables change.
    When a variable changes to something you didn't expect, you've probably found a bug.

  5. #5
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094
    Ok, so I isolated the problem, but I can't figure it out. I have always used while(getline(sLine,file)) to get all the data from a file, so this doesn't make sence to me, but it is never entering that loop.

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    void loadfile(ifstream& file);
    
    void counter(int aiRunes1[], string sRuneNames[], int iNumOfRunes, ifstream& file);
    
    void output(int aiRunes1[], string sRuneNames[], int iNumOfRunes);
    
    int main ()
    {
        cout<<"Welcome to TodesRunes 1.1!"<<endl;
        const int iNumOfRunes = 33;
        int aiRunes1[iNumOfRunes] = {0};
        string sRuneNames[iNumOfRunes] = {"El", "Eld", "Tir", "Nef", "Eth", "Ith",
                                          "Tal", "Ral", "Ort", "Thul", "Amn", "Sol",
                                          "Shael", "Dol", "Hel", "Io", "Lum", "Ko",
                                          "Fal", "Lem", "Pul", "Um", "Mal", "Ist",
                                          "Gul", "Vex", "Ohm", "Lo", "Sur", "Ber",
                                          "Jah", "Cham", "Zod"};
        
    
        ifstream file;     //ATMA dump
        loadfile(file);    //loads the ATMA dump
        counter(aiRunes1, sRuneNames, iNumOfRunes, file);
    //    output(aiRunes1, sRuneNames, iNumOfRunes);
        cout<<"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT";
        cin.get();
    }
    
    void loadfile(ifstream& file)
    {
        file.open( "runes.txt");
        if (!file.is_open())
            file.open( "rune.txt");;
        while(!file.is_open())
        {
            string filename;
            cout<<"TodesRunes could not find your ATMA dump,"<<endl
                <<"please specify the path to the txt file."<<endl;
            getline(cin,filename);
            file.open(filename.c_str());
        }        
    }
    
    void counter(int aiRunes1[], string sRuneNames[], int iNumOfRunes, ifstream& file)
    {   
    cout<<"1";
        string sLine;
    cout<<"2";
        while(getline(file , sLine))
    	{
    cout<<"3";
            if (sLine.empty() || (sLine == "\r")) continue;
    cout<<"4";
            int colon_pos = sLine.find(':');
    cout<<"5";
            string sRune = sLine.substr(colon_pos+2,sLine.size()-colon_pos-7);
    cout<<"6";
            for(int iCounter = 0; iCounter<iNumOfRunes; iCounter++)
            {
    cout<<"7";
                if(sRune==sRuneNames[iCounter])
                {
    cout<<"8";
                    aiRunes1[iCounter]++;
                    iCounter=iNumOfRunes+1;
                }
    cout<<"9";
            }
    cout<<"10";
        }
    cout<<"11";
    }
    
    void output(int aiRunes1[], string sRuneNames[], int iNumOfRunes)
    {
        for(int iCounter = 0; iCounter<iNumOfRunes; iCounter++)
        {
            cout<<sRuneNames[iCounter]<<": "<<aiRunes1[iCounter]<<endl;
        }
    }
    This is one of the runes.txt files I am testing with.
    Code:
    Character name  : Todesritter
    Character type  : Necromancer
    Character level : 6
    Character exp   : 17710
    
    Strength        : 30
    Energy          : 25
    Dexterity       : 25
    Vitality        : 25
    Stat Points Rem : 0
    Skill Points Rem: 0
    
    Life            : 72 / 72
    Mana            : 44 / 35
    Stamina         : 89 / 94
    
    Gold (Inventory): 2916
    Gold (Stash)    : 0
    
    Number of Items : 11
    
    1: Boots
    
    2: Superior Quilted Armor
    
    3: Tome of Identify
    
    4: Tome of Town Portal
    
    5: Minor Healing Potion
    
    6: Minor Healing Potion
    
    7: Minor Healing Potion
    
    8: Minor Healing Potion
    
    9: Lizard's Sash
    
    10: Wand
    
    11: Demon Wing - Buckler
    
    12: Tir Rune
    
    13: Eth Rune
    
    14: El Rune
    
    15: Eth Rune
    
    16: Amn Rune
    
    17: Ral Rune
    
    18: Tir Rune
    
    19: El Rune
    
    20: Ral Rune
    
    21: El Rune
    
    22: Ort Rune
    
    23: Eth Rune

    I get 1, 2, and 11, but none of the others form my cout<<'s

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,852
    *shrugs* works for me on Linux
    Code:
    Welcome to TodesRunes 1.1!
    12345679 ... lots more 79 and a fair number of 3456 ...
    El: 3
    Eld: 0
    Tir: 2
    Nef: 0
    Eth: 3
    Ith: 0
    Tal: 0
    Ral: 2
    Ort: 1
    Thul: 0
    Amn: 1
    Sol: 0
    Shael: 0
    Dol: 0
    Hel: 0
    Io: 0
    Lum: 0
    Ko: 0
    Fal: 0
    Lem: 0
    Pul: 0
    Um: 0
    Mal: 0
    Ist: 0
    Gul: 0
    Vex: 0
    Ohm: 0
    Lo: 0
    Sur: 0
    Ber: 0
    Jah: 0
    Cham: 0
    Zod: 0
    TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
    Check for an empty file of the same name in unexpected locations. If you're running inside an IDE, the current directory the program executes in is not always the directory where the executable is.

  7. #7
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094
    Ok, so I forgot that I was just testing the path feature, and not the autoloader. If it is autoloading it works fine, but if you have to enter the path (say you name it runes1.txt or something), it wont count, I have tested opening non-existant files aka bad paths, and it makes me try again (like I programmed into it).

    Updated source:
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    void loadfile(ifstream& file);
    
    void counter(int aiRunes1[], string sRuneNames[], int iNumOfRunes, ifstream& file);
    
    void output(int aiRunes1[], string sRuneNames[], int iNumOfRunes);
    
    int main ()
    {
        cout<<"Welcome to TodesRunes 1.1!"<<endl;
        const int iNumOfRunes = 33;
        int aiRunes1[iNumOfRunes] = {0};
        string sRuneNames[iNumOfRunes] = {"El", "Eld", "Tir", "Nef", "Eth", "Ith",
                                          "Tal", "Ral", "Ort", "Thul", "Amn", "Sol",
                                          "Shael", "Dol", "Hel", "Io", "Lum", "Ko",
                                          "Fal", "Lem", "Pul", "Um", "Mal", "Ist",
                                          "Gul", "Vex", "Ohm", "Lo", "Sur", "Ber",
                                          "Jah", "Cham", "Zod"};
        
    
        ifstream file;     //ATMA dump
        loadfile(file);    //loads the ATMA dump
        counter(aiRunes1, sRuneNames, iNumOfRunes, file);
        output(aiRunes1, sRuneNames, iNumOfRunes);
        int total = 0;
        for(int iCounter = 0; iCounter<iNumOfRunes; iCounter++)
        {
            total=total+aiRunes1[iCounter];
            cout<<aiRunes1[iCounter];
        }
        cout<<"\nTotal Runes: "<<total;
        
        cin.get();
    }
    
    void loadfile(ifstream& file)
    {
        file.open( "runes.txt");
        if (!file.is_open())
            file.open( "rune.txt");;
        while(!file.is_open())
        {
            string filename;
            cout<<"TodesRunes could not find your ATMA dump,"<<endl
                <<"please specify the path to the txt file."<<endl;
            getline(cin,filename);
            file.open(filename.c_str());
        }        
    }
    
    void counter(int aiRunes1[], string sRuneNames[], int iNumOfRunes, ifstream& file)
    {   
        string sLine;
        while(getline(file , sLine))
    	{
            if (sLine.empty() || (sLine == "\r")) continue;
            int colon_pos = sLine.find(':');
            string sRune = sLine.substr(colon_pos+2,sLine.size()-colon_pos-7);
            for(int iCounter = 0; iCounter<iNumOfRunes; iCounter++)
            {
                if(sRune==sRuneNames[iCounter])
                {
                    aiRunes1[iCounter]++;
                    iCounter=iNumOfRunes+1;
                }
            }
    
        }
    }
    
    void output(int aiRunes1[], string sRuneNames[], int iNumOfRunes)
    {
        for(int iCounter = 0; iCounter<iNumOfRunes; iCounter++)
        {
            cout<<sRuneNames[iCounter]<<": "<<aiRunes1[iCounter]<<endl;
        }
    }
    I am sure it is loading the file, because if it couldn't open it, then it wouldn't leave the loop. So I am lost, once again =/

  8. #8
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094
    through more testing, I am finding it is getting nothing from the file if I open it by puting in the path. I have verified it is open at different parts of each function. But my while(getline(file,sLine)) is not getting anything, nor is it even going through the file, because it takes a couple seconds for it to go though the 26 meg file when I autoload it.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21