编写一段代码以输出print / output语句本身的行号(形式为“ Hello World,从X行开始!”)


25

挑战

编写一个程序,输出Hello World, from line X!,其中X是源代码中实际打印语句本身的行号。

规则

  • 在这种情况下,我们希望将输出字符串的语句的第一行号显示到stdout
  • 您应该避免简单地在源代码中搜索字符串(文件或quine)来查找行号
  • 如果将任何其他空格或语句(不会中断代码流)添加到源代码,则应在运行时(如果适用,在编译之后)反映出来。

推荐建议

如果由语言提供,则可以使用异常/堆栈跟踪来实现此目标。尽力使用跨不同系统/实现移植的代码,但请注意,这不是必需的。__LINE__不鼓励使用定义的变量,例如,尽管规则允许。

赢家

  • 这是一场人气竞赛(于2014年6月10日结束),将根据当时的当前投票来宣布社区投票最高答案

  • 投票时,请考虑某人的答案的创造性,详尽程度或趣味性。以及所使用的编程语言的困难/限制


“第一行号”是什么意思?您是否在说如果语句跨越多行会发生什么?
user2357112支持Monica 2014年

@ user2357112是的,只是为了解决任何歧义,如果有人需要使用milti-line语句。
2014年

标题非常明确,但可能有点长。
primo 2014年

1
答案很无聊,因为这是一个很糟糕的问题。就像问问者不知道LINE的存在一样。实际上,我专门签署了反对票,我认为那太糟糕了。
戴夫2014年

1
@Markasoftware如果在其前面添加了一行,则输出不会更改以反映这一点。
2014年

Answers:


48

辛克莱基本

10 PRINT "Hello world, from line ";PEEK 23621;"!"

世界十号线您好!

PEEK通过在存储当前行号的地址处输入地址,此方法将适用于任何行,因此以下内容也将适用:

341 PRINT "Hello world, from line ";PEEK 23621;"!"

世界,您好,来自341行!


同样,Timex / Sinclair BASIC!
加布2014年

我不假装不懂这种语言,但是STR$如果+用分号代替符号,您是否不能忽略呢?
李斯特先生2014年

@MrLister是的,那肯定可以,但是我总是+习惯使用s。
kitcar2000 2014年

40

基本知识

我认为这可以完成所有要求的工作:

10 PRINT "Hello World, from line 10!"

5
If any additional whitespace or statements (which do not interrupt the flow of the code) is added to the source code, it should be reflected at run-time (after compiling if applicable)。目的就在那里。同样,这是源代码的第一行,而不是第十行。
Bill Woodger 2014年

30
它可能是源代码中的第一行,但仍然是第10行
吱吱作响的ossifrage

13
我相信这将不再属于有趣的范畴。尽管从字面上看它符合要求,但它确实是没有想象力和无趣的。为什么会有这么多的投票?(我已投票)
Tim S.

18
这是一个很好的答案,因为它利用了BASIC语言某个方面的愚蠢但特定的优势,而这是其他语言(尤其是现代语言)中不常见的。它可能不是最受欢迎的(时间会证明一切),但是我几乎看不出它比使用诸如__LINE__这样的常量或从当前堆栈帧中获取调试信息(像当前大多数其他答案一样)有趣。
尼克

2
聪明,但是如果没有其他事情比这次投票更多,我将感到失望。
agweber 2014年

35

爪哇

public class Hello{
    public static void main(String[] args) {
        System.out.println("Hello World, from line "+new Exception().getStackTrace()[0].getLineNumber()+"!");
    }
}

1
我更喜欢Thread.currentThread().getStackTrace()
Cruncher 2014年

3
Thread.getStackTrace()如果在当前线程上被调用,则调用(new Exception())。getStackTrace(),所以这是同一件事
DHall 2014年

1
很奇怪...。2x相同的答案和2不同的upvote数量...(可以用作RNG源...)(相同的位置:codegolf.stackexchange.com/a/30058/10801
masterX244 2014年

@ masterX244这两个答案并不完全相同;这一getLineNumber()方法使用了堆栈跟踪中的方法,而您链接到的答案则使用toString()它来查找行号。
突破

9
@ masterX244还值得注意的是,此答​​案早于2小时出现。第二次我看到一个答案,却没有第一次有趣。
2014年

30

佩尔

close STDERR;
open FOOBAR,">",\$_;


print!warn,'Hello World, from line ',/(\d+)\.$/,'!';

不像using那样短__LINE__,但是也许更有趣。

warn是一种调试工具,它向发出语句STDERR,指示在哪个文件以及在哪一行上发出了警告... 除非 STDERR先前已关闭或无法访问,否则将对最近打开的文件发出警告处理-这是未记录的行为。我不确定将其归类为功能还是错误。

在这里,STDERR被关闭,标识为的新文件句柄FOOBAR被打开,并被路由到变量$_。然后对其进行解析以检索警告的行号,该行号嵌入在print语句中。


3
是的,它绝对更有趣:)
2014年

27

C ++

#include <iostream>
#include <utility>
#include <type_traits>

#define __(A,B,C,...) B##C##A
#define _(A,...) __(__VA_ARGS__, A)
template<unsigned...Is> struct v;
template<unsigned I0, unsigned... Is> struct v<I0, Is...>:v<I0-1,I0-1, Is...> {};
template<unsigned...Is> struct v<0,Is...>:std::integral_constant<unsigned, sizeof...(Is)> {};

int main() {
  std::cout << "Hello world from line " << v<_(EXTRACT,_(Q,_,E,_,$$main$$,),_(@22,,_,_),_(Z,N,L,I,_,,L),__STACK_TRACE__)>::value << "\n";
}

现场例子


2
这是……巫术
Paladine

1
我花了很长时间才知道它是如何工作的。红鲱鱼太多了!这很美味。
sehe 2014年

1
那么它是怎样工作的?
0x499602D2 2015年

16

a

print("Hello world, from line "..debug.getinfo(1).currentline.."!")

16

C#

C#5.0 [CallerLineNumber]可以解决问题:

using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace LineNumberConsole
{
    class Program
    {
        public static void Main()
        {
            Console.WriteLine("Hello World, from line {0}!", ToRoman(GetLineNumber()));
            Console.ReadLine();
        }

        private static int GetLineNumber([CallerLineNumber] int sourceLineNumber = 0)
        {
            return sourceLineNumber;
        }

        private static string ToRoman(int number)
        {
            // TODO: Copy some source code from http://pastebin.com/w0hm9n5W
            // Skipped here for brevity
            return number.ToString();
        }
    }
}

输出量

Hello World, from line X!

使用罗马数字有任何特殊原因吗?
科尔·约翰逊

4
当打印行是第10行时,将按字面解释该问题。X罗马数字是10
2011年

罗马数字很不错!
NPSF3000 2014年

15

C

#include <stdio.h>
main(){
printf("Hello World, from line %d!", __LINE__);
}

不鼓励使用诸如LINE之类的已定义变量,尽管规则允许这样做。
vaxquis 2014年

@vaxquis,是的,但是我的答案早于对问题进行编辑的
gnibbler 2014年

IMO 仍然是一个糟糕且过于明显的解决方案。我想知道为什么人们在世界上所有语言(包括PHP,D,Perl)上发布此解决方案的各种变体,而不是尝试做些有趣或有趣的事情?
vaxquis 2014年

14

蟒蛇

示例(10行,213个字符):

import sys
import traceback
lineno = None
while True:
    try:
        print 'Hello World, from line %d!' % lineno
        break
    except:
        lineno = traceback.tb_lineno(sys.exc_info()[2])
        continue

在这里尝试在线。可以添加非流更改代码和空格,程序将显示更新的行数,同样,此代码段也可以在现有程序中的任何位置使用。预期产量:

Hello World, from line 6!

另一个示例(在此处尝试在线)显示添加代码/空格后它可以工作。预期产量:

Down we go...
Gotta catch 'em all.
Down we go...
Hello World, from line 11!
Awesome!

12

Java脚本

function getLine(n) {
   try {
      to
   } catch (dat) {
      var stack = dat.stack.split('\n');
       for (var i = 0; i < stack.length; i++) {
           if (~stack[i].indexOf ('getLine')) break;          
       }
      return dat.stack.split ('\n')[i + ~~n].match (/:(\d+)/)[1] - ~~window.hasOwnProperty ('__commandLineAPI')
   }
}
//Line 12
console.log ('Hello World, from line ' + getLine(1) + ' !')

注意:从chrome开发人员控制台中评估的表达式将包装在一条with语句中。因此,如果是这种情况,我们需要将行减一


2
数据堆栈,呵呵。验证可在Firefox上运行。
突破

1
@Breakthrough :)是的,它可以跨浏览器运行(尽管仅在最新的Chrome,FF,IE中进行了测试)。从控制台进行评估时,Chrome需要特殊处理,因为它会将所有语句包装在一个with子句中。
C5H8NNaO4 2014年

2
有趣但含糊的用户名。谷氨酸钠,也许吗?(顺便说一句,我正在考虑对DNA和氨基酸问一个问题,其中谷氨酸是其中之一。)
Level River St

@steveverrill据谷歌,你是正确的
kitcar2000 2014年

@ kitcar2000可能是。但是,还有其他一些鲜为人知的化合物,例如:天冬氨酸甲酯钠或硝基戊酸酯。
级圣河

11

Python 3

import hashlib
with open(__file__) as f:
    line_num = 0
    for line in f.readlines():
        line = line.rstrip() # make it work with or without newline at the end
        line_num += 1
        if hashlib.sha256(bytes(line, "UTF-8")).hexdigest()[0:6] == 'cc46f7':
            print('Hello world, from line {}!'.format(line_num)) # cc46f7

世界八号线您好!

此自读代码包含一个自引用哈希。最后一行的SHA256和(以开始的空白而没有尾随的空白)开头 cc46f7...。当对print行进行哈希处理时,它会发现哈希值与所搜索的魔术值匹配。


您难道不就将line_num =设置为-1并在循环外打印并获得魔术哈希值吗?
戴夫2014年

1
@dave不确定我是否关注您。神奇的哈希值使此解决方案变得更聪明。
Tim S. 2014年

+1对我的规则进行字面解释:)非常聪明。
2014年

5
@Stefan这个网站是关于最坏做法的。;)
Tim S.

1
@sehe最有可能是由于空白问题。制作文件时,文件末尾没有换行符。在哈希之前,我添加了一行以从行尾去除空白。现在应该可以更一致地工作了。(还要确保您没有将空格转换为制表符),我尝试将其上载到ideone以向您显示实时版本,但是它无法在其中读取自己的文件。
Tim S.

9

GNU COBOL

好吧,他们说这不可能完成。实际上,是我说无法完成。现在已完成,并使用所应用的方法重新实现了过时的语言功能。

问题指出:

如果将任何其他空格或语句(不会中断代码流)添加到源代码,则应在运行时(如果适用,在编译之后)将其反映出来。

的东西任何量可以前三个插入DISPLAYS的引起输出的开始,和任何DISPLAY s都会“中断代码流”,所以可以。

COBOL曾经有一个TRACE动词(语句),该动词仅在执行时列出源行号(无法访问程序中的行号)。尽管用途有限,但我包含了TRACE的实现。

   ID Division.
   Program-ID. HIWHERE.
   ENVIRONMENT DIVISION.
   configuration section.
          source-computer. TinkerToy with debugging mode.
   Procedure Division.
   Declaratives.
   Debug-Declaratives Section.
       Use For Debugging on a b
       .
   Debug-Declaratives-Paragraph.
       Display Debug-Line "!"
       .
   End Declaratives
       .
   Main-Program Section.
       DISPLAY "Perform"
       Display "Hello World, from line " no advancing Perform b
       display "GO TO"
       Display "Hello World, from line " no advancing GO TO a
       .
   a.
       dISPLay "Fall through"
       Display "Hello World, from line " no advancing. b.
   The-Last-bit-OF-the-PROGRAM.
       GOBACK
       .

输出是

Perform
Hello World, from line     18!
GO TO
Hello World, from line     20!
Fall through
Hello World, from line     23!

为了展示编写语言的能力和灵活性,本示例同时使用了混合大小写,完全小写和完全大写的形式。没关系,因为在处理时,所有内容都“折叠”为大写。

从正在运行的程序中获取正在运行的程序中源行号的唯一标准COBOL方法是使用DEBUGGING DECLARATIVE。在此类声明的a SECTION内(严格在a内的一段内)SECTION,您可以访问特殊寄存器DEBUG-LINE。它包含动词(语句)的源行号,该动词导致将控制权转移到特定的过程名称(段落或SECTION)。

因此,使用PERFORM,或GO TO,或“掉线”将SECTION执行调试声明中的段落。

好的但是 DISPLAY不会导致控制权的转移。

没问题。将其与控制权转移放在同一行

问题在于,如果“将任何其他空格或语句(不会中断代码流)添加到源代码中,则应在运行时(如果适用,在编译之后)将其反映出来”。

因此,将其放在同一行上但在控制权转移之前,将其内容DISPLAY分成两部分(请记住,“在这种情况下,我们希望显示输出字符串的语句的第一行号” )并在控制权转移之前输出第一部分,第二部分则从DEBUG-LINE在调试过程中。

最后一个棘手的地方是“掉线”(可以PERFORM编辑“过程” ,可以是a的目标GO TO,也可以简单地通过下一行输入)。在这种情况下,将放到DISPLAY 定义过程的行上,但在定义的前面

“过程”(ab)的名称已被严格缩短,以使它们可以与放在同一源代码行中DISPLAY。严格来说,COBOL过程名称应从第8列到第11列之间的某个位置开始。但是,如今的语法对此要宽松得多。在某种程度上,我可以在与某些代码相同的行上定义过程名称。甚至嵌入到代码中。需要保养,偶尔需要停止。

在显示的PROCEDURE DIVISION每个句号中,是必需的,不再需要。

编译:

cobc -x -g hiwhere.cbl

要执行(Linux):

COB_SET_DEBUG=Y ./hiwhere

最后,返回TRACE(没有READY / RESET)。

   ID Division.
   Program-ID. tRacE.
   ENVIRONMENT DIVISION.
   configuration section.
          source-computer. TinkerToy with debugging mode.
   Procedure Division.
   Declaratives.
   Debug-Declaratives Section.
       Use For Debugging on a
       .
   Debug-Declaratives-Paragraph.
       Display Debug-Line
       .
   End Declaratives
       .
   Main-Program Section.
  *    Just append "perform a" to a single-line statement.
       DISPLAY "1" . perform a
       Display "2" . perform a
       display "3" . perform a
  *    Or prepend "perform a." for a multi-line statement, or a
  *    statement which won't "come back". 
       perform a. GOBACK
       .
   a.
       CONTINUE
       .

输出为:

1
    17
2
    18
3
    19
    20

其中三个DISPLAY语句输出1、2和3,17、18、19和20是“可执行”(非调试)行的行号。


8

爪哇

使用Exception的堆栈跟踪行为来获取当前行。只要不将Printstatement分成多行,或者将classfile弄乱,它应该可以工作

public class PrittLnbr
{
    public static void main(String[] args)
    {
        System.out.println("Hello World, from line "+new Error().getStackTrace()[0].toString().split(":")[1]+"!");
    }
}



6

爪哇

public class HelloFrom {
    public static void main(String[] args) {
        System.out.println("Hello World, from line " + Thread.currentThread().getStackTrace()[1].getLineNumber() + "!");
    }
}

技术上,像我一样(相同codegolf.stackexchange.com/a/30058/10801
masterX244

2
排序,除了使用当前线程而不是创建新的错误来获取堆栈跟踪。没有任何错误;)
Cineris

6

蟒蛇

import inspect
print ("Hello world from line %d!" % (inspect.getlineno(inspect.currentframe())))

输出量

Hello World from line 2!

1
迄今为止最好的Python之一!
kirbyfan64sos 2014年

6

Befunge

做只是为了好玩。

>00g1+:00p"v"\10v  
    v-*45g00p\g <  
#v+1_$10g1vv,,,,<  
^<p000p01+<#>,,,^  
>" enil morf ,oll"v
@.,,,,,,,,,<^,"He"<

有条件的:代码的左上角必须为0 <x <20和0 <= y <62; 并且前两个单元格必须为空。

例:

                         v                  

                         0                  
                         0                  
                         0                  
                         p                  
                         0                  
                         1                  
                         0                  
                         p                  
                         >00g1+:00p"v"\10v  
                             v-*45g00p\g <  
                         #v+1_$10g1vv,,,,<  
                         ^<p000p01+<#>,,,^  
                         >" enil morf ,oll"v
                         @.,,,,,,,,,<^,"He"<

将输出:

你好,从第10行


不知道这是什么,但我相信您的输出要求,所以+1 ;-)
ysap14年

1
对于那些质疑强大的Befunge的力量的人,请在这里尝试:quirkster.com/iano/js/befunge.html
贾斯汀

6

C

通过使用可变参数宏,我们可以创建一个打印函数,该函数自动将行号添加到任意printf语句的末尾,并始终打印到stdout。

test.c:

#include <stdio.h>

#define printfl(format, ...) fprintf(stdout, format " From line %d\n", ##__VA_ARGS__, __LINE__)

int main() {
    printfl("Hello World! I have %d argument(s).", 1);
    return 0;
}

输出:

% ./test
Hello World! I have 1 argument(s). From line 6

注意:我偏离了模式,以证明printfl仍然是有效的可变参数函数。如果您真的关心输出的格式,则可以随时更改我使用的文字。


仅当您使用恒定格式的字符串时,此方法才有效。如果您为格式字符串传入任何其他表达式,它将失败。
Snowbody 2014年

5

重击

#
# some comments to fill some lines...
#
echo "Hello World, from line $LINENO!"

输出量

Hello World, from line 4!

@professorfish ...显示我的答案的我的风格有什么问题?您至少应该解释一下为什么要操纵我的艺术品... :-P

2
我更改了密码吗?如果我这样做了,对不起。我只是担心非bash用户无法分辨源代码是什么,输出是什么

1
除我以外的其他人都喜欢看到他的东西被改变而没有评论为什么?奇怪的地方

3
它基本上是一个格式修复程序。这些AFAIK并没有真正的问题

不鼓励使用诸如LINE之类的已定义变量,尽管规则允许这样做。
vaxquis 2014年


5

C或C ++和AWK

lineno.c:

// code or comments
// ....
#error Hello World, from line
// other code or comments

用法:

gcc lineno.c 2>&1 | awk '{ split($0,a,":"); ; printf("%s %s!\n", gensub(".*#error ","",1), a[2]); exit; }'

输出:

您好,世界,从3号线

笔记:

  • 没有用户编写的代码搜索该文件。
  • g ++将在c ++文件上工作。

4

在Ruby中有点无聊:

puts "Hello World, from line #{__LINE__}!"

这不是作弊吧?


不,这不是在作弊!这个挑战显然会很多在一些语言更容易,而在其他更困难的,但是,这就是为什么我张贴:)(我现在明白为什么的评分标准中包含如此重要)
突破

不鼓励使用诸如LINE之类的已定义变量,尽管规则允许这样做。
vaxquis 2014年

1
@vaxquis是的,此答案之后添加了该语句。
Ajedi32

4

Java脚本

使用堆栈跟踪的一行。

(function (o) { console.log("Hello World, from line " + (Error.captureStackTrace(o) || o.stack.match(/\d+/)[0] - !!__commandLineAPI) + "!"); })({});

3

眼镜蛇

class Program
    def main
        print 'Hello World, from line [System.Diagnostics.StackFrame(true).getFileLineNumber]!'

3

红宝石

File.write "hello.rb", "x=2\n"+"x+=1\n"*rand(rand(100))+'puts "Hello World, from line #{x}!"'
system "ruby hello.rb"
File.delete "hello.rb"

3

电源外壳

便宜的举动

Function LemmeGetDatError() {
    "Too busy chuggin along"
    "Then all of a sudden, I meet a new programmer"
    "And he's all like"
    Write-Output "$(Try {"Hello World from"; Throw "error" } Catch {$_.ScriptStackTrace.Split(":")[1]})"
}

LemmeGetDatError

3

电源外壳

$l=(Get-PSCallStack | ForEach{$_.Location})[0].split(' ')[-1]; "Hello World, from line $l!"

和:

try{ I AM ERROR. } catch { $l=$error[0].InvocationInfo.ScriptLineNumber; "Hello World, from line $l!" }

两者都是这样的:

PS C:\MyFolder> .\helloworld.ps1
Hello World, from line 1!

+1,但Write-Host不写入标准输出。只需传递字符串即可将其发送到stdout。例如"Hello World, from line {0}!" -f (gcs| %{$_.ScriptLineNumber})[0]
Rynant 2014年

@Rantant好点!我将更新我的答案以考虑...
DarkAjax 2014年

3

蟒蛇

import traceback

print 'Hello World, from line %i!' % traceback.extract_stack()[0][1]

简短而甜美。


3

佩尔

另一个Perl:

use warnings;

$SIG{__WARN__} = sub { ($line = shift) =~ s/\D//g; };

$x=$x+1; print "Hello World, form line $line!\n";
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.