c++, Debian linux system, g++ compiler

Alright, I have a serious problem. I keep getting a segmentation fault everytime cin recieves a string with a period in it and stores it into a string. I used couts to find the location of the segmentation fault. it happens EXACTLY after cin >> myString; is called, and only when I input "map.txt". It mighthave something to do with the period directly in the middle. Maybe it'll happen with other characters, but the one I need is a period.

It won't happen if I input "map." , ".txt" , "map..txt" or "hello.txt" but "map.txt" gives a segmentation fault before the-line-after the input. It will happen with either cin >> or getline( cin , myString ).


The reason I need this to work is so I can read in the file in a ifstream In; , using In.open( myString.c_str() ) . But I can't do that if it gives me a segmentation fault everytime I input the right name for the file! I just need to know why this isn't working. Any help is appreciated. I might still have some muffins for everyone who helps ^_^

Recommended Answers

All 8 Replies

please post some code

And if you're reading in filenames, don't you think getline() would be a better alternative to cin?

Infarction: Well, there's not much necessary, but here's the code that gave the error.

#include <iostream>
#include <string>
#include <sstream>
#include <ifstream>
#include "function.h" /* for the function called, but it's not important. The fault is before it */
using namespace std;

int main()
{
        string fileName;
        cout << "What's the file name/path of the map file? ";
        cin >> fileName;
 /* getline( cin, fileName, '\n' ); does the exact same thing here, I'm afraid, Joe Programmer */
       function( fileName );

       return 0;
}

The segmentation fault happens on the same line it is taken in. Thanks, guys!

Does this crash?

int main()
{
        string fileName = "map.txt";
        function( fileName );
        return 0;
}

If yes, you need to post function()

Does this crash?

int main()
{
        string fileName;
        cout << "What's the file name/path of the map file? ";
        cin >> fileName;
        return 0;
}

If not, you need to post function()

Salem: The first one does crash before execution of the line function( fileName ); . I tested by putting a cout before the function call. The second doesn't crash.

Alright, well let's see here... I don't like to bother you guys with such long snippets of code... I'll take a look. Is it the peek? Nope... AAAAAAAHHHH! Here you go. It's in a class, so you'll need the class def, class constructor, and main... just use it this way:

#include <iostream>
#include <string>
#include <sstream>
#include <ifstream>
using namespace std;

class MatchingTile
{
    public:
        MatchingTile( string inFile );
            
    private:
        vector <vector <string> > board;
        vector <vector <string> > visibleBoard;
        vector <vector <string> > cpuMemory;    
};

int main()
{
        string fileName;
        cout << "What's the file name/path of the map file? ";
        cin >> fileName;
       MatchingTile Game( fileName );
       return 0;
}

MatchingTile::MatchingTile( string inFile )
{
    ifstream In;
    In.open( inFile.c_str() );
    while( In.fail() )
    {
        cout << "\nSorry, but the file failed to open. Try again( Ctrl+C cancels and exits ): ";
        cin >> inFile;
        In.open( inFile.c_str() );
    }
    
    string tempLine; // temp string to hold each line

    vector < vector <string> > backwBoard;
    /* A backwards 2-d vector (the rows are the columns in the real one)
    I'm doing this so I can get the size of the board before I create them,
    making it easier to fill them out */
    
    while ( !In.eof() ) // starting my readin, it's a bit non-standard so I'll document
    { 
        getline( In, tempLine );
        // this getline stores a line from the file into a string
        
        string tempString; // temp string to hold each word

        tempLine.push_back( ' ' ); // add a space to the end of the line for my next getline loop        
        istringstream inss( tempLine, ios_base::trunc ); /* a string stream that holds the lines
        so I can use nested getlines ^_^ Cool, huh? */

        vector <string> tempRow; // a temp row for my backwards vector
        
        while ( getline( inss, tempString, ' ') ) // get a string from inss, stopping at spaces
        {
            tempRow.push_back( tempString ); // put it in a row
        } // continue until the end of inss
        
        backwBoard.push_back( tempRow ); // put the row into the backwBoard
    }
    In.close();
    int     row = backwBoard.size(), // store the number of columns in backwBoard as "row"
        col = backwBoard[0].size(); // store the no of rows in backwBoard as "col"
        // Cause it's backwards! ^_^
    vector < string > emptyCol( row , "Down" ); // make an empty column
    vector < vector <string> > board;// make boards
    vector < vector <string> > visibleBoard;
    vector < vector <string> > cpuMemory;
    for( int c = 0 ; c < col ; c++ )
    {
        board.push_back( emptyCol );
        visibleBoard.push_back( emptyCol );
        cpuMemory.push_back( emptyCol );
    }
    
    // now to fill out board with the contents of backwBoard
    for ( int x = 0 ; x < col ; x++ )
    {
        for ( int y = 0 ; y < row ; y++ )
        {
            board[x][y] = backwBoard[y][x];
            // backwBoard has columns as rows, so reverse the coordinates from board to get the same
        }
    }
    // constructors don't return anything ^_^
};

I hate bothering people with such long and complicated things... It probably has to do with the vectors. Specifically "board" and "bwBoard" Those are the ones that have the most going on. I'll look into it in the mean time. I tried so hard in those parts to keep from going out, commenting like crazy...

well, thanks for the help, everyone! It would probably take me forever on my own.

>#include <ifstream>
Hmm, I had to include <fstream> to make this program compile, as well as <vector>.

Even though using getline() doesn't solve your problem, you should still use it. For 2 reasons: a) there's no newline left behind in the input bufer, and b) if the user enters a filename with spaces in it, the you're not left with the first part (the part before the space).

tempLine.push_back( ' ' ); // add a space to the end of the line for my next getline loop

Why? A space at the end of the line isn't going to do any good...

Some other things look strange in your code, although I don't get any seg faults...

Oh, crap. Yeah I ALWAYS mistype that header, and I guess I did forget the vector library, too. My bad.

I know some things are a bit strange... I will try the getline( cin , fileName ); bit, but you don't get any seg faults? are you on a linux machine? I kinda thought this is a pretty specific problem with linux machines, but I can't find anywhere else where this has happened...

I'll try to figure it out... but everytime I try using debugging statements it makes it appear as though the segmentation fault is occuring exactly as the variable is stored.

Alright, I managed to figure out that 1) my map files might have extra spaces, causing me to have some columns (lines) that have an empty index.
2) the backwards vector was all I needed, my board is going to be easier to deal with as backwards.
So I was getting segmentation faults because of empty indexes in some columns, and
because I was attempting to do something I no longer understand with the boards. Thanks for helping me bounce ideas, guys. And thanks for the tips, they really do help. ^_^ Now you know why I stick around here.

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.