Urgent help needed!

Hello all,

I'm new to the language C++. Recently our teacher asked us to write a code
that does the following things:

1 - Remove all comments from a file (only comments starting with //).
2 - 'Jump' correctly.
3 - Find out if a certain number is a Lychrel number.
4 - Include statistics (how many lines/characters does the input file have?)

It has to behave like a compiler, so to say. We have to use functions to achieve these goals and we may only use <iostream>, <fstream>, <string>, and <climits>.

Now I'm facing one big problem. I'm writing a function that counts how many lines the input file has, but it just doesn't work.
I don't get any errors, but when I run the program, I get (for teller) 0.
If I remove the 0 from the code (see below for the code) I get the result 2147344384. That obviously is incorrect.

Here below you can find the code. This is my attempt to count how many times a person pressed 'Enter' to continue on a new line.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int telRegels (ifstream& invoer)
{   int teller;
    char B = invoer.get ();
    char A = '\n';
    int C = static_cast<int>(B);
    while (! invoer.eof())
    {     if (C == 13)
           {teller++;
           }
          A = B;
          B = invoer.get ();
    }
    return teller;
}


   cout << telRegels (invoer);


Could you guys help me?

Kind regards,

NSA
Last edited on
Source code file probably uses LF style lines.
http://stackoverflow.com/questions/1552749/difference-between-cr-lf-lf-and-cr-line-break-types
use '\n' to find line ends.

EDIT: It is more possible that opening a file in text mode will make stream extraction automaticly convert CRLF sequence to a single '\n' which is often represented by 0x0A or LF character.
Last edited on
So, I have to search from '\n' instead of CR?
But that doesn't give me the amount of lines in a source code, right?
Is the rest of the code okay?
For a file opened in text mode, do not test for either CR ot LF characters.
Test for the newline character '\n'

> But that doesn't give me the amount of lines in a source code, right?

It gives you the number of newline characters in the file.
(The number of lines would be one grater than that if the file does not end in a newline. I guess you could ignore that possibility for this exercise; assume that the last character in the file is a newline character.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <string>
#include <iostream>
#include <fstream>
#include <limits>

int telRegels( std::ifstream& invoer )
{
    const char newline = '\n' ;

    int teller = 0 ; // *** initialize to zero

    char c ;
    while( invoer.get(c) )
    {
        if( c == newline ) ++teller ;
    }

    return teller ;
}

int telRegels_v2( std::ifstream& invoer )
{
    const char newline = '\n' ;
    int teller = 0 ;

    // http://www.cplusplus.com/reference/istream/istream/ignore/
    while( invoer.ignore( std::numeric_limits<std::streamsize>::max(), newline ) )
        ++teller ;

    return teller - 1 ;
}

int main()
{
    {
        std::ifstream this_file(__FILE__) ;
        std::cout << telRegels(this_file) << '\n' ;
    }

    {
        std::ifstream this_file(__FILE__) ;
        std::cout << telRegels_v2(this_file) << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/9f96f4310ef047c7
Last edited on
1
2
3
4
5
6
7
8
9
int linesCount(ifstream& in)
{
    char c;
    int count = 1; //Line numeration starts from 1
    while(in.get(c))
        if(c == '\n')
            ++count;
    return count; 
}
Simplified your code. Yes, it will be correct.

EDIT: Arrr. I should refresh page before posting.
JLBorges wrote:
The number of lines would be one grater than that if the file does not end in a newline
I have always thought that last newline starts a new (empty) string.
Line numbering in IDEs and text editors agrees with me :)
Last edited on
Thanks for your replies guys.
JLBorges, I don't really understand the second function (V2).
Is it the same as the first? What does it do?

Thanks again,

NSA
> I have always thought that last newline starts a new (empty) string.
> Line numbering in IDEs and text editors agrees with me :)

Line numbering in IDEs and text editors that I have encountered agrees with me :)

There is also some confusion whether newlines terminate or separate lines. If a newline is considered a separator, there will be no newline after the last line of a file. Some programs have problems processing the last line of a file if it is not newline terminated. Conversely, programs that expect newline to be used as a separator will interpret a final newline as starting a new (empty) line.
- http://en.wikipedia.org/wiki/Newline

As there is no universal agreement on whether a text file should end in a newline, the IS specifies that:
A source file that is not empty and that does not end in a new-line character, or that ends in a new-line character immediately preceded by a backslash character before any such splicing takes place, shall be processed as if an additional new-line character were appended to the file.




> JLBorges, I don't really understand the second function (V2).
> Is it the same as the first? What does it do?

invoer.ignore( std::numeric_limits<std::streamsize>::max(), newline )
extracts and throws away characters one by one till a newline character is extracted and thrown away (or eof is reached).

Since we put this in a loop, we the number of times
invoer.ignore( std::numeric_limits<std::streamsize>::max(), newline )
is executed is equal to the number of newlines in the file plus one. (Plus one, because when it executes for the last time, it will return because an eof was encountered)
Last edited on
Ooh I see...
Thanks for that!

Another question; I want to remove all comments in
a file beginning with //. I have this (see below), but don't know how to continue.
I thought that if the program finds '//' , then it removes the code that comes after '//' till it finds a '\n'.

1
2
3
4
5
6
7
8
9
10
11
12
13
void commentWeg (ifstream& invoer, ofstream& uitvoer)
{    char vorigeKar = '\n';
     char huidigeKar = invoer.get();
     while (! invoer.get())
     {     if (huidigeKar == '/' && vorigeKar == '/')
               while (invoer.get() != '\n')
               {     
                 //something  
               }
           vorigeKar = huidigeKar;
           huidigeKar = invoer.get();    
     }
}
> Another question; I want to remove all comments in a file beginning with //.

First, read this tutorial up to the part that talks about 'Regular Expressions with the Boost Library'
http://www.mochima.com/tutorials/strings.html

Make sure that you understand the first part using std::string
Regular expressions can wait.

Then, try writing something like this on your own:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>

int main()
{
    std::ifstream this_file(__FILE__) ;  // open this file

    std::string line ;
    int line_number = 0 ;

    // read line by line from file till eof
    // see: http://www.cplusplus.com/reference/string/string/getline/
    while( std::getline( this_file, line ) ) // for each line in the file
    {
        // check if it contains a "//"
        // this does not take care of:
        char this_is_not_a_comment[] = "// this is not // a comment" ;
        // and a few other constructs.
        // but we will ignore that nicety for the moment

        // does this line contain a "//" ?
        // see: http://www.cplusplus.com/reference/string/string/find/
        auto pos = line.find( "//" ) ;
        if( pos != std::string::npos ) // yes, it does
        {
            // make this line just the the part before the "//"
            // see: http://www.cplusplus.com/reference/string/string/substr/
            line = line.substr( 0, pos ) ;
        }

        // print out the line without comments
        std::cout << std::setw(2) << ++line_number << ". " << line << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/70b6867ea4195447
If you want to go for the symbol-by-symbol approach, you can study my old uni C assigment. I think it is easy to get hold of algorithm and implement in C++. Note that there is several bad techniques here (namely void main and extensive use of comma): I was stuppid then :)
http://pastebin.com/Hr6xEHmd
Hmm...
Do I have to use <iomanip> ? I'm not allowed to use any other one than the ones mentioned in my first post.
I have to make a function of it and place it above int main().
I have this so far, but I get three errors:
1- 'pos' does not name a type.
2- 'pos' was not declared in this scope.
3- 'setw' was not declared in this scope.

Here's my function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
#include <climits>
#include <string>
using namespace std;

void commentWeg (ifstream& invoer, ofstream& uitvoer)
{    string line;
     int line_number = 0;
     while (getline(invoer, line))
     {     auto pos = line.find("//");
           if (pos != string::npos)
           {  line = line.substr(0, pos);
           }
           cout << setw(2) << ++line_number <<". " << line << '\n';
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
//#include <climits>
#include <string>
using namespace std;

void commentWeg (ifstream& invoer, ofstream& uitvoer)
{    string line;
     int line_number = 0;
     while (getline(invoer, line))
     {    // auto pos = line.find("//"); // C++11
           std::size_t pos = line.find("//");
           if (pos != string::npos)
           {  line = line.substr(0, pos);
           }
           // cout << setw(2) << ++line_number <<". " << line << '\n';
           std::cout.width(2) ;
           cout << ++line_number <<". " << line << '\n';
     }
}
Topic archived. No new replies allowed.