Es scheint ein berühmtes Buch zu sein, also habe ich es gekauft <a target = "_ blank" href = "https://www.amazon.co.jp/gp/product/4797328355/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4797328355&linkCode=as2&tag=lespacetr2f2 > Gewöhnliche Linux-Programmierung Die königliche Straße der gcc-Programmierung, die aus dem Mechanismus von Linux gelernt werden kann <img src = "// ir-jp.amazon-adsystem.com/e/ir?t=lespacetranqu-22&l=am2&o=9&a=4797328355" "width =" 1 "height =" 1 "border =" 0 "alt =" "style =" border: none! Wichtig; Rand: 0px! Wichtig; "/> <a target = "_ blank" href = "https://www.amazon.co.jp/gp/product/B075ST51Y5/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B075ST51Y5&linkCode=as2&a0aaa > Gewöhnliche Linux-Programmierung 2. Ausgabe: Der königliche Weg der gcc-Programmierung, der aus dem Mechanismus von Linux gelernt werden kann <img src = "// ir-jp.amazon-adsystem.com/e/ir?t=lespacetranqu-22&l=am2&o=" 9 & a = B075ST51Y5 "width =" 1 "height =" 1 "border =" 0 "alt =" "style =" border: none! Wichtig; Rand: 0px! Wichtig; "/>
Versuchen Sie es mit normaler Linux-Programmierung Teil 1 https://qiita.com/uturned0/items/b9ae846f2aff5865c074 Versuchen Sie es mit normaler Linux-Programmierung Teil 2 https://qiita.com/uturned0/items/56beac990cdd6f1059ed Versuchen Sie es mit normaler Linux-Programmierung Teil 3 https://qiita.com/uturned0/items/675092da8aa89c4b1ff0 Teil 4 https://qiita.com/uturned0/items/8f5765cfc0f0be8a1981 Teil 5 https://qiita.com/uturned0/items/ab97deb489c994a836da Teil 6 https://qiita.com/uturned0/items/b7df48e87ae9170f3698
chapter 6
Systemaufruf ist sehr langsam. Es ist langsam, es sei denn, Sie lesen es in Einheiten von 1 KB oder mehr. Um es abzudecken stdio = Standard I / O Bibliothek, es war kein Studio!
Sie können eine Zeile anstelle der Byteeinheit lesen
Holen Sie sich Bytes gemeinsam von fd mit read () → stdio-Puffern → Programm gibt 1 Byte, geben Sie nur das zurück Bargeldähnliche Kanji-Abteilung
Schreiben ist das gleiche. Stdio puffert bis zu einem gewissen Grad, und wenn es gesammelt wird, wird es vom Systemaufruf von write () geschrieben
Wenn das Ausgabeziel ein Terminal ist, wird es in Zeilenumbrucheinheiten ausgegeben, und wenn es sich im Entpufferungsmodus "man set vbuf" befindet, wird es sofort ausgegeben. stderr ist immer im Entpufferungsmodus. So schnell.
typedef FILE ist wie die fd ID von stdio. Es gibt einen Puffer im Inneren, aber Sie müssen sich dessen nicht bewusst sein.
fd = 0, STDIN_FILENO, stdin fd = 1, STDOUT_FILENO, stdout fd = 2, STDERR_FILENO, stderr
fopen(3)
Oh offen. Sie können es auch in höheren Sprachen sehen.
NAME
fopen, fdopen, freopen, fmemopen -- stream open functions
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <stdio.h>
FILE *
fopen(const char * restrict path, const char * restrict mode);
Wenn Sie einen Pfad übergeben, wird open () geöffnet und ein Zeiger auf den FILE-Typ zurückgegeben, der ihn verwaltet.
Das zweite Argument ist ungefähr dasselbe wie open ()
Schließen Sie mit fclose ()
Englische Bücher in C-Sprache rufen Bytezeichen auf, aber es gibt ein großes Problem in Mehrbyte-Sprachen. Bytes und Buchstaben sind unterschiedlich. Das war's.
fgetc(3), fputc(3) Wenn der Rückgabewert int oder EOF ist, wird -1 zurückgegeben.
getc(3), putc(3) Dies ist dasselbe wie fgetc, jedoch in Makros geschrieben. Früher war es früh, aber jetzt macht es keinen Unterschied mehr.
Was ist ein Makro? Ich habe es vergessen
define ist eine der Anweisungen an den Präprozessor. Ein Briprozessor ist ein Programm, das vor dem Kompilieren verarbeitet wird. Als Vorverarbeitung zur Kompilierungszeit wird die durch den Makronamen angegebene Zeichenfolge durch eine Konstante oder einen Ausdruck ersetzt. Diese Ersetzung wird als Makroersetzung bezeichnet. Dieser Prozess wird als Makroprozess bezeichnet. Verwenden Sie define, um die Makroverarbeitung zu definieren. https://www.sejuku.net/blog/25927
Es wurde definiert. Mit c-lang können Sie mit define nicht nur Konstanten, sondern auch Funktionen und Variablen deklarieren. Da der Wert vor dem Kompilieren festgelegt wird, ist er wahrscheinlich für umgebungsabhängige Variablen (64 Bit, x86 usw.) nützlich.
ungetc(3) Sie können die gelesenen Bytes an den Stream zurückgeben. Es ist Zeit, nach vorne zu schauen und zu dem Fall zurückzukehren, in dem Sie ihn nicht gebraucht haben.
Wenn Sie die Nummer 1234 + -5678 lesen möchten, lesen Sie bis zu 5 und stellen Sie fest, dass die nächste Nummer begonnen hat. Kehren Sie 5 zum Stream zurück und fahren Sie mit der nächsten Schleife fort. Das war's
code
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int i;
for (i=1; i<argc; i++) {
FILE *f;
int c;
f = fopen(argv[i], "r");
if(!f) {
perror(argv[i]);
exit(1);
}
while ((c = fgetc(f)) != EOF) { //Behalte fgetc, bis du EOF drückst
// if (putchar(c) < 0) exit(1);
putchar(c);
}
fclose(f);
}
exit(0);
}
Lauf
$ gcc -Wall -O2 scat.c && ./a.out test
abc
def
xyz
012
AIUEO
Kakikukeko
(c = fgetc (f))
setzt das Ergebnis von fgetc (f) in c. Als ich es versuchte, war der Zeichencode zurück.
Wenn ich abc \ n setze, sieht es so aus
97a98b99c10
97 ist a und 98 ist b. Diese Zahl wird in Buchstaben umgewandelt ... Wo schreibst du () das? Das?
Ah. Ist putchar (c)
ein write ()? Ich bin in einem bedingten Ausdruck, aber er wird immer ausgeführt. Das war's.
Ich erinnere mich, dass ich in einem solchen Fall einen Mann gemacht habe.
PUTC(3) BSD Library Functions Manual PUTC(3)
NAME
fputc, putc, putc_unlocked, putchar, putchar_unlocked, putw -- output a character or word to a stream
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <stdio.h>
int
fputc(int c, FILE *stream);
Ich schrieb "Ausgabe eines Zeichens oder Wortes in einen Stream".
Es funktioniert ohne Behandlung des Putchar-Fehlers, aber es scheint, dass ein Fehler auftritt, wenn die andere Partei eine Pipe ist. Ich habe es versucht, aber ich konnte keinen Fehler bekommen.
fgets(3)
Ich kann Zeile für Zeile lesen, aber es gibt Blutgefäße. Ich kann nicht sagen, ob ich eine Zeile normal lese oder ob ich in den vollen Puffer geschrieben und gestoppt habe. Die Gegenmaßnahme besteht darin, mit getc () eine eigene zu erstellen. Ich habe nur bis zu 1 Byte gelesen und am Ende '\ 0'geschrieben, also habe ich es nicht sehr gut verstanden.
gets() Verwenden Sie es niemals. Pufferüberlauf.
FGETS(3) BSD Library Functions Manual FGETS(3)
NAME
fgets, gets -- get a line from a stream
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <stdio.h>
char *
fgets(char * restrict str, int size, FILE * restrict stream);
char *
gets(char *str); <---------
Oh, der Titel ist jetzt BSD-Bibliothek. Hallo. gets (char * str)
hat keine Größe angegeben. Mit anderen Worten, es schreibt endlos in das * str
, das ein Zeiger sein kann. Selbst wenn * str 8 Bit ist, wird es nur als Speicheradresse erkannt, sodass (wahrscheinlich) auch das 9. Bit geschrieben wird. Es spielt keine Rolle, welche Daten vorhanden sind. Super gefährlich.
Es gibt Unmengen alter gefährlicher Funktionen. Sie können es nicht verwenden, da es im Handbuch enthalten ist.
fputs(const char *buf, FILE *stream);
Ich gehe nicht und stelle es einfach in den Stream. Nicht symmetrisch zu Fgets. was ist das
#include <error.h>
{
errno = 0;
if (fputs(buf, f) == EOF) {
if (errno != 0) {
//Fehlerbehandlung
}
}
}
Wird errno zurückgegeben, wenn alle Byte-Strings geschrieben wurden? Setzen Sie daher im Voraus "errno = 0" und verwenden Sie "if" (errno! = 0), um festzustellen, ob es sich um einen echten Fehler handelt.
Was ist errno?
errno ist ein global definierter ganzzahliger Wert. Konstanten, die Fehlern entsprechen, sind in errno.h definiert. Es gibt Systemaufrufe und Funktionen, die errno im Fehlerfall auf einen Wert setzen. ... Zu diesem Zeitpunkt ändert sich errno auf keinen Fall auf 0 Durch Zuweisen von 0 zu errno vor der Verarbeitung, Sie können feststellen, ob es sich dabei um einen Fehler handelt. ... Da es nur einen Fehler gibt, kann dieser jederzeit neu geschrieben werden. https://qiita.com/ota42y/items/b2f59d7a82c550648677
Anscheinend sieht es aus wie ein reserviertes c-lang-Wort (definiert in error.h?). Aber ich konnte perror nur mit stdio.h verwenden.
Ich dachte, es wäre in stdio.h enthalten, aber es war nicht so.
https://code.woboq.org/userspace/glibc/libio/stdio.h.html
Es wurde perror importiert.
#include <errno.h>
#include <stdio.h>
https://code.woboq.org/userspace/glibc/stdio-common/perror.c.html
Aber es gibt kein "errno" in "error.h" https://code.woboq.org/userspace/glibc/misc/error.h.html
Ich wusste nicht, wer wie importiert, aber ich fand die Quelle "errno.h"
# define errno (*__errno_location ())
https://code.woboq.org/gcc/include/errno.h.html
Derzeit ist es irgendwo definiert, sodass Sie es verwenden können, ohne es zu deklarieren. Wenn es jedoch nicht mit 0 initialisiert wird, kann es nicht ordnungsgemäß als Fehler identifiziert werden.
c-lang ist das wirklich
int puts(const char +buf);
Das Ausgabeziel ist auf stdout beschränkt, mit \ n am Ende. Wenn Sie jedoch eine Verbindung von fgets () herstellen, ist fgets ebenfalls \ n und der Zeilenumbruch wird verdoppelt. Wirklich das.
printf() Geben Sie die Breite an, indem Sie eine Zahl zwischen% einfügen. 0 Auffüllen, wenn Sie mit% 0 beginnen. % - Wird gerechtfertigt bleiben.
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
printf("%010x\n", 77) ; // 000000004d
printf("%10s\n", "abc") ; // abc
printf("%-10s\n", "abc") ; // abc
exit(0);
}
result
Printf ist praktisch, aber seien Sie vorsichtig, da es gefährlich sein kann, wenn% im Argument enthalten ist. Es ist gefährlich, so etwas wie fgets () auszudrucken, dass Sie nicht wissen, was kommen wird.
Ich benutze scanf () nicht, weil es gefährlich ist
6.5 ~~ Lang ... mir ist das Herz gebrochen. Oh, es ist Arbeitszeit. Ende. ~~
Ich bin betrunken, aber ich glaube, dass ich mich später daran erinnern kann, wenn ich es einzeln schreibe
fread()
Größe x nmemb gelesen Die Anzahl der Mitglieder ist nmemb. Ich fand es MB-ähnlich.
Read () write () und Systemaufrufe sind LINUX-Systemaufrufe. Nur in der UNIX-Welt. Da fread () die Welt von C-lang ist, funktioniert es in anderen Welten. Hallo.
6.6 Derzeit läuft Linux auf einem 32-Bit-Computer. Hey, wie alt ist dieses Buch! !! !!
Wenn Sie es so lange deklarieren, sind die 32-Bit- und 64-Bit-Versionen off_t. Wie heißen Sie?
Back Quotes sind nervig, weil ich betrunken bin.
6.7
fileno()
int
fileno(FILE *stream);
Ich bin müde, aber ich habe mein Bestes getan, um ↑ zu kopieren und einzufügen. Gibt den fd zurück, den der Stream umschließt. Oh, wie kann ich Stream zu einem Argument machen ... Ich bin müde, also nein
fdopen() Erstellt einen neuen FILE-Wert, der fd umschließt und einen Zeiger zurückgibt. Wann und warum verwenden Sie es ... Wenn Sie zwei erstellen, können Sie den Cursor separat bewegen?
Dateideskriptor und DATEI sind unterschiedlich. Ist das anders ??? fopen () kann keine Berechtigung für die neu erstellte Datei angeben. Öffnen Sie also () und fdopen (), um eine DATEI zu erstellen. Standardstein. Gemeinsamer Gedanke. Die Worte von Katzen, die ich in letzter Zeit nicht gesehen habe
ioctl () fcntl () ist nicht in stdin, also möchte ich FILE, also benutze ich fdopen ().
Ich weiß es nicht mehr
fflush() Das scheint wichtig zu sein. Schreiben Sie sofort den vom Stream gepufferten Inhalt. Es wird verwendet, wenn Sie ohne Zeilenumbrüche wie Drucken an das Terminal ausgeben möchten. Wird es wirklich Flush to Output genannt? Flush schreiben. Etwas Seltsames. Ich habe das Gefühl, ich werde es sehen, wenn ich einen Fehler behebe, der nicht auf die Festplatte geschrieben werden kann. Schreiben Sie beim Spülen. Das war's.
feof()
Ich fühle mich wie ich das gut sehe! !! Ich schrieb, dass ich es definitiv benutzen würde, wenn ich dachte. Es scheint zu überprüfen, ob der Stream beim letzten Lesen EOF war. Es scheint, dass ich es geschrieben habe, um dir zu sagen, dass du es nicht benutzen sollst. Aber ich habe das Gefühl, dass ich es oft sehe! !!
Es scheint, dass das Urteil von EOF ziemlich schwierig ist, wenn ich darüber nachdenke. Selbst wenn keine Datei (FD) vorhanden ist, ist diese falsch. Während (! Feof ()) eine Endlosschleife durchläuft, müssen Sie sich vorher darum kümmern. Darüber hinaus ist der Kommentar dieser Person erstaunlich
EOF Now we get to EOF. EOF is the response you get from an attempted I/O operation. It means that you were trying to read or write something, but when doing so you failed to read or write any data, and instead the end of the input or output was encountered. This is true for essentially all the I/O APIs, whether it be the C standard library, C++ iostreams, or other libraries. As long as the I/O operations succeed, you simply cannot know whether further, future operations will succeed. You must always first try the operation and then respond to success or failure. https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong?rq=1%EF%BC%89
Nun, das Wichtigste ist, in der letzten Zeile heißt es: „Schreib es, lies es und du wirst es verstehen.“ Vielleicht bist du betrunken.
Früher habe ich fopen () während (feof) in das PHP kopiert und eingefügt, das ich zum ersten Mal bei der Arbeit berührt habe, aber jetzt habe ich das Gefühl, dass ich endlich die Bedeutung verstehe.
clearerr()
Bei der Erstellung von tail -f liest stdio nicht (), sobald EOF aufgenommen wurde. Wenn Sie clearerr () verwenden, um es zu versuchen, wird das Fehler-Flog & EOF-Flag des Streams gelöscht. Das war's. Dann liest stdio erneut (). Hallo.
6.10 strace strace kam ---------- =! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! Ich habe darauf gewartet.
Führen Sie dies aus
$ cat hello.c
#include <stdio.h>
int
main(int argc, char *argv[])
{
printf("hello");
return 0;
}
Lauf
$ gcc heelo.c
$ ./a.out
hello
strace!!!
$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 33 vars */]) = 0
brk(NULL) = 0x1a44000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa733d28000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=138375, ...}) = 0
mmap(NULL, 138375, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fa733d06000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20&\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2156160, ...}) = 0
mmap(NULL, 3985888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fa73373a000
mprotect(0x7fa7338fd000, 2097152, PROT_NONE) = 0
mmap(0x7fa733afd000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c3000) = 0x7fa733afd000
mmap(0x7fa733b03000, 16864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fa733b03000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa733d05000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa733d03000
arch_prctl(ARCH_SET_FS, 0x7fa733d03740) = 0
mprotect(0x7fa733afd000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7fa733d29000, 4096, PROT_READ) = 0
munmap(0x7fa733d06000, 138375) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa733d27000
write(1, "hello", 5hello) = 5
exit_group(0) = ?
+++ exited with 0 +++
Oh ... ich verstehe irgendwie ... ich verstehe ...! Danke an dieses Buch ...!
Zu Beginn las ich eine Bibliothek wie "libc.so.6".
Ich bin sicher, dass mmap eine speichersichernde ist.
write(1, "hello", 5hello) = 5
Das ist es. Ich kenne Ich weiß, der erste ist Standard. 0 ist stdin und 2 ist stderr. Ich weiß nicht, was 5 ist. 5 Hallo, ich weiß nicht, was es ist, aber ich kann es irgendwie verstehen. Oh, 5 können 5 Bytes sein (5 Zeichen in Hallo)! !! !!
Code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static void do_cat(const char *path);
static void die(const char *s);
int
main(int argc, char *arvg[])
{
int i;
if (argc < 2) {
do_cat("/dev/stdin");
}
for (i=1; i<argc; i++) {
do_cat(arvg[i]);
}
exit(0);
}
#define BUFFER_SIZE 4
static void
do_cat(const char *path)
{
int fd;
unsigned char buf[BUFFER_SIZE];
int n;
fd = open(path, O_RDONLY);
if (fd < 0) die(path);
for (;;) {
n = read(fd, buf, sizeof buf);
if (n < 0) die(path);
if (n == 0) break;
if (write(STDOUT_FILENO, buf, n) < 0) die (path);
}
if (close(fd) < 0) die(path);
}
static void
die(const char *s)
{
perror(s);
exit(1);
}
Rufen Sie eine kurze Datei auf
$ ./a.out txt
abc
xyz
Versuchen Sie es mit Strace
$ strace ./a.out txt
execve("./a.out", ["./a.out", "txt"], [/* 33 vars */]) = 0
brk(NULL) = 0x1505000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc02f188000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=138375, ...}) = 0
mmap(NULL, 138375, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc02f166000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20&\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2156160, ...}) = 0
mmap(NULL, 3985888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fc02eb9a000
mprotect(0x7fc02ed5d000, 2097152, PROT_NONE) = 0
mmap(0x7fc02ef5d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c3000) = 0x7fc02ef5d000
mmap(0x7fc02ef63000, 16864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fc02ef63000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc02f165000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc02f163000
arch_prctl(ARCH_SET_FS, 0x7fc02f163740) = 0
mprotect(0x7fc02ef5d000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7fc02f189000, 4096, PROT_READ) = 0
munmap(0x7fc02f166000, 138375) = 0
open("txt", O_RDONLY) = 3
read(3, "abc\n", 4) = 4
write(1, "abc\n", 4abc
) = 4
read(3, "xyz\n", 4) = 4
write(1, "xyz\n", 4xyz
) = 4
read(3, "\n", 4) = 1
write(1, "\n", 1
) = 1
read(3, "", 4) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
2020-11-06-00:56:52 irteamsu@kuji-localdev-001-pool-jp2v-dev:/kc/hello$
Der Anfang ist der gleiche. Ist es anders, dass read () in der zweiten Hälfte erscheint? Gleich
strace -e trace=open,read,write,close
Es ist sicherlich leicht zu sehen, wenn Sie es versuchen
$ strace -e trace=open,read,write,close ./a.out txt
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20&\2\0\0\0\0\0"..., 832) = 832
close(3) = 0
open("txt", O_RDONLY) = 3
read(3, "abc\n", 4) = 4
write(1, "abc\n", 4abc
) = 4
read(3, "xyz\n", 4) = 4
write(1, "xyz\n", 4xyz
) = 4
read(3, "\n", 4) = 1
write(1, "\n", 1
) = 1
read(3, "", 4) = 0
close(3) = 0
+++ exited with 0 +++
code
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int i;
for (i=1; i<argc; i++) {
FILE *f;
int c;
f = fopen(argv[i], "r");
if(!f) {
perror(argv[i]);
exit(1);
}
while ((c = fgetc(f)) != EOF) { //Behalte fgetc, bis du EOF drückst
// if (putchar(c) < 0) exit(1);
putchar(c);
}
fclose(f);
}
exit(0);
}
strace
$ strace -e trace=open,read,write,close ./a.out txt
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20&\2\0\0\0\0\0"..., 832) = 832
close(3) = 0
open("txt", O_RDONLY) = 3
read(3, "abc\nxyz\n\n", 4096) = 9
write(1, "abc\n", 4abc
) = 4
write(1, "xyz\n", 4xyz
) = 4
write(1, "\n", 1
) = 1
read(3, "", 4096) = 0
close(3) = 0
+++ exited with 0 +++
das Gleiche? Wenn Sie denken, ist das anders! !!
read(3, "abc\nxyz\n\n", 4096) = 9
Ich lese ** 4096 Bytes ** mit diesem Lesen, und dann gibt es kein Lesen! !!
Da ich es früher auf 4 Bytes eingestellt habe, gab es zwei Lesevorgänge, aber es gibt nur einen Standard. Der Rest bleibt erhalten, bis geschrieben steht. Das war's! !! !!
~~ Betrunken sinken. nimm den Rest. ~~
Guten Morgen.
erledigt. Es scheint nicht gut zu sein, es mit ASCII-Code zu schreiben, da es den Fehler von Putchar nicht behandelt. Aber ich hatte das Gefühl, nichts anderes als Putsch zu verstehen
Quelle, auf die Sie sich nicht beziehen sollen, weil sie angemessen ist ↓. Die Antwort lautet https://github.com/aamine/stdlinux2-source/blob/master/cat4.c
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int i;
for (i=1; i<argc; i++) {
FILE *f;
int c;
f = fopen(argv[i], "r");
if(!f) {
perror(argv[i]);
exit(1);
}
while ((c = fgetc(f)) != EOF) { //Behalte fgetc, bis du EOF drückst
if (c == 9) { //Wenn Tab kommt
putchar(92); // \Herausgeben(Zahlen können der ASCII-Tabelle entnommen werden)
putchar(116); //Ausgabe t(Zahlen können der ASCII-Tabelle entnommen werden)
continue;
}
if (c == 10) putchar(36); // \Wenn n kommt$Herausgeben(Zahlen können der ASCII-Tabelle entnommen werden)
if (putchar(c) < 0) exit(1);
}
fclose(f);
}
exit(0);
}
Überprüfen Sie die Antwort.
Obwohl es "int c" ist, ist es keine C-Sprache, die "if (c ==" \ n ")" kann. Es ist eine ganze Zahl. Es ist schlau. Ich wollte fputs verwenden. Aber wenn Sie int c setzen, werden Sie wütend. Ist '\ t'in fput und int in putchar? Wie nervig. Ich hasse dich.
Es ist geschafft, aber es scheint einen Fehler zu geben.
Mein Code ↓. Die Antwort lautet https://github.com/aamine/stdlinux2-source/blob/master/wc-l-stdio.c
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
FILE *f;
int c;
int num = 0;
f = fopen("/dev/stdin", "r");
if(!f) {
perror(argv[0]);
exit(1);
}
while ((c = fgetc(f)) != EOF) { //Behalte fgetc, bis du EOF drückst
if (c == 10) num++;
}
printf("%d\n", num++);
fclose(f);
exit(0);
}
Ergebnis
Richtige Antwort
$ gcc -Wall -O2 wc.c && cat test | ./a.out txt
6
$ wc -l test
6 test
Falsche Antwort
$ wc -l /var/log/system.log
6943 /var/log/system.log
$ cat /var/log/system.log | ./a.out
6947
Es ist ein bisschen anders. Warum gibt es so viele Zeilenumbrüche?
→ Es war ein Missverständnis. Nur das Syslog erhöhte sich w
$ wc -l /var/log/system.log && cat /var/log/system.log | ./a.out
6984 /var/log/system.log
6984
Die Antwort auf die Frage war hier! http://i.loveruby.net/stdlinux2/answers.html
Überprüfen Sie die Antwort.
Obwohl es "int c" ist, ist es keine C-Sprache, die "if (c ==" \ n ")" kann. Es ist eine ganze Zahl. Es ist schlau. Sie können eine große Datei nur verwenden, wenn Sie sie auf unsigned long n; gesetzt haben. Wenn es eine Datei gibt, die am Ende mit \ n endet, wird sie noch einmal gezählt. Ich habe es als Standardeingabe geschrieben, aber es unterstützt auch Datei. Unfair. Vielleicht ist das Problem anders, weil mein Buch die erste Ausgabe ist.
Yosha ah ah ah ah Kapitel 6 ist vorbei! !! !! !! !! !! !! !! !!
Sie können den C-Sprachcode verstehen! !! !! !! !! !! !!
Sie können sehen, wo sich die Hauptfunktion befindet, indem Sie sich die Quelle des Befehls wc ansehen. https://github.com/coreutils/coreutils/blob/master/src/wc.c
Ich wusste nicht, was drin war
Ich lese dieses Buch
<a target = "_ blank" href = "https://www.amazon.co.jp/gp/product/4797328355/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4797328355&linkCode=as2&tag=lespacetr2f2 > Gewöhnliche Linux-Programmierung Der Königsweg der gcc-Programmierung, der aus dem Mechanismus von Linux gelernt werden kann <a target = "_ blank" href = "https://www.amazon.co.jp/gp/product/B075ST51Y5/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B075ST51Y5&linkCode=as2&a0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > Gewöhnliche Linux-Programmierung 2. Ausgabe: Der königliche Weg der gcc-Programmierung, der aus dem Mechanismus von Linux gelernt werden kann
Recommended Posts