How to Get the Current Line Number

How do I get the current line number?

In .NET 4.5 / C# 5, you can get the compiler to do this work for you, by writing a utility method that uses the new caller attributes:

using System.Runtime.CompilerServices;

static void SomeMethodSomewhere()
{
ShowMessage("Boo");
}
...
static void ShowMessage(string message,
[CallerLineNumber] int lineNumber = 0,
[CallerMemberName] string caller = null)
{
MessageBox.Show(message + " at line " + lineNumber + " (" + caller + ")");
}

This will display, for example:

Boo at line 39 (SomeMethodSomewhere)

There's also [CallerFilePath] which tells you the path of the original code file.

Getting the current row number?

The answer was given by @ZyX in a comment to another answer:

You have <C-r> in insert mode for this kind of things:

nnoremap <F1> i<C-r>=line('.')+1<CR><Esc>

Dynamically get the current line number

I was able to use the Thread.currentThread().getStackTrace() method to create a set of functions that work together to produce the line number of the code that called the first method, like so:

/** @return The line number of the code that ran this method
* @author Brian_Entei */
public static int getLineNumber() {
return ___8drrd3148796d_Xaf();
}

/** This methods name is ridiculous on purpose to prevent any other method
* names in the stack trace from potentially matching this one.
*
* @return The line number of the code that called the method that called
* this method(Should only be called by getLineNumber()).
* @author Brian_Entei */
private static int ___8drrd3148796d_Xaf() {
boolean thisOne = false;
int thisOneCountDown = 1;
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for(StackTraceElement element : elements) {
String methodName = element.getMethodName();
int lineNum = element.getLineNumber();
if(thisOne && (thisOneCountDown == 0)) {
return lineNum;
} else if(thisOne) {
thisOneCountDown--;
}
if(methodName.equals("___8drrd3148796d_Xaf")) {
thisOne = true;
}
}
return -1;
}

Hope this helps! I put these in a utility class so that they are out of the way, but still easily accessible. The second method is private to prevent any other method other than the first method from calling it so that it always works correctly.

Is there a way to find the line number of the current line being read from a file?

1)Is there a way in C that we could find the line number of a line that we are reading from a file.

Not unless you count the lines from the beginning of the file. You can't just position yourself arbitrarily in a file and know what line of text you're on, unless there is information in the file itself telling you, or you have created an index of sorts by a previous pass over the file. The usual approach is to accumulate a line count as you process lines from the file.

2)I would also like to know if there is another way to find out the total number of lines in a file other than by creating a loop which looks for EOF in each line until it reaches the end.

No. You must run through the whole the file and count the number of lines. Any external tools (such as wc) are doing exactly this. You need to be aware of different line-ending styles. Depending on what functions you are using to read the file, you may or may not have automatic newline translation.

Print current line number in intellij

One way to do this is to get the stack trace element and call getLineNumber.

public static int getCurrentLineNumber() {
return Thread.currentThread().getStackTrace()[2].getLineNumber();
}

Note that I used an index of 2 because that refers to the frame of the method that calls getCurrentLineNumber. If you are just doing this inline, i.e. like this:

System.out.println(Thread.currentThread().getStackTrace()[1].getLineNumber());

You should use an index of 1 instead.

Note that an index of 0 refers to the frame of the getStackTrace method.

Get current line number from bufferedReader

Very simple: you keep track yourself.

    String line;
int currentLine = 0;

while ((line = bufferedReader.readLine()) != null) {
String[] numbers = line.split(" ");

System.out.println("Linenumber " + currentLine);
System.out.println(numbers[0]);
System.out.println(line);
currentLine ++;
}
reader.close();

How to get the current line number?

There is always way...

I found not the perfect solution, but a good workaround I can use.

I call a function which searches the own batch file(%~f0) with findStr, for the function parameter <uniqueID>, so this works only if these <uniqueID>'s are really unique for the whole batch.

The linenumber is get from the result of findstr /N.

In this sample:

6: call :getLineNumber errLine uniqueID4711 -2

The third parameter -2 is used to add an offset to the linenumber, so the result will be 4.

@echo off
SETLOCAL EnableDelayedExpansion

dir ... > nul 2> nul
if %errorlevel% NEQ 0 (
call :getLineNumber errLine uniqueID4711 -2
echo ERROR: in line !errLine!
)

set /a n=0xGH 2> nul
if %errorlevel% NEQ 0 (
call :getLineNumber errLine uniqueID4712 -2
echo ERROR: in line !errLine!
)
goto :eof

:::::::::::::::::::::::::::::::::::::::::::::
:GetLineNumber <resultVar> <uniqueID> [LineOffset]
:: Detects the line number of the caller, the uniqueID have to be unique in the batch file
:: The lineno is return in the variable <resultVar> add with the [LineOffset]
SETLOCAL
for /F " usebackq tokens=1 delims=:" %%L IN (`findstr /N "%~2" "%~f0"`) DO set /a lineNr=%~3 + %%L
(
ENDLOCAL
set "%~1=%LineNr%"
goto :eof
)

How to get the current line number in a multi-line list initializer of testcases?

Edit This answer is now wrapped in a CPAN module (GitHub)!


@zdim's answer got me thinking about fluent interfaces. Below are two hacks that work for my particular use case, but that don't help me understand the behaviour reported in the question. If you can help, please post another answer!

Hack 2 (newer) (the one now on CPAN)

I think this one is very close to minimal. In perl, you can call a subroutine through a reference with $ref->(), and you can leave out the second and subsequent -> in a chain of arrows. That means, for example, that you can do:

my $foo; $foo=sub { say shift; return $foo; };
$foo->(1)
(2)
(3);

Looks good, right? So here's the MCVE:

#!perl
use strict; use warnings; use 5.010;

package FluentAutoIncList2 {
sub new { # call as $class->new(__LINE__); each element is one line
my $class = shift;
my $self = bless {lnum => shift // 0, arr => []}, $class;

# Make a loader that adds an item and returns itself --- not $self
$self->{loader} = sub { $self->L(@_); return $self->{loader} };

return $self;
}
sub size { return scalar @{ shift->{arr} }; }
sub last { return shift->size-1; } # $#

sub load { goto &{ shift->{loader} } } # kick off loading

sub L { # Push a new record with the next line number on the front
my $self = shift;
push @{ $self->{arr} }, [++$self->{lnum}, @_];
return $self;
} #L

sub add { # just add it
my $self = shift;
++$self->{lnum}; # keep it consistent
push @{ $self->{arr} }, [@_];
return $self;
} #add

} #FluentAutoIncList2

# List of [line number, item index, expected line number, type]
my $testcases = FluentAutoIncList2->new(__LINE__) # line 28
->add(__LINE__,0,36,'LINE')
->add(__LINE__,1,37,'LINE');
$testcases->load(2,38,'load')-> # <== Only need two arrows.
(3,39,'chain load') # <== After that, () are enough.
(4,40,'chain load')
(5,41,'chain load')
(6,42,'chain load')
(7,43,'chain load')
;

foreach my $idx (0..$testcases->last) {
printf "%2d %-10s line %2d expected %2d %s\n",
$idx, $testcases->{arr}->[$idx]->[3],
$testcases->{arr}->[$idx]->[0],
$testcases->{arr}->[$idx]->[2],
($testcases->{arr}->[$idx]->[0] !=
$testcases->{arr}->[$idx]->[2]) && '*';
}

Output:

 0 LINE       line 36 expected 36
1 LINE line 37 expected 37
2 load line 38 expected 38
3 chain load line 39 expected 39
4 chain load line 40 expected 40
5 chain load line 41 expected 41
6 chain load line 42 expected 42
7 chain load line 43 expected 43

All the chain load lines were loaded with zero extra characters compared to the original [x, y] approach. Some overhead, but not much!

Hack 1

Code:

By starting with __LINE__ and assuming a fixed number of lines per call, a counter will do the trick. This could probably be done more cleanly with a tie.

#!perl
use strict; use warnings; use 5.010;

package FluentAutoIncList {
sub new { # call as $class->new(__LINE__); each element is one line
my $class = shift;
return bless {lnum => shift // 0, arr => []}, $class;
}
sub size { return scalar @{ shift->{arr} }; }
sub last { return shift->size-1; } # $#

sub L { # Push a new record with the next line number on the front
my $self = shift;
push @{ $self->{arr} }, [++$self->{lnum}, @_];
return $self;
} #L

sub add { # just add it
my $self = shift;
++$self->{lnum}; # keep it consistent
push @{ $self->{arr} }, [@_];
return $self;
} #add

} #FluentAutoIncList

# List of [line number, item index, expected line number, type]
my $testcases = FluentAutoIncList->new(__LINE__) # line 28
->add(__LINE__,0,29,'LINE')
->add(__LINE__,1,30,'LINE')
->L(2,31,'L()')
->L(3,32,'L()')
->L(4,33,'L()')
;

foreach my $idx (0..$testcases->last) {
printf "%2d %-10s line %2d expected %2d %s\n",
$idx, $testcases->{arr}->[$idx]->[3],
$testcases->{arr}->[$idx]->[0],
$testcases->{arr}->[$idx]->[2],
($testcases->{arr}->[$idx]->[0] !=
$testcases->{arr}->[$idx]->[2]) && '*';
}

Output:

 0 LINE       line 29 expected 29
1 LINE line 30 expected 30
2 L() line 31 expected 31
3 L() line 32 expected 32
4 L() line 33 expected 33


Related Topics



Leave a reply



Submit