Skip to content

Instantly share code, notes, and snippets.

@sasairc
Last active November 9, 2018 11:19
Show Gist options
  • Save sasairc/20d99b27f72b308be34242f098864804 to your computer and use it in GitHub Desktop.
Save sasairc/20d99b27f72b308be34242f098864804 to your computer and use it in GitHub Desktop.

テキストファイルの行と文字を全反転する

この記事は「tac と rev でやれ」 Advent Calender 2049 の記事です。

source code

毎度の事ですが、呼び出し元 (main()) から読んで下さい。そうすればわかります。

/*
 * tacrev.c - tac と rev でやれ
 *
 * gcc tacrev.c -lbenly_typestring -o tacrev
 *
 */
#include <benly/typestring.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

static
int read_file(FILE* fp, size_t* lines, STRING*** dest)
{
    size_t      th_lines    = 256;

    STRING**    s           = NULL;

    if ((s = (STRING**)
                malloc(sizeof(STRING*) * (th_lines + 1))) == NULL) {
        perror("malloc"); goto ERR;
    }
    *lines = 0;
    string_errno = 0;
    while (fgetline(fp, &s[*lines]) != EOF) {
        if (string_errno < 0)
            goto ERR;
        if (*lines == (th_lines - 1)) {
            th_lines += th_lines;
            if ((s = (STRING**)
                        realloc(s, sizeof(STRING*) * th_lines)) == NULL) {
                perror("realloc"); goto ERR;
            }
        }
        (*lines)++;
    }
    *dest = s;

    return 0;

ERR:
    th_lines = 0;
    if (s != NULL) {
        while (th_lines < *lines) {
            if (s[th_lines] != NULL) {
                s[th_lines]->release(s[th_lines]);
            }
            th_lines++;
        }
        free(s);
    }

    return -1;
}

static
void do_tacrev(STRING** s, size_t lines)
{
    while (lines > 0) {
        lines--;
        s[lines]->chomp(&s[lines]);
        s[lines]->reverse(&s[lines]);
        fputline(stdout, s[lines]);
        s[lines]->release(s[lines]);
        putchar('\n');
    }
    free(s);

    return;
}

static
int source_pipe(void)
{
    size_t      lines   = 0;

    STRING**    s        = NULL;

    if (read_file(stdin, &lines, &s) < 0)
        return -1;
    else
        do_tacrev(s, lines);

    return 0;
}

static
int source_argument(char* path)
{
    FILE*       fp      = NULL;

    size_t      lines   = 0;

    STRING**    s       = NULL;

    if ((fp = fopen(path, "r")) == NULL) {
        fprintf(stdout, "tacrev: %s: %s\n",
                path, strerror(errno));
        return -1;
    }
    if (read_file(fp, &lines, &s) < 0) {
        fclose(fp);
        return -2;
    }
    fclose(fp);
    do_tacrev(s, lines);

    return 0;
}

int main(int argc, char* argv[])
{
    if (argc > 1) {
        while (argc > 1) {
            argc--;
            if (source_argument(argv[argc]) < 0)
                return 1;
        }
    } else {
        if (source_pipe() < 0)
            return 2;
    }

    return 0;
}

example

% gcc tacrev.c -lbenly_typestring -o tacrev
% < tacrev.c | ./tacrev
}
;0 nruter    

;)s(eerf    
}    
;)'n\'(rahctup        
;)]senil[s(esaeler>-]senil[s        
;)]senil[s ,tuodts(eniltupf        
;)]senil[s&(esrever>-]senil[s        
;)]senil[s&(pmohc>-]senil[s        
;--senil        
{ )0 > senil( elihw    
;1 nruter        
)0 < )s& ,senil& ,nidts(elif_daer( fi    

;LLUN =       s    **GNIRTS    

;0 =   senil      t_ezis    
{
)][vgra *rahc ,cgra tni(niam tni

}
;1- nruter    

}    
;)s(eerf        
}        
;++senil_ht            
}            
;)]senil_ht[s(esaeler>-]senil_ht[s                
{ )LLUN =! ]senil_ht[s( fi            
{ )senil* < senil_ht( elihw        
{ )LLUN =! s( fi    
;0 = senil_ht    
:RRE

;0 nruter    

;s = tsed*    
}    
;++)senil*(        
}        
}            
;RRE otog ;)"collaer"(rorrep                
{ )LLUN == ))senil_ht * )*GNIRTS(foezis ,s(collaer                        
)**GNIRTS( = s(( fi            
;senil_ht =+ senil_ht            
{ ))1 - senil_ht( == senil*( fi        
;RRE otog            
)0 < onrre_gnirts( fi        
{ )FOE =! )]senil*[s& ,pf(eniltegf( elihw    
;0 = senil*    
}    
;RRE otog ;)"collam"(rorrep        
{ )LLUN == )))1 + senil_ht( * )*GNIRTS(foezis(collam                
)**GNIRTS( = s(( fi    

;LLUN =           s    **GNIRTS    

;652 =    senil_ht      t_ezis    
{
)tsed ***GNIRTS ,senil *t_ezis ,pf *ELIF(elif_daer tni
citats

>h.bildts< edulcni#
>h.oidts< edulcni#
>h.gnirtsepyt/ylneb< edulcni#
/* 
* 
vercat o- gnirtsepyt_ylnebl- c.vercat ccg * 
* 
れやで ver と cat - c.vercat * 
*/

;LLUN ってやけに楽しそうね。

% time sh -c "cat /usr/share/yasuna/yasuna-quotes | tac | rev" > /dev/null
sh -c "cat /usr/share/yasuna/yasuna-quotes | tac | rev" > /dev/null  0.01s user 0.01s system 42% cpu 0.038 total
% time sh -c "cat /usr/share/yasuna/yasuna-quotes | tacrev" > /dev/null
sh -c "cat /usr/share/yasuna/yasuna-quotes | tacrev" > /dev/null  0.03s user 0.01s system 103% cpu 0.036 total

速度もそんなに遅くない。もっと遅いかと思っていた。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment