DaniWeb IT Discussion Community

DaniWeb IT Discussion Community (http://www.daniweb.com/forums/index.php)
-   C++ (http://www.daniweb.com/forums/forum8.html)
-   -   Segmentation Fault error (http://www.daniweb.com/forums/thread160632.html)

gotm Dec 3rd, 2008 6:34 pm
Segmentation Fault error
 
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <stdio.h>
#include <time.h>

using namespace std;

bool StringToInt(const string &s, int &i);

int main()
{

        // opening up and setting up the input file stream so we can read it
        // to perform the "account info" and the "history" parts of the program.
        // the inserting part will be done later.
        ifstream logFileIn;
        logFileIn.open("logfile.txt");
       
        // store each line of the logfile into an array where each element
        // of the array is each line of the text file.
        vector<string> each_Line;
        ifstream ifs( "logfile.txt" );
        string temp;
        while( getline( ifs, temp ) )
        {
                each_Line.push_back( temp );
        }

        //closing file so we can open later to write to it
        logFileIn.close();
       
        int numLines = each_Line.size();

        // storing the account holders # in another array and then removing
        // dupes.
        vector<string> account_Numbers(numLines);
        int i;
        for (i=0;i<numLines-1;i++)
        {
                account_Numbers[i] = each_Line[i].substr(0,4);
        }

        // storing the peoples names in another array in the same positions
        // as the previous array of their account #'s.
        vector<string> account_Names(numLines);
       
        int j;
        for (j=0;j<numLines-1;j++)
        {
                account_Names[j] = each_Line[j].erase(0,5);
                int colonPos = account_Names[j].find(":",0);
                account_Names[j] = account_Names[j].substr(0,colonPos);
        }

        // now doing the same thing with a date array.
        vector<string> account_Dates(numLines);

        for (int k=0;k<numLines-1;k++)
        {
                account_Dates[k] = each_Line[k].erase(0,5);
                int colonPos2 = account_Dates[k].find(":",0);
                account_Dates[k] = account_Dates[k].substr(colonPos2+1,8);
        }       

        // once again but for the type of transaction.
        vector<string> account_Tran(numLines);

        for (int l=0;l<numLines-1;l++)
        {
                account_Tran[l] = each_Line[l];
                int colonPos3 = account_Tran[l].rfind(":",(account_Tran[l].length()-1));
                account_Tran[l] = account_Tran[l].substr(colonPos3-1,1);
        }

        // and finally an array for the amount.
        vector<string> amount(numLines);

        for (int m=0;m<numLines-1;m++)
        {
                amount[m] = each_Line[m];
                int finalColon = amount[m].rfind(":",(amount[m].length()-1));
                amount[m] = amount[m].substr(finalColon+1,10);
        }

        //** Here is where the user will select from one of three menus.
       
        cout << endl;
        cout << "Please enter either 'i' for Account Info, 'h' for History, or 't' to Insert a Transaction: " << endl;
        string choice;
        cin >> choice;
       
        //***** Account Info Menu *****//
        if (choice == "i")
        {

                //display list of names
                for (int numNames=0;numNames<numLines-1;numNames++)
                {
                                cout << numNames+1 << ". " << account_Names[numNames] << endl;
                }

                //allow user to select a certain person by entering there number, or q
                //to exit
                cout << endl;
                cout << "Select a person by entering the number next to their name, or enter '0' to quit" << endl;
                int nameChoice;
                cin >> nameChoice;
                if (nameChoice == 0)
                {
                        cout << endl;
                        cout << "Thank you for using this program.";
                }
                else
                {
                        cout << endl;
                        cout << "Account #: " << account_Numbers[nameChoice-1] << endl;
                        cout << "Name: " << account_Names[nameChoice-1] << endl;
                        int balance;
                        for (int a=0;a<numLines-1;a++)
                        {
                                if (account_Names[a] == account_Names[nameChoice-1])
                                {
                                        int tempconvert;
                                        if (account_Tran[a] == "D")
                                        {
                                                if (StringToInt(amount[a],tempconvert))
                                                {
                                                }       
                                                balance = balance + tempconvert;
                                        }
                                        else if (account_Tran[a] == "W")
                                        {
                                                if (StringToInt(amount[a],tempconvert))
                                                {
                                                }
                                                tempconvert = tempconvert * (-1);
                                                balance = balance + tempconvert;
                                        }
                                }
                        }
                        cout << "Balance: $" << balance << endl << endl;
                        cout << "Thank you and please use this program again." << endl;
                }       

        }

        //***** History Menu *****//
        else if (choice == "h")
        {

                //display list of names
          for (int numNames2=0;numNames2<numLines-1;numNames2++)
                  {
                          cout << numNames2+1 << ". " << account_Names[numNames2] << endl;
                  }
          //allow user to select a certain person by entering there number, or q to exit
          cout << endl;
                cout << "Select a person by entering the number next to their name, or enter '0' to quit" << endl;
                int nameChoice2;
                cin >> nameChoice2;
                if (nameChoice2 == 0)
                {
                        cout << endl;
                        cout << "Thank you for using this program.";
                }
                else
                {

                        for (int b=0;b<numLines-1;b++)
                        {
                                if (account_Names[b] == account_Names[nameChoice2-1])
                                {
                                        cout << account_Dates[b] << " " << account_Tran[b] << " $" << amount[b] << endl;
                                }
                        }

                }

        }
       
        //***** Insert a Transaction Menu *****//
        else if (choice == "t")
        {

                //display list of names
                for (int numNames3=0;numNames3<numLines-1;numNames3++)
                {
                        cout << numNames3+1 << ". " << account_Names[numNames3] << endl;
                }
                //user select a person or now a new option to create a new account.
                cout << endl;
                cout << "Select the # next to the person whos account you want to add a transaction to or enter 'add' if you want to add a new account." << endl;
                string nameChoice3;
                cin >> nameChoice3;
                if (nameChoice3 == "add")
                {
                        cout << endl << "Please enter the name of the account holder that you want to add(no spaces please): ";
                        string newAccount;
                        cin >> newAccount;
                        account_Names[numLines] = newAccount;
                        cout << endl << "Please enter the 4 digit account # of the account you would like to create: ";
                        string newAccountNum;
                        cin >> newAccountNum;
                        account_Numbers[numLines] = newAccountNum;
                        cout << endl << "Please enter the type of transaction ('D' or 'W'): ";
                        string newAccountTran;
                        cin >> newAccountTran;
                        account_Tran[numLines] = newAccountTran;
                        cout << endl << "Please enter the amount (without $ sign) of the transaction: ";
                        string newTranAmount;
                        cin >> newTranAmount;
                        amount[numLines] = newTranAmount;
                        cout << endl << "What is todays date? (YY/MM/DD): ";
                        string newDate;
                        cin >> newDate;
                        account_Dates[numLines] = newDate;

                        ofstream logFileOut;
                        logFileOut.open ("logfile.txt");
                        for (int write=0;write<account_Names.size();write++)
                        {
                                logFileOut << account_Numbers[write] << ":" << account_Names[write] << ":" << account_Dates[write] << ":" << account_Tran[write] << ":" << amount[write] << "\n";
                                logFileOut.close();
                        }
                }
                       

        }

        // if they did not enter a correct option.
        else
        {
                cout << "You did not enter a correct choice. The program will now exit. Please run it again and enter correctly." << endl;
        }

}

bool StringToInt(const string &s, int &i)
{
        istringstream myStream(s);

        if (myStream>>i)
                return true;
        else
                return false;
}

The segmentation fault error occurs I think in the block of code from line 200-203. It might occur beyond that as well but I haven't been able to find out because it won't get past the previous part.

Any help?

nmaillet Dec 3rd, 2008 7:59 pm
Re: Segmentation Fault error
 
The problem is with line 203. You're trying the assign the value of
newAccount
to memory outside the bounds of the vector's array. Use
account_Names.push_back(newAccount)
instead, and it should reallocate the memory for you.

Nick

gotm Dec 3rd, 2008 8:10 pm
Re: Segmentation Fault error
 
Quote:

Originally Posted by nmaillet (Post 749740)
The problem is with line 203. You're trying the assign the value of
newAccount
to memory outside the bounds of the vector's array. Use
account_Names.push_back(newAccount)
instead, and it should reallocate the memory for you.

Nick

Thank you so much that fixed it. I have one more question though. The loop after that section where I am writing to the file. When the program finishes, and I looked at the file, it has one line with just the first line of the original file in it. From the program you can probably see what I want it to do, which is just append pretty much one more line of info to the file, even though the way I have it set up to do it is rewrite the whole thing line by line.

Any help on this?

nmaillet Dec 3rd, 2008 8:25 pm
Re: Segmentation Fault error
 
No problem, and try this:
logFileOut.open ("logfile.txt");
for (int write=0;write<account_Names.size();write++)
{
        logFileOut << account_Numbers[write] << ":" << account_Names[write] << ":" << account_Dates[write] << ":" << account_Tran[write] << ":" << amount[write] << "\n";
}
logFileOut.close();
You were closing the file with each iteration.

Nick


All times are GMT -4. The time now is 7:20 pm.

Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2009 DaniWeb® LLC