Narzędzia użytkownika

Narzędzia witryny


os_cp:open:solutions

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
os_cp:open:solutions [2023/04/11 23:50]
jkonczak removed
— (aktualna)
Linia 1: Linia 1:
-~~Exercise.#​~~ 
-<code c> 
-int main(int argc, char *argv[]){ 
-    return 0; 
-} 
-</​code>​ 
-To compile, one may use any of: 
-  * ''​cc prog.c -o prog''​ 
-  * ''​gcc   --std=c17 -Wall --pedantic -g -O2 x.c -o x''​ 
-  * ''​clang --std=c17 -Wall --pedantic -g -O2 x.c -o x''​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​stdio.h>​ 
-int main(int argc, char *argv[]){ 
-    printf("​Hello.\n"​);​ 
-    return 0; 
-} 
-</​code>​ 
-<code c> 
-#include <​stdio.h>​ 
-int main(int argc, char *argv[]){ 
-    fprintf(stdout,​ "​Hello.\n"​);​ 
-    return 0; 
-} 
-</​code>​ 
-<code c> 
-#include <​unistd.h>​ 
-int main(int argc, char *argv[]){ 
-    write(STDOUT_FILENO,​ "​Hello.\n",​ 7); 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    write(STDOUT_FILENO,​ argv[1], strlen(argv[1]));​ 
-    write(STDOUT_FILENO,​ "​\n",​ 1); 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    write(STDOUT_FILENO,​ argv[1]+3, strlen(argv[1])-3);​ 
-    write(STDOUT_FILENO,​ "​\n",​ 1); 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    for(int i = 0; i < argc; ++i){ 
-        write(STDOUT_FILENO,​ argv[i], strlen(argv[i]));​ 
-        write(STDOUT_FILENO,​ "​\n",​ 1); 
-    } 
-    return 0; 
-} 
-</​code>​ 
-or, knowing that the argument array has a [[https://​en.wikipedia.org/​wiki/​Sentinel_value|sentinel]]: ​ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    do { 
-        write(STDOUT_FILENO,​ *argv, strlen(*argv));​ 
-        write(STDOUT_FILENO,​ "​\n",​ 1); 
-    } while(*++argv);​ 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    char buffer[256];​ 
-    strncpy(buffer,​ argv[1], 254); 
-    buffer[254] = 0; 
-    strcat(buffer,​ "​\n"​);​ 
-    write(STDOUT_FILENO,​ buffer, strlen(buffer));​ 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​stdlib.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    size_t length = strlen(argv[1]);​ 
-    char *buffer = (char*) malloc(length+1);​ 
-    memcpy(buffer,​ argv[1], length); 
-    buffer[length]='​\n';​ 
-    write(STDOUT_FILENO,​ buffer, strlen(buffer));​ 
-    free(buffer);​ 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​ctype.h>​ 
-#include <​stdlib.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    size_t length = strlen(argv[1]);​ 
-    char *buffer = (char*) malloc(length+1);​ 
-    for(int i = 0; i < length; ++i) 
-        buffer[i] = toupper(argv[1][i]);​ 
-    buffer[length]='​\n';​ 
-    write(STDOUT_FILENO,​ buffer, length+1); 
-    free(buffer);​ 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    char buffer[256];​ 
-    scanf("​%254[^\n]",​ buffer); 
-    strcat(buffer,​ "​\n"​);​ 
-    write(STDOUT_FILENO,​ buffer, strlen(buffer));​ 
-    return 0; 
-} 
-</​code>​ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
-int main(int argc, char *argv[]){ 
-    char buffer[256];​ 
-    fscanf(stdin,​ "​%254[^\n]",​ buffer); 
-    strcat(buffer,​ "​\n"​);​ 
-    write(STDOUT_FILENO,​ buffer, strlen(buffer));​ 
-    return 0; 
-} 
-</​code>​ 
-<code c> 
-#include <​unistd.h>​ 
-int main(int argc, char *argv[]){ 
-    char buffer[256];​ 
-    int length = read(STDIN_FILENO,​ buffer, 256); 
-    write(STDOUT_FILENO,​ buffer, length); 
-    return 0; 
-} 
-</​code>​ 
- 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​stdio.h>​ 
-int main(int argc, char *argv[]){ 
-    char buffer[256];​ 
-    while(1){ 
-        int length = read(STDIN_FILENO,​ buffer, 256); 
-        if(length == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(length == 0) 
-            break; 
-        write(STDOUT_FILENO,​ buffer, length); 
-    } 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​stdio.h>​ 
-int readFile(){ 
-    char buffer[256];​ 
-    while(1){ 
-        int length = read(STDIN_FILENO,​ buffer, 256); 
-        if(length == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(length == 0) 
-            return 0; 
-        write(STDOUT_FILENO,​ buffer, length); 
-    } 
-} 
-int main(int argc, char *argv[]){ 
-    if(readFile()) 
-        return -1; 
-    lseek(STDIN_FILENO,​ 0, SEEK_SET); 
-    if(readFile()) 
-        return -1; 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​stdio.h>​ 
-int main(int argc, char *argv[]){ 
-    char buffer[256];​ 
-    while(1){ 
-        int length = read(4, buffer, 256); 
-        if(length == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(length == 0) 
-            break; 
-        write(STDOUT_FILENO,​ buffer, length); 
-    } 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-int main(int argc, char *argv[]){ 
-    int fd = open("/​tmp/​z",​ O_RDONLY); 
-    if(fd == -1){ 
-        perror(NULL);​ 
-        return 1; 
-    } 
-    char buffer[256];​ 
-    while(1){ 
-        int length = read(fd, buffer, 256); 
-        if(length == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(length == 0) 
-            break; 
-        write(STDOUT_FILENO,​ buffer, length); 
-    } 
-    close(fd); 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-int main(int argc, char *argv[]){ 
-    int fd = open(argv[1],​ O_RDONLY); 
-    if(fd == -1){ 
-        perror(NULL);​ 
-        return 1; 
-    } 
-    char buffer[256];​ 
-    while(1){ 
-        int length = read(fd, buffer, 256); 
-        if(length == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(length == 0) 
-            break; 
-        write(STDOUT_FILENO,​ buffer, length); 
-    } 
-    close(fd); 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-#include <​stdlib.h>​ 
-#include <​string.h>​ 
- 
-int main(int argc, char *argv[]){ 
-    int fd = open(argv[1],​ O_RDONLY); 
-    if(fd == -1){ 
-        perror(NULL);​ 
-        return 1; 
-    } 
-    int num = 1; 
-    int printNumber = 1; 
-    while(1){ 
-        char c; 
-        int count = read(fd, &c, 1); 
-        if(count == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(count == 0) 
-            break; 
-        if(printNumber){ 
-            char numBuf[16]; 
-            sprintf(numBuf,​ "%5d ", num++); 
-            write(STDOUT_FILENO,​ numBuf, strlen(numBuf));​ 
-            printNumber=0;​ 
-        } 
-        write(STDOUT_FILENO,​ &c, 1); 
-        if(c == '​\n'​) 
-            printNumber=1;​ 
-    } 
-    close(fd); 
-    return 0; 
-}</​code>​ 
-++++ The program above is intentionally made simple rather than efficient; the program below is more efficient, but has a few more lines. | 
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
- 
-void checkPrintNl(int *shallPrint,​ unsigned *number){ 
-    if(!*shallPrint) 
-        return; 
-    char buf[12]; 
-    sprintf(buf,​ "%5u ", (*number)++);​ 
-    write(STDOUT_FILENO,​ buf, strlen(buf));​ 
-    *shallPrint=0;​ 
-} 
- 
-int main(int argc, char *argv[]){ 
-    int fd = open(argv[1],​ O_RDONLY); 
-    if(fd == -1){ 
-        perror(NULL);​ 
-        return 1; 
-    } 
-    int printLineNum = 1; 
-    unsigned lineNum = 1; 
-    while(1){ 
-        char buf[256]; 
-        int length = read(fd, buf, 256); 
-        if(length == -1){ 
-            perror(NULL);​ 
-            return 1; 
-        } 
-        if(length == 0) 
-            break; 
-        char *it = buf, *nlPos; 
-        while( (nlPos = memchr(it, '​\n',​ length)) ){ 
-            checkPrintNl(&​printLineNum,​ &​lineNum);​ 
-            int partLen = nlPos+1-it; 
-            write(STDOUT_FILENO,​ it, partLen); 
-            length -= partLen; 
-            it = nlPos+1; 
-            printLineNum = 1; 
-        } 
-        if(length){ 
-            checkPrintNl(&​printLineNum,​ &​lineNum);​ 
-            write(STDOUT_FILENO,​ it, length); 
-        } 
-    } 
-    return 0; 
-} 
-</​code>​ 
-++++ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
- 
-#define CHECK(result,​ textOnFail) \ 
-if(result == -1){                 \ 
-    perror(textOnFail); ​          \ 
-    return 1;                     \ 
-} 
-int main(int argc, char *argv[]){ 
-    if(argc < 3){ 
-        write(STDERR_FILENO,​ "Not enough arguments\n",​ 21); 
-        return 1; 
-    } 
-    int file1 = open(argv[1],​ O_RDONLY); 
-    CHECK(file1,​ argv[1]); 
-    int file2 = open(argv[2],​ O_RDONLY); 
-    CHECK(file2,​ argv[2]); 
-    while(1){ 
-        char buf1[256], buf2[256]; 
-        int len1 = read(file1, buf1, 256); 
-        CHECK(len1, argv[1]); 
-        int len2 = read(file2, buf2, 256); 
-        CHECK(len2, argv[2]); 
-        if(len1 != len2) 
-            break; 
-        if(len1 == 0){ 
-            write(STDOUT_FILENO,​ "Files have the same contents\n",​ 29); 
-            return 0; 
-        } 
-        if(memcmp(buf1,​ buf2, len1)) 
-            break; 
-    } 
-    write(STDOUT_FILENO,​ "Files differ\n",​ 13); 
-    return 0; 
-} 
-</​code>​ 
- 
-~~Exercise.#​~~ 
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-#include <​stdlib.h>​ 
- 
-int main(int argc, char *argv[]){ 
-    ++argv; --argc; // get rid of program name; simplifies array indexes 
-    int *file = malloc(sizeof(int) * argc); 
-    int running = 0; 
-    for(int i = 0; i < argc; ++i){ 
-        file[i] = open(argv[i],​ O_RDONLY); 
-        if(file[i] == -1) 
-            perror(argv[i]);​ 
-        else 
-            running = 1; 
-    } 
-    while(running){ 
-        running = 0; 
-        for(int i = 0; i < argc; ++i){ 
-            while(file[i] != -1){ 
-                char c; 
-                int l = read(file[i],​ &c, 1); 
-                if(l <= 0){ 
-                    if(l == -1) 
-                        perror(argv[i]);​ 
-                    close(file[i]);​ 
-                    file[i] = -1; 
-                    break; 
-                } 
-                if(c == '​\n'​){ 
-                    running = 1; 
-                    break; 
-                } 
-                write(STDOUT_FILENO,​ &c, 1); 
-            } 
-            write(STDOUT_FILENO,​ (i == argc-1) ? "​\n"​ : "​\t",​ 1); 
-        } 
-    } 
-    free(file); 
-    return 0; 
-} 
-</​code>​ 
-++++ The program above is intentionally made simple rather than efficient; the program below is more efficient, but has more lines. | 
-NB: speedup of this program vs the one above is way beyond 100x  
-<code c> 
-#include <​unistd.h>​ 
-#include <​fcntl.h>​ 
-#include <​stdio.h>​ 
-#include <​string.h>​ 
-#include <​stdlib.h>​ 
-#include <​assert.h>​ 
- 
-/** A few words of explanation:​ each '​read'​ and '​write'​ call involves 
- * the operating system. Calling the OS is expensive. Thus, I/O is 
- * usually buffered. This program buffers both input and output, but 
- * to buffer output and still use OS API, one has to buffer I/O oneself. 
- */ 
-#define BUFSIZE 4096 
- 
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OUTPUT BUFFERING ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
- 
-struct { //< custom standard output buffer 
-    char b[2*BUFSIZE];​ 
-    size_t c; 
-} outBuf; 
- 
-void flushOutput(){ //< writes out the standard output buffer 
-    if(outBuf.c != write(STDOUT_FILENO,​ outBuf.b, outBuf.c)){ 
-        perror("​writing to output failed"​);​ 
-        exit(1); 
-    } 
-    outBuf.c = 0; 
-} 
- 
-/** adds data to output buffer and outputs if buffer is sufficiently filled 
-  * @warning: this relies on an assumption that count never exceeds BUFSIZE */ 
-void bufferOutput(char *data, size_t count){ ​ 
-    assert(count <= BUFSIZE); 
-    memcpy(outBuf.b + outBuf.c, data, count); 
-    if((outBuf.c += count) >= BUFSIZE) 
-        flushOutput();​ 
-} 
- 
-// ~ ~ ~ ~ ~ READING LINES FROM INPUT & BUFFERING INPUT ~ ~ ~ ~ ~ 
- 
-struct myFile {  //< stores state & buffer of a file 
-    char *name; ​ //< used for diagnostics when read returns -1 
-    int fd;      //< once the file ends (or read fails), -1 is put here 
-    char buf[BUFSIZE];​ 
-    int pos;     //<​ position where data in buf starts 
-    int count; ​  //<​ number of bytes in but from pos to end of data 
-}; 
- 
-/// reads from file to buffer, @returns 0 if any data was read, else returns 1 
-int readChunk(struct myFile *f){ 
-    f->pos = 0; 
-    f->count = read(f->​fd,​ f->buf, BUFSIZE); 
-    if(f->​count<​=0){ 
-        if(f->​count == -1) 
-            perror(f->​name);​ 
-        close(f->​fd);​ 
-        f->fd = -1; 
-        return 1; 
-    } 
-    return 0; 
-} 
- 
-/** reads and outputs a line from file, 
- * @returns 0 if there is any outstanding data in file, else returns 1 */ 
-int readAndOutputLine(struct myFile *f){ 
-    while(1){ 
-        if(f->fd == -1) 
-            return 1; 
-        if(f->​count == 0) 
-            if(readChunk(f)) 
-                return 1; 
-        char *nlPos, *startPos = f->​buf+f->​pos;​ 
-        if( (nlPos = memchr(startPos,​ '​\n',​ f->​count)) ){ 
-            int partLen = nlPos-startPos;​ 
-            bufferOutput(startPos,​ partLen); 
-            f->​pos ​  += partLen+1; 
-            f->count -= partLen+1; 
-            if(f->​count) 
-                return 0; 
-            return readChunk(f);​ 
-        } 
-        bufferOutput(startPos,​ f->​count);​ 
-        f->count = 0; 
-    } 
-} 
- 
-// ~ ~ ~ ~ ~ OPENING FILES, LOOPING THROUGH LINES ~ ~ ~ ~ ~ 
- 
-int main(int argc, char *argv[]){ 
-    ++argv; --argc; // get rid of program name; simplifies array indexes 
-    struct myFile *myFiles = malloc(sizeof(myFiles) * argc); 
-    int allFilesEof = 1; 
-    for(int i = 0 ; i < argc; ++i){ 
-        myFiles[i].fd = open(argv[i],​ O_RDONLY); 
-        if(myFiles[i].fd == -1) 
-            perror(argv[i]);​ 
-        else { 
-            myFiles[i].name = argv[i]; 
-            allFilesEof &= readChunk(myFiles+i);​ 
-        } 
-    } 
-    while(!allFilesEof){ 
-        allFilesEof = readAndOutputLine(myFiles);​ 
-        for(int i = 1 ; i < argc; ++i){ 
-            bufferOutput("​\t",​ 1); 
-            allFilesEof &= readAndOutputLine(myFiles+i);​ 
-        } 
-        bufferOutput("​\n",​ 1); 
-    } 
-    free(myFiles);​ 
-    flushOutput();​ 
-    return 0; 
-} 
-</​code>​ 
-++++ 
- 
- 
-~~META: 
-language = en 
-~~ 
  
os_cp/open/solutions.1681249831.txt.gz · ostatnio zmienione: 2023/04/11 23:50 (edycja zewnętrzna)