Hey, I have to read numbers from a text file. Heres an example input:

6 8
1 2 10
1 3 9
2 3 7
2 4 2
3 5 5
4 5 3
4 6 8
5 6 4

The parser I coded works fine in NetBeans and Dev c++, however we are required to run it on a linux terminal also.
Heres how the last column looks after I read it in from the text file in linux:

10
7
2
5
3
8
4

it seems to skip the 9. Heres my code for reading the info from the text file "input.txt"

//first I get all the lines and add them to a string vector
ifstream myFile("input.txt");
    if (myFile.is_open())
    {
        while (!myFile.eof())
        {
            getline(myFile,line);
            inputLines.push_back(line);
        }

        myFile.close();
    }
 
    //this while loop will parse all the info from the text file
    while (lineNumber < inputLines.size())
    {
        //converts the read in line to a c sting
        cstrInput = new char[line.size()+1];
        strcpy(cstrInput,inputLines[lineNumber].c_str());
        
        //parse the line, looking for a space or " "
        parser = strtok(cstrInput," ");
        
        while (parser != NULL)
        {
            //all input is integers, so convert the num to an integer
            num = atoi(parser);
            
            
            if (infoType == 1)
            {
                //infoType is one, and line number is 0, so I'm parsing nV
                if (lineNumber == 0)
                {
                    //create a new set with nV amount
                    theSet = new dis_set(num);
                } 
                
                //u is the first column
               //not the first line, so info is u values
                else
                {
                    theEdge.u = num;
                    
                }
            } 
            
            else if (infoType == 2)
            {
                //infoType is two, and line number is 0, so I'm parsing nE
                if (lineNumber == 0)
                {
                    //create a new heap with nE amount
                    theHeap = new min_heap(num);
                  
                } 
                else
                {
                   //v is the second coloumn 
                   //not the first line, so info is v value
                    theEdge.v = num;
                }
            } 

            //if infoType is 3, than I'm reading a cost value.
            else if (infoType == 3)
            {
                if (lineNumber == 0)
                    ;
                else
                
               //cost is the third coloumn
               theEdge.cost = num;
            }

            parser = strtok(NULL," ");
            infoType++;
        }

        //insert the newly created edge into the heap
        theHeap->insert(theEdge);
        lineNumber++;
        infoType = 1; // set infoType to 1
    }

The first line of the text file just tells me how many vertices (nV) and edges (nE) I have.

I create a loop that goes through the string vector. Each loop it creates an Edge (an edge is a struct made up of 3 ints which are two vertices and a cost). I set the first value to Edge.u, I set the second value to Edge.v, and i set the third Edge.cost.

I then insert the edge into a min-heap. But, like I stated above the parse code works in NetBeans and Dev c++, but it doesnt work properly in a linux terminal.

Dani AI

Generated

Most likely cause: undefined behaviour from your manual C-string handling rather than a platform text/IO bug. The symptoms (works in Windows IDE but drops a token on Linux) are classic for a buffer overwrite or parsing that depends on incidental memory layout.

Two concrete problems to check in 's posted code:

  • The buffer you allocate for cstrInput uses line.size() while you copy inputLines[lineNumber]. If those sizes differ you write past the allocated buffer and corrupt memory; that can silently “work” on one platform and fail on another.
  • Using while (!myFile.eof()) and strtok makes the logic brittle (and strtok mutates the buffer). Also make sure you never insert an Edge for the header line (the first line with nV/nE).

Safer approach (replace manual C strings with C++ streams): read lines with std::getline and parse each line with std::istringstream. Example pattern:

std::ifstream in("input.txt");
std::string line;
while (std::getline(in, line)) {
    if (!line.empty() && line.back() == '\r') line.pop_back(); // strip Windows CR if needed
    std::istringstream iss(line);
    if (header_line) {
        int nV, nE;
        if (iss >> nV >> nE) { /* init */ }
    } else {
        int u, v, cost;
        if (iss >> u >> v >> cost) heap.insert({u,v,cost});
    }
}

Extra debugging tips:

Following 's hint, try building the exact same sources with g++ on Windows (outside the IDE) and with the sanitizers enabled; that will usually expose the underlying UB rather than chasing platform differences.

Recommended Answers

All 2 Replies

I then insert the edge into a min-heap. But, like I stated above the parse code works in NetBeans and Dev c++, but it doesnt work properly in a linux terminal.

What do you mean by the statement above? Are you trying to compile your code using GCC in Linux? Or do you mean your code works fine in Windows but not in Linux?

Everything you posted looks portable from Windows to Linux and vice-versa, so I would imagine the problem would be elsewhere, either in code you haven't posted or some linking or compiler or makefile issues. I'd try building it with g++ on Windows outside of the IDE using whatever Makefile you are using in Linux and see if it still works in Windows. If not, it may be that the Makefile generated by the IDE has something non-portable or it could be a path or permissions issue or any of a whole bunch of things.

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.