To musi być powszechne pytanie, które od czasu do czasu mają wszyscy programiści. Jak odczytać wiersz z pliku tekstowego? Wtedy następne pytanie zawsze brzmi: jak to odpisać.
Oczywiście większość z was korzysta z wysokiego poziomu frameworka w codziennym programowaniu (które są dobre w odpowiedziach), ale czasami miło jest wiedzieć, jak to zrobić na niskim poziomie.
Ja wiem, jak to zrobić w C
, C++
a Objective-C
, ale na pewno będzie przydatna, aby zobaczyć jak to się robi we wszystkich popularnych językach, jeśli tylko pomoże nam uczynić lepszą decyzję o tym, co język robić nasz plik IO w. W szczególności Myślę, że to będzie interesujące zobaczyć, jak jej dokonać w ciągu językach manipulacyjnych, takich jak: python
, ruby
i oczywiście perl
.
Więc myślę, że możemy tutaj stworzyć zasób społeczności , do którego wszyscy możemy oznaczyć nasze profile jako gwiazdkę i odwołać się, gdy musimy wykonać operacje we / wy pliku w jakimś nowym języku. Nie wspominając już o znajomości języków, z którymi nie mamy do czynienia na co dzień.
Oto, jak musisz odpowiedzieć:
- Utwórz nowy plik tekstowy o nazwie „ fileio.txt ”
- Wpisz pierwszą linię „hello” do pliku tekstowego.
- Dołącz drugą linię „world” do pliku tekstowego.
- Wczytaj drugą linię „world” do ciągu wejściowego.
- Wydrukuj ciąg wejściowy do konsoli.
Wyjaśnienie:
- Powinieneś pokazać, jak to zrobić, tylko w jednym języku programowania na odpowiedź.
- Załóżmy, że plik tekstowy nie istnieje wcześniej
- Nie musisz ponownie otwierać pliku tekstowego po wpisaniu pierwszego wiersza
Brak ograniczeń dotyczących języka.
C
, C++
, C#
, Java
, Objective-C
Są świetne.
Jeśli wiesz, jak to zrobić w Prolog
, Haskell
, Fortran
, Lisp
, czy Basic
to proszę śmiało.
źródło
Odpowiedzi:
Python 3
Wyjaśnienia
readlines () zwraca listę wszystkich wierszy w pliku. Dlatego wywołanie readlines () powoduje wczytanie każdego wiersza pliku. W tym konkretnym przypadku dobrze jest użyć readlines (), ponieważ i tak musimy przeczytać cały plik (chcemy jego ostatniej linii). Ale jeśli nasz plik zawiera wiele wierszy, a chcemy po prostu wydrukować jego n-ty wiersz, nie ma potrzeby czytania całego pliku. Oto kilka lepszych sposobów na pobranie n-tej linii pliku w Pythonie: Co zastępuje xreadlines () w Pythonie 3? .
O co chodzi z tym stwierdzeniem? Instrukcja with uruchamia blok kodu, w którym można użyć zmiennej f jako obiektu strumienia zwróconego przez wywołanie metody open (). Kiedy kończy się blok with, Python automatycznie wywołuje f.close (). Gwarantuje to, że plik zostanie zamknięty, gdy wyjdziesz z bloku with, bez względu na to, jak lub kiedy wyjdziesz z bloku (nawet jeśli wyjdziesz z niego przez nieobsługiwany wyjątek). Możesz jawnie wywołać f.close (), ale co się stanie, jeśli twój kod zgłosi wyjątek i nie dostaniesz się do wywołania f.close ()? Dlatego przydatne jest wyrażenie with.
Nie musisz ponownie otwierać pliku przed każdą operacją. Możesz napisać cały kod wewnątrz jednego z blokiem.
Użyłem trzech z blokami, aby podkreślić różnicę między trzema operacjami: zapis (tryb 'w'), dołączenie (tryb 'a'), odczyt (tryb 'r', domyślny).
źródło
readlines()[1]
w przykładowym kodzie. W tym przypadku możesz wiedzieć, że plik ma tylko dwie linie, ale ktoś inny beztrosko zakładając, że jest to dobre rozwiązanie, może wypróbować go na pliku zawierającym milion wierszy i otrzymać raczej nieprzyjemną niespodziankę.readlines()
zwraca iterator (nie listę) Tylko uwaga: zazwyczaj nie możesz zindeksować iteratora.range
Obiekt ma specjalną obsługę indeksowania, co jest wykonywane w O (1).LOLCODE
Specyfikacje są co najmniej pobieżne, ale zrobiłem, co mogłem. Niech rozpocznie się głosowanie w dół! :) Nadal uważam to za zabawne ćwiczenie.
źródło
Mózg *** k
źródło
COBOL
Ponieważ nikt inny tego nie zrobił ......
źródło
Haskell
Jeśli chcesz tylko czytać / zapisywać plik:
źródło
IO a
, który ma specjalne wsparcie kompilatora dla efektów ubocznych. (Czystość jest zachowana w innym miejscu, ponieważ wszystko, co wywołuje lub obserwuje efekt uboczny, jest typuIO a
, więc system typów zapewnia, że reszta programu pozostanie czysta.)IO
jest to monada, ale nie dlatego wolno robić efekty uboczne. Bycie monadą jest tym, co pozwala napisać tę imperatywną składnię: zapewnia również (również przy obsłudze języków specjalnych) efekty uboczne występujące w rozsądnej kolejności, więc nie czyta się z pliku przed zapisaniem, itp. .re
źródło
Rubin
źródło
File.open
z blokiem plik jest otwierany, przekazywany do bloku, a następnie automatycznie zamykany.DO#
File.ReadLines(path).ElementAt(1)
to tylko .Net 4.0, alternatywą jestFile.ReadAllLines(path)[1]
parsowanie całego pliku w tablicę.źródło
ANSI C
źródło
Skrypt powłoki (UNIX)
Właściwie
sed -n "2p"
część drukuje drugą linię, ale pytanie prosi o zapisanie drugiej linii w zmiennej, a następnie wydrukowanie, więc ... :)źródło
sed
), tutaj: stackoverflow.com/questions/3538156/ ...LINE=`foo`
przechwytuje dane wyjściowefoo
do zmiennejLINE
.x86 Assembler (NASM) w systemie Linux
Nie tknąłem asm od 7 lat, więc musiałem trochę użyć google, żeby to razem zhakować, ale nadal działa;) Wiem, że to nie jest w 100% poprawne, ale hej: D
OK, to nie działa. przepraszam za to. chociaż drukuje
world
na końcu, nie drukuje go z pliku, ale z tego,ecx
który jest ustawiony w linii 27.Wykorzystane źródła: http://www.cin.ufpe.br/~if817/arquivos/asmtut/quickstart.html
http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html
http://www.digilife.be/quickreferences/QRC/LINUX%20System%20Call%20Quick%20Reference.pdf
źródło
JavaScript - node.js
Po pierwsze, wiele zagnieżdżonych wywołań zwrotnych.
Trochę czystsze:
źródło
node.js
platformy. Zobacz nodejs.orgCommon Lisp
źródło
PowerShell
źródło
gc
zamiast zamiastcat
ma sens :-)get-alias
dał micat
pierwszy (nie używam dużo PowerShell).Skrypt powłoki
Oto skrypt powłoki używający tylko poleceń wbudowanych, zamiast wywoływać polecenia zewnętrzne, takie jak
sed
lubtail
tak, jak robiły to poprzednie odpowiedzi.Podczas pisania znaczących skryptów powłoki zaleca się używanie w jak największym stopniu wbudowanych, ponieważ tworzenie oddzielnego procesu może być powolne; z szybkiego testu na moim komputerze,
sed
rozwiązanie jest około 20 razy wolniejsze niż przy użyciuread
. Jeśli zamierzasz zadzwonićsed
raz, jak w tym przypadku, nie ma to większego znaczenia, ponieważ wykona to szybciej, niż możesz to zauważyć, ale jeśli zamierzasz wykonać to setki lub tysiące razy, może zsumować.Dla tych, którzy nie są zaznajomieni ze składnią
{
i}
wykonują listę poleceń w bieżącym środowisku powłoki (w przeciwieństwie do(
i)
które tworzą podpowłokę; musimy działać w bieżącym środowisku powłoki, abyśmy mogli później użyć wartości zmiennej) . Musimy pogrupować polecenia razem, aby oba działały na tym samym strumieniu wejściowym, utworzonym przez przekierowanie zfileio.txt
; gdybyśmy po prostu uruchomiliread < fileio.txt; read input < fileio.txt
, otrzymalibyśmy po prostu pierwszą linię, ponieważ plik zostałby zamknięty i ponownie otwarty między dwoma poleceniami. Ze względu na specyfikę składni powłoki ({
i}
są to słowa zastrzeżone, w przeciwieństwie do metaznaków), musimy oddzielić{
i}
od pozostałych poleceń spacjami i zakończ listę poleceń za pomocą;
.read
Wbudowane bierze jako argument nazwy zmiennych do odczytu w. Zużywa wiersz danych wejściowych, dzieli dane wejściowe na białe znaki (technicznie rzecz biorąc, dzieli je zgodnie z zawartością$IFS
, która domyślnie jest znakiem spacji, gdzie znak spacji oznacza podzielenie go na dowolną spację, tabulator lub nową linię), przypisuje każde słowo do nazw zmiennych podanych w kolejności, a pozostałą część wiersza przypisuje ostatniej zmiennej. Ponieważ dostarczamy tylko jedną zmienną, po prostu umieszcza cały wiersz w tej zmiennej. Używamy tej$input
zmiennej ponownie , ponieważ nie obchodzi nas, co znajduje się w pierwszym wierszu (jeśli używamy Bash, nie możemy po prostu podać nazwy zmiennej, ale aby była przenośna, zawsze musisz podać co najmniej jedną nazwę).Zauważ, że chociaż możesz czytać wiersze pojedynczo, tak jak ja tutaj, znacznie bardziej powszechnym wzorcem byłoby zawinięcie go w pętlę while:
źródło
Clojure
Lub równoważnie, używając makra wątków
->
(znanego również jako narzędzie do usuwania nawiasów):źródło
spit
to naprawdę nazwa funkcji zapisu do pliku?FA#
źródło
PODSTAWOWY
Nie używałem BASICa od prawie 10 lat, ale to pytanie dało mi powód do szybkiego odświeżenia wiedzy. :)
źródło
Cel C
źródło
Perl
źródło
perl -we 'for (q{ps aux |}){ open _; print <_>; }'
R:
źródło
PHP
źródło
?>
Jawa
źródło
C ++
lub nieco mniej pedantycznie,
źródło
<limits>
aby powiedzieć,ignore
że nie ma ograniczeń co do rozmiaru linii.Udać się
źródło
os.O_RDWR | os.O_CREATE, 0666
śmieci są nawet potrzebne do podstawowego wejścia / wyjścia plików w Go?Erlang
Chyba nie najbardziej idiomatyczny Erlang, ale:
źródło
Emacs Lisp
Pomimo tego, co niektórzy mówią, Emacs jest głównie edytorem tekstu [1]. Więc chociaż Emacs Lisp może być używany do rozwiązywania wszelkiego rodzaju problemów, jest on zoptymalizowany pod kątem potrzeb edytora tekstu. Ponieważ edytory tekstu (oczywiście) mają dość specyficzne potrzeby, jeśli chodzi o sposób obsługi plików, wpływa to na to, jakie funkcje związane z plikami oferuje Emacs Lisp.
Zasadniczo oznacza to, że Emacs Lisp nie oferuje funkcji do otwierania pliku jako strumienia i czytania go część po części. Podobnie nie możesz dołączyć do pliku bez uprzedniego załadowania całego pliku. Zamiast tego plik jest w całości [2] wczytywany do bufora [3], edytowany i ponownie zapisywany do pliku.
Do zadań typu „must” użyłbyś Emacs Lisp, ponieważ jest to odpowiednie, a jeśli chcesz zrobić coś, co nie wymaga edycji, możesz użyć tych samych funkcji.
Jeśli chcesz ciągle dołączać do pliku, wiąże się to z ogromnym narzutem, ale jest to możliwe, jak pokazano tutaj. W praktyce zwykle kończysz wprowadzanie zmian w buforze, ręcznie lub programowo, przed zapisaniem do pliku (po prostu połącz pierwsze dwa wyrażenia s w poniższym przykładzie).
[1] Przynajmniej nie posunąłbym się do nazywania go systemem operacyjnym; alternatywny interfejs użytkownika tak, system operacyjny nie.
[2] Możesz załadować tylko części pliku, ale można to określić tylko bajtowo.
[3] Bufor jest zarówno typem danych w pewnym sensie podobnym do łańcucha, jak i „rzeczą, którą widzisz podczas edycji pliku”. Podczas edycji bufor jest wyświetlany w oknie, ale bufory niekoniecznie muszą być widoczne dla użytkownika.
Edycja: Jeśli chcesz zobaczyć tekst wstawiany do bufora, musisz oczywiście uczynić go widocznym i spać między akcjami. Ponieważ Emacs normalnie wyświetla ponownie ekran tylko podczas oczekiwania na wejście użytkownika (a spanie to nie to samo, co oczekiwanie na wejście), musisz także wymusić ponowne wyświetlenie. Jest to konieczne w tym przykładzie (użyj go zamiast drugiego seksu); w praktyce ani razu nie musiałem używać `` redisplay '' - więc tak, to jest brzydkie, ale ...
źródło
Pliki wsadowe systemu Windows - wersja nr 2
Aby wyjaśnić to ostatnie okropne wyszukiwanie pętli, zakłada się, że w pliku jest tylko świat hello (nowa linia). Więc po prostu pomija pierwszą linię i odbija tylko drugą.
Changelog
2 - Ups, musiałem źle odczytać wymagania lub zmieniły się na mnie. Teraz czyta ostatnią linię z pliku
źródło
Scala:
Korzystanie z biblioteki standardowej:
Korzystanie z biblioteki Scala-ARM Josha Sueretha :
Ponieważ wiele osób używa tego samego deskryptora pliku do zapisania dwóch ciągów, uwzględniam to również w mojej odpowiedzi.
Korzystanie z biblioteki standardowej:
Korzystanie z biblioteki Scala-ARM Josha Sueretha :
źródło
getLines().toList()
powinien byćgetLines().toSeq
leniwy?Groovy
źródło