ยืนยันชื่อไฟล์ใหม่


19

ที่รันไทม์ให้พร้อมต์บรรทัดอินพุตจนกว่าผู้ใช้อินพุตไม่ใช่ชื่อของไฟล์หรือไดเร็กทอรีที่มีอยู่หรือไอเท็มระบบไฟล์อื่นที่สัมพันธ์กับไดเร็กทอรีการทำงานปัจจุบัน จากนั้นส่งคืน / พิมพ์ชื่อไฟล์ที่ป้อนล่าสุด คุณอาจสมมติว่าอินพุตของผู้ใช้ทั้งหมดจะเป็นชื่อไฟล์ที่ถูกต้อง

รหัสหลอก 1

myform = new form("GUI")
myform.mytxt = new editfield("")
myform.ok = new button("OK")
repeat
  waitfor(myform.ok,"click")
until not filesystem.exists(myform.mytxt.content)
return(myform.mytxt.content)

รหัสหลอก 2

LET TEXT = "."
WHILE HASFILE(TEXT) DO
  TEXT = PROMPT("")
ENDWHILE
RETURN TEXT

ตัวอย่างการป้อนข้อมูลของผู้ใช้ซึ่งจะทำให้เกิดการแจ้งเตือนอีกครั้งเมื่ออยู่ใน TIO

.
..
.env.tio
/
/bin/[
/lost+found

ตัวอย่างของการป้อนข้อมูลของผู้ใช้ซึ่งจะกลับมาเมื่อ TIO:

...
env.tio
../../bin/]
/lost/found

ฉันค่อนข้างใหม่ในการเขียนโปรแกรมกอล์ฟที่นี่และดูเหมือนจะไม่สามารถหาข้อมูลใด ๆ เกี่ยวกับสิ่งที่นับว่าเป็นวิธีแก้ปัญหา ฉันจำเป็นต้องรวมฟังก์ชั่น main () สำหรับภาษาที่ต้องใช้ในโปรแกรมหรือเป็นส่วนหนึ่งของส่วนหัวหรือไม่? คำสั่งนำเข้าสามารถเป็นส่วนหนึ่งของส่วนหัวใน TIO หรือจำเป็นต้องเป็นส่วนหนึ่งของรหัสและนับเทียบกับจำนวนไบต์หรือไม่ ตัวอย่างเช่นฉันมีวิธีแก้ปัญหานี้: goo.gl/8RWNguแต่ไม่แน่ใจว่าเป็นไบต์หรือไม่
Makotosan

2
@Makotosan ทั้งฟังก์ชั่นและโปรแกรมเต็มรูปแบบนั้นใช้ได้แม้ว่าในกรณีของฟังก์ชั่นที่พวกเขาต้องนำมาใช้ซ้ำ โดยทั่วไปการนำเข้าจะต้องรวมอยู่ในจำนวนไบต์
Martin Ender

คำตอบ:


7

แบตช์ 37 ไบต์

@set/ps=
@if exist %s% %0
@echo %s%

(ด้วยเหตุผลบางอย่างในปัจจุบัน Windows 10 CMD.EXEทำให้ชื่อเรื่องเสียหายเมื่อเรียกใช้งาน%0)


7

Mathematica, 33 28 ไบต์

f:=Input[]/._?FileExistsQ:>f

นี้จะถือว่าสภาพแวดล้อมโน้ตบุ๊ค Mathematica Input[]ของที่เราสามารถสอบถามข้อมูลจากผู้ใช้ด้วย การป้อนข้อมูลของผู้ใช้ควรจะตามตัวอักษรสตริงที่เกิดขึ้นจริงดังนั้นเช่นแทนเพียง"ab/cd.ef" ab/cd.efข้อเสียคืออินพุตสามารถเป็นนิพจน์ Mathematica โดยพลการซึ่งคำนวณสตริงอินพุต

สิ่งนี้จะกำหนดสัญลักษณ์fซึ่งเมื่อทำการประเมินแล้วทำการคำนวณที่ต้องการและประเมินในท้ายที่สุดกับอินพุตผู้ใช้ที่ไม่มีอยู่ครั้งแรก มันคือฟังก์ชั่น nullary ซึ่งเราไม่จำเป็นต้องรวม...[]ถึงเรียกมัน

นอกจากนี้เรายังสามารถบันทึกพวงของไบต์กว่าแบบดั้งเดิมการแสดงออกโดยการใช้รูปแบบของผู้ประกอบการทดแทนIf/.


สิ่งนี้จะล้มเหลวหากผู้ใช้ป้อนข้อมูลในสิ่งเดียวกันสองครั้ง
Lukas Lang

@ Mathe172 จับได้ดีแย่เกินไปแล้วฉันจะต้องไปกับวงที่น่าเบื่อ
Martin Ender

กลับกลายเป็นว่าฉันทำไม่ได้และมันก็ยิ่งสั้นลงไปด้วย :)
Martin Ender

7

Perl 5 -ln , 12 10 ไบต์

-2 ไบต์ขอบคุณ@DomHastings

#!/usr/bin/perl -ln
-e||1/!say

ลองออนไลน์!


1
ฉันคิดว่า-eทำงานได้โดยไม่ต้องระบุ$_อาจจะไม่ทำงานในบางกรณีแม้ว่าฉันจะเดาว่า ...
Dom Hastings

@ DomHastings ควรทำงานในทุกกรณี มีการบันทึกไว้ว่าจะใช้ $ _ เมื่อไม่มีอาร์กิวเมนต์สำหรับ -e
ท่อ

@DomHastings ขอบคุณด้วยเหตุผลบางอย่างที่ฉันคิดว่า-eเป็นข้อยกเว้น แต่แน่นอนว่ามันไม่ใช่
HH Ton Ton

4

Bash, 29

read f
[ -e $f ]&&$0||echo $f


@ Adámฉันไม่แน่ใจว่าทำไมมันไม่ทำงานใน TIO พอที่จะบอกว่าถ้าคุณบันทึกเป็นไฟล์สคริปต์และเรียกใช้มันฉันคิดว่ามันทำงานได้ตามที่คาดไว้
Digital Trauma

1
@ อดัมนี้ทำงานปัญหาที่คุณมีคือว่าโปรแกรมที่กำลังพยายามที่จะเรียกร้อง.code.tioที่มีร่างกายของสคริปต์ แต่ไม่มีข้อมูลเกี่ยวกับวิธีการเรียกใช้งาน ฉันไม่แน่ใจว่ามีวิธีที่ดีในการหลีกเลี่ยง Shebang หรือสคริปต์นี้ต้องอยู่ในเส้นทางของคุณ
FryAmTheEggman

2
คุณจะได้รับรอบทั้งสอง (ที่ค่าใช้จ่ายของทั้งสองไบต์) โดยการเปลี่ยนไป$0 ลองออนไลน์! . เนื่องจากใช้ชื่อพา ธ สัมพัทธ์และเชลล์ปัจจุบัน . $0.
Chris

1
มันคิดว่าอะไร*เป็นอินพุต?
Toby Speight

4

PowerShell 2 (ถึง 6), 35 ไบต์

while(Test-Path($x=Read-Host)){};$x

Read-Hostรออินพุต (หากกำหนดสตริงเป็นพารามิเตอร์ให้ใช้สตริงเป็นพรอมต์) หากอินพุตที่จัดเตรียมไว้เป็นชื่อไฟล์ (หรือชื่อโฟลเดอร์) สำหรับรายการที่มีอยู่Test-Pathจะส่งคืน$trueและบล็อกสิ่งที่ไม่{}ทำงานดำเนินการและจะแจ้งให้ป้อนข้อมูลอีกครั้ง หากTest-Pathส่งคืน$falseเนื่องจากอินพุตไม่ใช่ไฟล์หรือโฟลเดอร์ที่มีอยู่บล็อกที่ไม่ทำอะไรเลยจะไม่ทำงานและจะมีการพิมพ์ชื่ออินพุต


1
ยินดีต้อนรับสู่ PPCG!
Martin Ender

คุณไม่จำเป็นต้องใช้เซมิโคลอนหลัง {} เพื่อบันทึกไบต์
Veskah

@Veskah - ฉันทำใน PS2 และไม่ทำลาย PS3 +
Jeff Zeitlin

โอ้ฉันไม่ดี ไม่ได้ทดสอบใน 2
Veskah

4

C (gcc) , 62 ไบต์

main(){char b[99];while(scanf("%s",b)&&!access(b,0));puts(b);}

ลองออนไลน์!

main(){
    char b[99]; // Declare buffer b
    while (scanf("%s",b)&&!access(b,0));    // Take one line of input, and test if file is accessible (exists)
    puts (b);   // If doesn't exist, loop ends and print file
}

ยินดีต้อนรับสู่ PPCG! คุณสามารถใช้while(gets(b),!access(b,0));เพื่อบันทึก 7 ไบต์
เดนนิส

3

ขี้ขลาด 40 ไบต์

tryfor)io.open(s=io.read())catchprint(s)

ในรูปแบบที่ขี้ขลาดจริงนี่ใช้คำหลักที่ติดอยู่กับแต่ละคนวงเล็บที่ไม่ตรงกันและคำหลักโดยนัย ทำความสะอาดแล้วดูเหมือนว่า:

try{
    while(true){
        s = io.read()
        io.open(s)
    }
}catch(e){
    print(s)
}

ชำรุด

try                                     // Try statement, this one is expected to fail.
   for)                                 // for) is a for loop with no arguments, which is functionally equivilent to a while(true) loop, much like for(;;)
       io.open(                         // Try to open a file relative to the CWD. If this fails to find a file, it will throw an error and escape the try/catch
               s=io.read()              // Read a line from STDIN and store it as s, this will still pass it to the arguments of the call.
                          )
                           catch        // When io.open fails
                                print(s)// Print out the last entered line.

3

Haskell , 76 ไบต์

import System.Directory
f=do x<-getLine;b<-doesPathExist x;last$pure x:[f|b]

ลองออนไลน์!

ส่งคืนIO xโดยที่xชื่ออินพุตของไฟล์ที่ไม่มีอยู่

Ungolfed

import System.Directory

insist = do { file <- getLine;
              exists <- doesPathExist file;
              if exists then insist else pure file }

3

R , 66 51 ไบต์

while((s=readline())%in%list.files(a=T)){};print(s)

-15 ไบต์ขอบคุณ plannapus

เรียกใช้การวนซ้ำไม่สิ้นสุดที่แต่ละรอบซ้ำ

  1. อินพุตของผู้ใช้บรรทัดเดียวถูกเก็บไว้ในตัวแปร s
  2. เราตรวจสอบว่าอินพุตอยู่ในรายการชื่อไฟล์สำหรับไดเรกทอรีทำงานหรือไม่ ( ต้องใช้a=Tตัวเลือกสำหรับlist.files()รับสิ่งต่าง ๆ เช่น..)
  3. หากsอยู่ในรายการนั้นเราไปที่การทำซ้ำครั้งถัดไป sถ้าไม่ได้เราทำลายห่วงและพิมพ์

วิธีการย่อให้สั้นลงเป็นwhile((s=readline())%in%list.files(a=T)){};print(s)อย่างไร
plannapus

@plannapus ความคิดที่ยอดเยี่ยม! Incorporated
duckmayr

ไม่เป็นไร นอกจากนี้ฉันไม่ได้คิดทันที แต่มีฟังก์ชั่นlist.filesและdirคำพ้องความหมายดังนั้นคุณสามารถแทนที่ได้ด้วยdirที่นี่
plannapus

คุณสามารถแทนที่readline()ด้วยscan(,'')
JAD

และprintด้วยcat
JAD

3

Python 3 , 55 ไบต์

import glob
s="."
while glob.glob(s):s=input()
print(s)

ลองออนไลน์!

-4 ไบต์ขอบคุณ ManfP
-6 ไบต์ขอบคุณ Rick Rongen


2
@ Adámการตีความที่แย่มากขอโทษ
HyperNeutrino

คุณสามารถแทนที่อันแรกinput()ด้วย"."
ManfP

1
import osและos.path.existsสั้นลงสามไบต์
Jonathan Allan

1
Rick Rongenแนะนำimport globและwhile glob.glob(s):...อยู่ในการแก้ไข
Martin Ender

@ มาร์ตินเอนเดอร์ขอบคุณที่บอกฉัน :)
HyperNeutrino

3

C #, 101 ไบต์

()=>{var s="";try{for(;;System.IO.File.GetAttributes(s=System.Console.ReadLine()));}catch{}return s;}

สำหรับแต่ละค่าส่งคืนที่ถูกต้อง 4 ค่า:

Ungolfed

() =>
{
    var s = "";
    try
    {
        for(;; System.IO.File.GetAttributes(s = System.Console.ReadLine()));
    }
    catch {}
    return s;
}

คำอธิบาย

ขึ้นอยู่กับความจริงที่ว่า File.GetAttributes () จะแสดงข้อยกเว้นหากวัตถุระบบไฟล์ที่ระบุในอาร์กิวเมนต์ไม่มีอยู่


2

Powershell 3.0, 75 ไบต์

$x=1;while($x){$i=Read-Host;$x=Test-Path("$PSScriptRoot\$i")};Write-Host $i

ความพยายามครั้งแรก; ฉันแน่ใจว่ามีการเพิ่มประสิทธิภาพบางอย่างที่ฉันสามารถทำได้

แบบฟอร์มที่อ่านง่ายขึ้นเล็กน้อย:

$x=1;                                                                       # Make sure we enter our while loop.
     while($x){                                                             # While we keep getting file names,                   
               $i=Read-Host;                                                # Get input from the user
                            $x=Test-Path("$PSScriptRoot\$i")};              # Combine our path with the user input, and see if it already exists.
                                                              Write-Host $i # Return the final (valid) file name.

มันจะไม่ทำงานได้โดยไม่ต้อง$PSScriptRoot\?
อดัม

ยินดีต้อนรับสู่ PPCG! Golfs รวดเร็วไม่กี่ - คุณสามารถใช้ห่วงแทนซึ่งช่วยให้คุณสามารถเลื่อนการเริ่มต้นลงในตัวสร้างห่วงfor for($x=1;$x){...}ประการที่สองคุณสามารถกำจัดได้Write-Hostเนื่องจากมีข้อ จำกัดWrite-Outputในการทำโปรแกรมสำหรับสิ่งที่เหลืออยู่ในไพพ์ไลน์ดังนั้นเพียงแค่ออกจากที่$iนั่นจะพอเพียง
AdmBorkBork

ดูโซลูชันของฉันด้านล่าง; ฉันลดจำนวนไบต์ของคุณลงครึ่งหนึ่งแล้ว
Jeff Zeitlin

@ Adám: อาจจะ! ฉันไม่ได้คิดอย่างนั้น : P AdmBorkBork ขอขอบคุณ! ฉันใช้เวลานานในการหลบซ่อน นั่นเป็นความคิดที่ดี การส่งออกโดยปริยายไม่ได้ข้ามใจของฉัน ...
Arkitekt

2

Java 9, 87 ไบต์

v->{String s;for(;new java.io.File(s=System.console().readLine()).exists(););return s;}

Ungolfed

เห็นได้ชัดว่า JVM ของ TIO ไม่มีระบบConsoleดังนั้นจึงไม่สามารถทดสอบได้ (ดูSystem.console())

import java.util.function.*;
class Main {
  public static void main(String[] args) {
    Function<Void,String> f =


v->{
  String s;
  for(;new java.io.File(s=System.console().readLine()).exists(););
  return s;
}


;
    System.out.println(f.apply(null));
  }
}

2

JavaScript (Node.js) , 158 118 ไบต์

require('readline').createInterface({input:process.stdin}).on('line',s=>require('fs').existsSync(s)||--console.log(s))

ลองออนไลน์!

ขอมอบเครดิตให้แก่ @ ConorO'Brien สำหรับรุ่นที่สั้นกว่า วัตถุที่ถูกแทรกแทนการใช้ const และการใช้เงื่อนไขการออกจากข้อผิดพลาดแทนที่จะออกอย่างชัดเจน


1
คำตอบที่ดีจนถึงตอนนี้ แต่มีที่ว่างสำหรับศักยภาพ คุณสามารถเล่นกอล์ฟวิธีนี้ได้สองสามวิธี: คุณสามารถละทั้งสองconstอย่างและคุณยังสามารถแทนที่แต่ละตัวแปรด้วยคำจำกัดความของมัน จากนั้นแทนการใช้คุณสามารถใช้s=>{if(...){...}} นอกจากนี้คุณสามารถออกจากที่มีข้อผิดพลาดเพื่อให้คุณสามารถเขียนแลมบ์ดาเป็นs=>require('fs').existsSync(s)||process.exit(console.log(s)) ลองออนไลน์! s=>require('fs').existsSync(s)||--console.log(s)
Conor O'Brien

ความคิดที่ยอดเยี่ยม! ขอบคุณ!
Makotosan


1

Perl 6, 39 ไบต์

my$f=".";while $f.IO.e {$f=get};say $f;

ใช้งานได้ใน REPL แต่ดูเหมือนว่าจะทำงานไม่ถูกต้องใน TIO


แล้วประมาณsay first !*.IO.e,lines23 ไบต์ล่ะ
nwellnhof

ข้างต้นอาจบล็อกไปเรื่อย ๆ เมื่อทำงานบนบรรทัดคำสั่ง แต่สิ่งที่ชอบ{}while ($_=get).IO.e;.sayควรจะทำงาน
nwellnhof

1

PHP, 43 ไบต์

<?for(;file_exists($f=readline()););echo$f;

ทำงานเป็น CLI ค่อนข้างเข้าใจง่าย






1

ต่ำสุด , 38 ไบต์

"." :a (a exists?) ("" ask @a) while a

ออกจากชื่อไฟล์ที่ป้อนล่าสุดในสแต็ก

คำอธิบาย

"."         ; Put . on the stack. Every directory should contain this...
:a          ; Assign to a
(a exists?) ; A quot that checks if a exists in current directory
("" ask @a) ; Read line from stdin, assign to a
while       ; Do the second quote while the first leaves true on the stack
a           ; Leave a on the stack

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.