9 Replies - 3466 Views - Last Post: 22 October 2011 - 04:06 AM Rate Topic: -----

#1 hulla  Icon User is offline

  • Writing Lines


Reputation: 49
  • View blog
  • Posts: 732
  • Joined: 05-March 11

Why does this program work strangely ?

Posted 20 October 2011 - 06:16 AM

I have this program that is supposed to remove the white-space of a program. It functions strangely at somewhere around line thirty and skips straight to somewhere around line 104. Here is the code.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    cout << "Enter the file's name with the extension appended." << endl;
    cout << "It must be in the same directory as this program."  << endl;
    string fileName;
    getline(cin, fileName);
    cin.sync();
    cout << fileName << " | Opening" << endl;
    ifstream inFile;
    inFile.open(fileName.c_str());
    if(!inFile)
    {
        cout << "Unable to open " << fileName        << endl;
        cout << "Press enter to exit."               << endl;
        cin.sync();
        cin.get();
        return 0;
    }
    cout << fileName << " | Counting lines" << endl;
    // counter counts
    int counter = 0;
    // storeCurrentLine stores the current line, just so that the lines of the file can be read in.
    string storeCurrentLine;
    // Get the number of lines
    for(; !inFile.eof(); counter++) { getline(inFile, storeCurrentLine); }
    cout << "Finished counting . . ." << endl;
    string *lines = new string[counter];
    if(lines == 0)
    {
        cout << "The file is too large!"    << endl;
        cout << "Press enter to exit . . ." << endl;
        cin.sync();
        cin.get();
        return 0;
    }
    // Reset counter to 1 so that I can recycle it, being an int
    counter = 1;
    // Feed file's lines into *lines[counter-1]
    for(; !inFile.eof(); counter++)
    {
        cout << fileName << " | Getting line " << counter << endl;
        getline(inFile, lines[counter-1]);
    }
    // Parse *lines's strings
    int iii = 1, iiii = 1;
    string currentLine;
    for(; iii != counter; iii++)
    {
        cout << fileName << " | Parsing line " << iii << endl;
        currentLine = lines[iii-1];
        // If a string continues on the next line,
        if (currentLine[currentLine.length()+1] == '\\')
            currentLine[currentLine.length()+1] == ' ';
        // Check if line is a preprocessor directive. If line is, then program will leave it on it's seperate line
        for(; iiii != currentLine.length(); iiii++)
        {
            cout << fileName << " | Reading line " << iii << " / Character " << iiii << endl;
            if(currentLine[iiii-1] != '\t' && currentLine[iiii-1] != ' ' && currentLine[iiii-1] != '#')
                break;
            if(currentLine[iiii-1] == '#')
                // If the preprocessor directive continues on the next line, replace the escape-sequence with a space
                if(currentLine[currentLine.length()-1] == '\\')
                {
                    currentLine[currentLine.length()-1] == ' ';
                }
                lines[counter-1] += '\n';
        }
        iiii = 1;
        iii  = 1;
        // currentChasIsInString will be used in the following for-loop to check whether or not the char being read is inside a string
        bool currentCharIsInString = false;
        // Checks if line has two consecutive spaces
        for(; iiii != currentLine.length(); iiii++)
        {
            cout << fileName << " | Reading line " << iii << " / Character " << iiii << endl;
            if(currentLine[iiii] == '"')
            {
                // If the current character is a string opener/closer, set currentChasIsInString to true or false respectively
                if(currentCharIsInString == false) currentCharIsInString = true;
                else                               currentCharIsInString = false;
            }
            /* If the current character is a space, and the next one is a space aswell, and the current character
             * does not lie in a string, erase the first space because one space is a sufficient delimiter */
            if(currentLine[iiii] == ' ' && currentLine[iiii+1] == ' ' && currentCharIsInString == false)
            {
                currentLine.erase(currentLine[iiii], 1);
                iiii--;
            }
        }
    }
    inFile.close();
    ofstream outFile;
    outFile.open(fileName.c_str());
    // Paste *lines's strings
    for(iii = 1; iii != counter; iii++)
    {
        cout << fileName << " | Pasting line " << iii << endl;
        outFile << lines[iii-1] << " ";
    }
    outFile.close();
    cout << fileName << " has had it's newlines removed, expect for the preprocessor directives." << endl;
    cout << "Process completed." << endl;
    delete[] lines;
    lines = 0;
    return 0;
}



Is This A Good Question/Topic? 0
  • +

Replies To: Why does this program work strangely ?

#2 jimblumberg  Icon User is online

  • member icon


Reputation: 4074
  • View blog
  • Posts: 12,562
  • Joined: 25-December 09

Re: Why does this program work strangely ?

Posted 20 October 2011 - 06:27 AM

It probably has to do with your input stream being in an error state. When you read to the end of file you set your stream eof error flag and leave the file pointer at the end of the file. To re-read a file you must clear the error and reposition the file pointer to the beginning of the file. Please note closing and reopening the file will not automatically clear the stream error.

Jim
Was This Post Helpful? 1
  • +
  • -

#3 Anarion  Icon User is offline

  • The Persian Coder
  • member icon

Reputation: 282
  • View blog
  • Posts: 1,456
  • Joined: 16-May 09

Re: Why does this program work strangely ?

Posted 20 October 2011 - 04:48 PM

I encourage you to take some time and read the C++ FAQ about iostreams or This Tutorial which discusses the problem in details. Your usage of eof is not exactly right.
The eof() member function of streams returns true when you try to read past the end of the file; So, it doesn't indicate if the file has reached it's end. Better say, it indicates if you try to read beyond the end of the file.

Given that, you can change your loop from this:
for(; !inFile.eof(); counter++) { getline(inFile, storeCurrentLine); }

To this:
while(getline(inFile, storeCurrentLine)) {
    counter++;
}

Now with this changed loop, you can read all the lines of the file without trying to read past it's end. Isn't that good? ;)
Hope this can help you.
Was This Post Helpful? 1
  • +
  • -

#4 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 449
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: Why does this program work strangely ?

Posted 20 October 2011 - 05:23 PM

I'm not usually one to give an example in another programming language but seeing a 100 line program do something I could do in one line on the command line sort of makes me cringe.

cat input | tr -d '\n' | tr -d '\t' | tr -d ' ' | tr -d '\r' > output



I used tr because it is available on windows if you are into that kind of oses:). Otherwise sed and a regular expression are probably shorter.
Was This Post Helpful? 0
  • +
  • -

#5 hulla  Icon User is offline

  • Writing Lines


Reputation: 49
  • View blog
  • Posts: 732
  • Joined: 05-March 11

Re: Why does this program work strangely ?

Posted 20 October 2011 - 08:24 PM

But this is not C++ . . . right?
Was This Post Helpful? 0
  • +
  • -

#6 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1345
  • View blog
  • Posts: 4,618
  • Joined: 19-February 09

Re: Why does this program work strangely ?

Posted 20 October 2011 - 09:49 PM

Dividing the program into functions helps in managing the complexity.
Was This Post Helpful? 1
  • +
  • -

#7 hulla  Icon User is offline

  • Writing Lines


Reputation: 49
  • View blog
  • Posts: 732
  • Joined: 05-March 11

Re: Why does this program work strangely ?

Posted 21 October 2011 - 05:47 AM

Good idea! Lemme do it now . . .
Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5832
  • View blog
  • Posts: 12,683
  • Joined: 16-October 07

Re: Why does this program work strangely ?

Posted 21 October 2011 - 06:10 AM

Recovering from the pain of having a variable named iiii...

These two lines just jumped out and say wtf:
// if currentLine.length() is valid
// how could currentLine.length()+1 contain any data?
if (currentLine[currentLine.length()+1] == '\\')
	// you're compareing here, not assigning
	currentLine[currentLine.length()+1] == ' ';



A few functions would be nice. A vector would be good. Variable scope, also good. If you're going to load the whole mess into memory anyway, you could just load it all into one string...
Was This Post Helpful? 0
  • +
  • -

#9 hulla  Icon User is offline

  • Writing Lines


Reputation: 49
  • View blog
  • Posts: 732
  • Joined: 05-March 11

Re: Why does this program work strangely ?

Posted 22 October 2011 - 01:32 AM

Oh thanks for catching that bug it was supposed to be -1.
I name my iterators iii instead of i so i can CTRL+F search them easily in for-loops without returning alot of results. iii was being used and I needed another so I named it iiii. I seriously wonder why everyone calls their iterators i. It's such a small name so it's hard to pick out in the code as well. i kinda looks like an operator as well in dense code or a formula. I guess I'm just different . . .
Edit: Typo.

This post has been edited by hulla: 22 October 2011 - 01:32 AM

Was This Post Helpful? 0
  • +
  • -

#10 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5832
  • View blog
  • Posts: 12,683
  • Joined: 16-October 07

Re: Why does this program work strangely ?

Posted 22 October 2011 - 04:06 AM

View Posthulla, on 22 October 2011 - 04:32 AM, said:

I seriously wonder why everyone calls their iterators i.


Well i for iterator... Seriously, they only have meaning within the context of the loop. If they are meant to survive the loop, you might use some other name. Though, usually, you'd move the logic into a function so you wouldn't have a ton of loops within the same code block, anyway.

The iterator isn't as important as the what you're using it for. If it's unclear what you're using it for, then the program might need to be reorganized.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1