C 標(biāo)準(zhǔn)庫(kù) - stdio.h

I/O 函數(shù) Return value 總結(jié), 字符處理函數(shù) 除外

(1) returnType 為 整型/size_t, return value 可能不用于表示個(gè)數(shù), 此時(shí)一般以 0 表示 success, nonZero 表示 fail

Return 
    0      , success
    nonZero, else

(2) returnType 為 int/size_t, return value 可能用于表示 個(gè)數(shù), 此時(shí)一般表示 successful 處理的個(gè)數(shù)

    fread 
    fwrite

1 類型

1.1 file position indicator: fpos_t // 類型

可用于 store (被 fgetpos) 和 restore (被 fsetpos) 文件 position

1.2 size_t

無符號(hào)整型

    sizeof 結(jié)果類型

1.3 FILE: 存 file stream

2 Predefined standard streams

    stdin 

    stdout

    stderr 

3 File 訪問

fopen   // opens a file
fclose  // closes a file

fflush  // synchronizes an output stream with the actual file

setvbuf // sets the buffer, and its size for a file stream
setbuf  // sets the buffer for a file stream

(1) FILE* fopen(const char* filename, const char* mode);

Return
    ptr to file stream, success
    
    NULL              , else    
        POSIX requires that `errno be set` in this case

(2) int fclose(FILE* stream );

I/O buf data 丟掉 / write from/to stream

(3) int fflush(FILE* stream);

[1] fflush(stdout/outputDevice);
    writes unwritten data (from stream's buffer) to associated output device.

[2] fflush(stdin); 
    the behavior is undefined.
    非 C標(biāo)準(zhǔn), `gcc 不支持`

Note: If stream is a null pointer, all open output streams are flushed

(4) int setvbuf(FILE* stream, char* buffer, int bufMode, size_t bufSize );

    bufMode: _IOFBF / _IOLBF / _IONBF   

(5) void setbuf(FILE* stream, char* buffer);

Sets internal buffer for stream. 至少 BUFSIZ characters long

Note

[1] 若 BUFSIZ 并非合適的 buffer size, setvbuf 可被用來 change it

封裝 setvbuf, 只留下 前2個(gè)參數(shù)

buffer == NULL/!= NULL 時(shí), 分別等價(jià)于

    setvbuf(stream, NULL, _IONBF, 0)        // 關(guān) buf
    setvbuf(stream, buffer, _IOFBF, BUFSIZ) // 全 buf + BUFSIZ(512 Byte)

Note

[2] 應(yīng)該用于 stream 關(guān)聯(lián)到 文件后, 任何其他操作前

[3] 常見錯(cuò)誤: stdin/stdout 的 buffer 數(shù)組 lifetime 先于 程序/main 結(jié)束

問題: 程序離開 main 后, 準(zhǔn)備 clear buf, 但 buffer lifetime 已結(jié)束

#include <stdio.h> 

int main() 
{ 
    int c; 
    char buf[BUFSIZ]; 
    setbuf(stdout,buf); 
    while( (c=getchar())!= EOF) 
        putchar(c); 
}
gcc 下 匯編可看出問題
image.png

solution: buffer array 放 main 之外

#include <stdio.h> 
char buf[BUFSIZ]; 
int main() 
{ 
    int c;  
    setbuf(stdout,buf); 
    while( (c=getchar())!= EOF) 
        putchar(c); 
}

應(yīng)用

[1] 關(guān) stdout buf, 以 立即輸出

    setbuf(stdout, NULL)

    //<=>
    setvbuf(stdout, NULL, _IOFBF, 0)` 設(shè)為全緩沖

[2] 關(guān) stdin buf, 即 清空 stdin buf

    setbuf(stdin, NULL)

    // <=>
    void clear_stdin_buf()
    {
        int ch;
        while( (ch = getchar() ) != '\n' && ch != EOF)
            ; 
    }
#include <stdio.h>
char buf[BUFSIZ];
int main()
{
    // 指定 stdout 緩沖區(qū) 為 buf 
    setbuf(stdout, buf);

    // 把 hello\n 放 stdout buf, 這行執(zhí)行完, 屏幕上 不打印 hello
    puts("hello");

    // 這行執(zhí)行完, 屏幕上 打印 hello
    fflush(stdout);
}

4 Direct input/output: fread/fwrite

fread
    reads from a file

fwrite
    writes to a file

file position indicator 自動(dòng)前移

(1) size_t fread(void* buffer, size_t size, size_t count, FILE* stream);

好像對(duì) 每個(gè) object, 調(diào) size 次 fgetc, reinterpreted 為 unsigned char 數(shù)組

Return: 成功 read 的 objects 數(shù), 可能 <= count: if error 或 end-of-file occurs

fread 不區(qū)分 end-of-file 和 error, callers 必須用 feof 和 ferror 去判斷 which occurred

(2) size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream );

好像對(duì) 每個(gè) object, 調(diào) size 次 fputc, 將 size 個(gè) unsigned chars(視為1個(gè)object) 寫進(jìn) stream

Return: 成功 write 的 objects 數(shù), 可能 <= count: if error occurs

#include <stdio.h>
#include <stdlib.h> // malloc 

enum { SIZE = 3 };
int main(void)
{
    double a[SIZE] = { 1.,2.,3. };

    FILE* fp = fopen("test.bin", "wb"); // must use binary mode
    fwrite(a, sizeof(*a), SIZE, fp);    // writes an array of doubles
    fclose(fp);

    // === (2) 解析 二進(jìn)制文件: 知道文件所存 object 類型 
    fp = fopen("test.bin", "rb");

    fseek(fp, 0, SEEK_END);      // set stream 上 文件位置指針 = offset/Bytes + whence = 文件尾
    size_t fileSize = ftell(fp); // 求 文件位置指針 相對(duì) 文件首 偏移 Bytes = fileSize
    rewind(fp);                  // set stream 上 文件位置指針 = 文件首

    size_t objectsCount = fileSize / sizeof(double);
    double* buf = (double *)malloc(fileSize); // allocate buf memory
    size_t ret = fread(buf, sizeof(double), objectsCount, fp);

    if (ret == objectsCount)
    {
        puts("Array read successfully, contents: ");
        for (size_t i = 0; i < objectsCount; ++i)
            printf("%f ", buf[i]);
        putchar('\n');
    }
    else // error handling
    {
        if (feof(fp))         // 1) EOF
            printf("Error reading test.bin: unexpected end of file\n");
        else if (ferror(fp))  // 2) error
            perror("Error reading test.bin");

    }

    free(buf);

    fclose(fp);
}
    Array read successfully, contents:
    1.000000 2.000000 3.000000

5 文件定位

ftell
    returns the current file position indicator

fgetpos
    gets the file position indicator

fseek
    moves the file position indicator to a specific location in a file

fsetpos
    moves the file position indicator to a specific location in a file

rewind
    moves the file position indicator to the beginning in a file

set 文件位置: para 數(shù) 1 / 2 / 3 => rewind / fsetpos / fseek

set stream 文件位置指針 = 文件頭 / pos 所指處 / offset + whence 處

(1) void rewind(FILE* stream)

(2) int fsetpos(FILE* stream, const fpos_t* pos)

    moves file position indicator to 文件中 特定位置

If a read or write error occurs, the error indicator (ferror) for the stream is set

(3) int fseek(FILE* stream, long int offset, int whence)

whence = SEEK_SET/SEEK_CUR/SEEK_END

get 文件位置: para 數(shù) 1 / 2 => ftell/fgetpos

get stream 文件位置 = 當(dāng)前文件位置指針 相對(duì) 文件首的偏移( Bytes 數(shù) ) / pos 所指處

(4) long int ftell(FILE* stream)

Note: 必須以 二進(jìn)制 打開

(5) int fgetpos(FILE* stream, fpos_t* pos)

    gets file position indicator

剛打開文件時(shí), pos 記錄文件起始位置: fpos_t pos; fgetpos(fp, &pos);

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(void)
{
    enum { SIZE = 3 };

    // (1) fwrite a file
    FILE* fp = fopen("test.bin", "wb");
    assert(fp);

    double arr[SIZE] { 1.1, 2.2, 3.3};
    int rc = fwrite(arr, sizeof(double), SIZE, fp);
    assert(rc == SIZE);
    fclose(fp);

    // (2) fread one by one 
    fp = fopen("test.bin", "rb");

    double d;
    fpos_t pos;
    fgetpos(fp, &pos);                // [1] store start pos of file
    
    rc = fread(&d, sizeof(d), 1, fp); // [2] read first double
    assert(rc == 1);
    printf("First value in the file: %.1f\n", d);
            
    if(fsetpos(fp, &pos) != 0)        // [3] set/move file position back to start of file
    {
       if (ferror(fp))
       {
          perror("fsetpos()");
          fprintf(stderr,"fsetpos() failed in file %s at line # %d\n", __FILE__,__LINE__-5);
          exit(EXIT_FAILURE);
       }
    }
    
    rc = fread(&d, sizeof(d), 1, fp); // [4] read again: the first double
    assert(rc == 1);
    printf("First value in the file again: %.1f\n", d);

    rc = fread(&d, sizeof(d), 1, fp); // [5] read next elem: the second double
    assert(rc == 1);
    printf("Second value in the file: %.1f\n", d);

    fclose(fp);

    // (3) demo error handling
    rc = fsetpos(stdin, &pos);
    if (rc) 
        perror("could not fsetpos stdin");
}
First value in the file: 1.1
First value in the file again: 1.1
Second value in the file: 2.2
could not fsetpos stdin: Bad file descriptor

6 Error handling

clearerr
    clears errors

feof
    checks for the end-of-file

ferror
    checks for a file error

perror
    `displays` a character string corresponding of the `current error to stderr`

feof / ferror 返回類型 int

return 
    NonZero, EOF Flag / Error Flag is set
    0,       false

(1) void clearerr(FILE* stream)

Resets(重置 <=> 取消) EOF indicator 和 Error flag(for given stream)

(2) int feof(FILE* stream)

Checks if EOF indicator (associated with stream) is set
<=>
Checks if `end of (the given file) stream has been reached`

(3) int ferror(FILE* stream)

Check if  Error flags is set
<=>
Checks the given stream for errors. 

(4) void perror(const char *str)

print 系統(tǒng)變量 errno 中存儲(chǔ)的 `error code 的 文本描述` 到 stderr

print: str + 冒號(hào) + 空格 + error code 的 文本描述

#include <stdio.h>
#include <stdlib.h>
// #include <assert.h>

int main(void)
{
    // === (1) 打開 不存在的文件
    FILE* pf= fopen("non_existent", "r");
    if (pf == NULL)
        perror("fopen() failed");
    else 
        fclose(pf);
  
    // === (2) 創(chuàng)建臨時(shí)文件
    FILE* tmpf = tmpfile();

    fputs("abcde\n", tmpf);
    rewind(tmpf);

    int ch;

    // exit: tmpf 文件指針 已越過 the last character => 到達(dá) EOF <=> EOF indicator is set 
    while ( (ch = fgetc(tmpf) ) != EOF) 
        printf("%c", ch);

    if ( feof(tmpf) ) // feof(tmpf) == true/nonZero // assert( feof(pf) ); // true, assert 順利通過
        puts("EOF indicator is set <=> EOF reached successfully");
    else if (ferror(tmpf) ) 
        puts("I/O error when reading");

    clearerr(tmpf);  // clear eof

    if ( feof(tmpf) )
        puts("EOF indicator set");
    else
        puts("EOF indicator cleared\n");
}

Note: 文件位置指針 指向 end-of-file 時(shí), 并 不 set FILE 結(jié)構(gòu)中 EOF flag, 再執(zhí)行一次 讀文件操作, 才會(huì) set EOF flag, 此時(shí)調(diào) feof(fp) 才 return true

=>

問題: feof(fp) -> 讀 -> print 出錯(cuò)
解決: 讀 -> EOF 檢測(cè) (!= EOF 或 !feof(fp) )-> print

solution1: 讀 -> while( ! feof(fp) ) -> print -> 讀

solution2: while (讀 != EOF) -> print

// === Prob:
#include <stdio.h>

int main()
{
    FILE *fp=NULL;
    int ch;

    fp = fopen("myfile.txt","w");
    fputs("abc", fp);  // {a, b, c, end-of-file}
    fclose(fp);

    fp = fopen("myfile.txt","r");
    if(fp == NULL)
        perror ("Error opening file");
        
    // fp: 指向 'c'
    // feof -> 讀   -> 輸出 
    //   feof(fp): return false -> 讀 'c': fp 移到 end-of-file             -> 輸出 'c'
    //   feof(fp): return false -> 讀 end-of-file: p 不移, set EOF flag -> 輸出 EOF
    //   feof(fp): return true  -> exit
    while( !feof(fp) )
    {
        ch = fgetc(fp);   
        printf("%c: %x\n", ch, ch);
    }
    fclose(fp);
}
a: 61
b: 62
c: 63
: ffffffff // EOF 的 hex 值 = 0xffffffff = -1
// === solution1:
#include <stdio.h>

int main()
{
    FILE *fp=NULL;
    int ch;

    fp = fopen("myfile.txt","w");
    fputs("abc", fp);  // {a, b, c, end-of-file}
    fclose(fp);

    fp=fopen("myfile.txt","r");
    if(fp == NULL)
        perror ("Error opening file");
        
    ch = getc ( fp ); 
    while( !feof(fp) )
    {
        printf("%c: %x\n", ch, ch);
        ch = getc(fp);    
    }
    fclose(fp);
}
// === solution2:
#include <stdio.h>

int main()
{
    FILE* fp = NULL;
    int ch;

    fp = fopen("myfile.txt", "w");
    fputs("abc", fp);  // {a, b, c, end-of-file}
    fclose(fp);

    fp = fopen("myfile.txt", "r");
    if (fp == NULL)
        perror("Error opening file");

    while ( (ch = fgetc(fp) ) != EOF)
        printf("%c: %x\n", ch, ch);

    if (fp)
        fclose(fp);
}
a: 61
b: 62
c: 63

7 Operations on files

remove
    erases a file

rename
    renames a file

tmpfile
    returns a pointer to a temporary file

(1) int remove(const char* filename)

(2) int rename(const char* oldFilename, const char* newFilename)

(3) FILE* tmpfile(void)

8 格式化 IO

8.1 從右到左: 將 data 按 格式化輸出 write 到 stream / stdout / buf(char*) / buf

int fprintf (FILE* stream,           const char* format, ...)
int printf  (                        const char* format, ...)
int sprintf (char* buf,              const char* format, ...)
int snprintf(char* buf, size_t size, const char* format, ...)

Return

    傳輸?shù)?字符數(shù), 
    負(fù)數(shù)         ,    output error 

Note

(1) printf: 默認(rèn) 無緩沖

(2) snprintf: size 不應(yīng)該超過 caller 所控制的 buf 區(qū)間

(3) sprintf / snprintf

1) format 中: 最后一個(gè) %s, 無 '\0' -> 加 '\0', 有 '\0' -> 保留; 其他 %s, 去 '\0'

2) 效率 高于 字符串操作函數(shù)

3) 更靈活: 可將 想要的結(jié)果 write到 指定 buf

#include <stdio.h>
int main()
{
    FILE *fp;
    fp = fopen( "file.txt", "w" );

    char name[20] = "xianyang";
    if( fp != NULL )
        fprintf( fp, "hello %s\n", name );

    fclose(fp); 
}
#include <stdio.h>

int main()
{
    char buf[10];
    char str1[] = {'a', 'b', 'c'};
    char str2[] = {'d', 'e', 'f'};

    sprintf(buf, "%.3s%.3s\n", str1, str2); 
    printf("%s", buf);

    //sprintf(buf, "%s%s", str1, str2);       //Don't do that!
}
abcdef

8.2 從 stream / stdin / buf 讀 格式化輸入指定變量

int fscanf(FILE* stream,    const char* format, ...)
int scanf (                 const char* format, ...)
int sscanf(const char* str, const char* format, ...)

Return

    成功匹配和賦值的個(gè)數(shù)(>= 0), success/第1個(gè)賦值就 matching failure   
    EOF                       , input fail 或 end-of-file

Note

[1] 格式字符串中 任何 單個(gè) 空白符 會(huì) 消耗 輸入中 所有 連續(xù)空白符, 好像 循環(huán) isspace

空白符: 空格(" ") 換行("\n") Tab("\t")

[2] 遇 分隔符: 跳過

非 matching 格式的值: 從 input Buffer 跳出, 不跳過 也不取出

(1) scanf 4步曲

    例: 鍵盤輸入 1 2 3

1) 鍵盤輸入字符形式 存入 input Buffer

2) 控制符 %d 將字符 轉(zhuǎn)化為相應(yīng)格式 的 值 (10進(jìn)制 123)

對(duì) %d 而言, 空白符 是 data 分隔符

3) 通過 取地址 i(&i) 找到 變量 i 的地址

4) put 123 to 變量 i

Note

[1] 除非必要, 雙引號(hào)內(nèi) 不要用 非 input 控制符 ( 包括 \n: 不起換行的作用 ), 否則就是 自找麻煩; 而且 對(duì)用戶而言, 輸入越簡(jiǎn)單越好

[2] 多變量輸入 時(shí), input 控制符 之間 要用 空格 回車 Tab 分隔

[3] scanf/printf 中, 非 I/O 控制符原樣 input/output

[4] 每個(gè) scanf 前 clear stdin Buffer, 可從 無殘留的 stdin Buffer 讀取

#include <stdio.h>

// empty stdin_cache
void clear_stdin_cache()
{
    int ch;
    while( (ch = getchar() ) != '\n' && ch != EOF)
        ; 
}

int main()
{
    int a;
    int count;

    scanf("%d", &a); 
    printf("%d\n", a);

    // 清空 stdin 緩存
    // setbuf(stdin, NULL); // 等價(jià)于 clear_stdin_cache(); 
    clear_stdin_cache();

    count = scanf("a= %d", &a);
    if(count > 0)
        printf("a= %d\n", a);
}
image.png

(2) fscanf

[1] 每讀完1項(xiàng), 遇 分隔符 結(jié)束 => fp 指向 "hello " 時(shí), 用 %s 只能取出 "hello", 空格 要用 %c 取出

[2] 與 fgets 區(qū)別: fgets 遇 空格(" ") 不結(jié)束

#include <stdio.h>

int main()
{
    int uVar;
    float fVar;
    char str[100];
    char ch;
    FILE* fp;

    fp = fopen("file.out", "w+");

    if (fp == NULL)
        printf("The file fscanf.out was not opened\n");
    else
    {
        fprintf(fp, "%s %d%f%c", "hello", 10, 3.14159, 'x');

        // set 指針至文件首
        fseek(fp, 0L, SEEK_SET);

        // 從文件中 讀 數(shù)據(jù)
        fscanf(fp, "%s", str);      // Note: 遇 空格 結(jié)束, fp 移動(dòng)到 空格 的 next 位置

        int pos = ftell(fp); 
        printf("%d\n", pos);        // 5: 空格位置

        fscanf(fp, "%2d", &uVar);  // 遇 空格 (對(duì) %s %d 來說是 分隔符): 跳過
        fscanf(fp, "%f", &fVar);
        fscanf(fp, "%c", &ch);

        printf("%s\n", str);
        printf("%d\n", uVar);
        printf("%f\n", fVar);
        printf("%c\n", ch);

        fclose(fp);
    }
}
5
hello
10
3.141590
x

(3) sscanf: %*s: 過濾掉 對(duì)應(yīng)匹配的 %s

#include <stdio.h>
int main()
{
    char buf[50];
    
    // 給定字符串 "hello, world", 僅保留 "world"
    sscanf("hello, world", "%*s%s", buf); // 過濾掉 "hello,"  
    printf("%s\n", buf); //world
}

9 非格式化 I/O: 字符處理函數(shù)

9.1 fputc / putc / putchar: Writes a character to stream / stream / stdout + advances position indicator of stream

return
    寫入的 字符, success
    EOF,         write error-> set Error Flag

(1) int fputc(int ch, FILE* stream)

(2) int putc (int ch, FILE* stream)

(3) int putchar(int ch)

    fputc / putc 僅 1 點(diǎn)不同
        某些 庫(kù)中, putc 用 宏實(shí)現(xiàn)

        putahcr() <=> getc( stdout )

9.2 fgetc / getc / getchar: Read a character from stream/stream/stdin

return
    所讀到的 character 
        提升為 int 值, 以 `include EOF 值`, success
            `file position indicator` 移到 `next character`
        
    EOF, 遇 end-of-file / read Error 
      => `sets EOF/Error Flags => feof() / ferror() == true

Note

里奇開發(fā) C 時(shí), 沒 terminal input 的概念, 輸入 都是從 文件 讀取

文件 為單位, 最后1行 結(jié)束后, 還要用 end-of-file 來標(biāo)志 文件結(jié)束

    => 

遇 newline("\n", 回車 認(rèn)為 == "\n"), 程序才認(rèn)為 輸入 ( scanf getchar gets 等 ) 結(jié)束

(1) int fgetc(FILE* stream );

(2) int getc(FILE* stream );

(3) int getchar ( void );

    fgetc / getc 僅 1 點(diǎn)不同: 某些 庫(kù)中, getc 用 宏實(shí)現(xiàn)
    
    getchar() <=> getc(stdin)
        實(shí)現(xiàn) maybe
        #define getchar() getc(stdin)

fgetc() / getc() 經(jīng)典用法

int c; // (1) note: int, not char, required to handle EOF

// (2) standard C I/O file reading loop
while ( (c = fgetc(fp) ) != EOF ) // 用 getc 也可
{                                       
    putchar(c);
}

if ( ferror(fp) ) 
{
    puts("I/O error when reading");
} 
else if ( feof(fp) ) 
{
    puts("End-of-file reached successfully");
}

getchar: 回車后, '\n' 及 之前字符 放 stdin buf, getchar 才開始 從 stdin buf 讀 1 個(gè)字符, 并 回顯 到屏幕

EOF: end of file

Windows/Unix 值都是 -1

1) 可作 文本文件 結(jié)束標(biāo)志

    文本文件 data 以 `字符 的 ASCII 碼值 ( 0-127 ) ` 存放,
    無 -1

2) 不可作 二進(jìn)制文件 結(jié)束標(biāo)志 -> feof(fp) 可判 二進(jìn)制/文本 文件 是否結(jié)束

    二進(jìn)制文件 有 -1 
#include <stdio.h>

//文本文件 復(fù)制到 另一個(gè)文件
void filecopy( FILE *fpin, FILE *fpout )
{
    int ch;
    
    ch = getc ( fpin );   
    while ( !feof( fpin ) ) 
    {
        putc( ch, fpout ); 
        ch = getc ( fpin ); // fp indicator 指向 EOF -> getc -> return EOF + set feof -> exit while
    } 
}

int main ()
{
    FILE*fpin,*fpout;
    fpin = fopen ("file1.dat","r"); 
    fpout = fopen ("file2.dat","w"); 
    filecopy( fpin,fpout ); 
    fclose ( fpin );
    fclose ( fpout ); 
}
image.png
文件1 依次讀取:
a(97) b(98) \n(10) c(99) -1(end-of-file)

=> windows: 行尾 只有 '\n', 可認(rèn)為 下一行首 '\r' 被 覆蓋

windows 下 輸入 EOF 的方法:回車 -> ctrl + z -> 回車

// 經(jīng)典例子: copy input to output 
#include <stdio.h>
#include <ctype.h>

int main()
{
    int ch;

    while( ( ch = getchar() ) != EOF )
          putchar( tolower( ch ) );
}

9.3 fputs / puts: Write C風(fēng)格字符串 to stream / stdout

Note:

[1] not Write '\0'

[2] fputs/puts: (file)不加 / (stdout)加 newline("\n")

Return 
    >= 0, success
    EOF,  error -> + sets Error Flag

(1) int fputs(const char* buf, FILE* stream);

(2) int puts (const char* buf);

9.4 fgets / gets: 從 stream/stdin Read a line(1行)

Note:

[1] fgets/gets: newline copied into buf / 去 newline ( 遇 newline, not copied into buf )

[2] 加 '\0'

return
    buf,  success
    NULL, end-of-file 或 read error -> + `sets EOF/Error Flags

(1) char* fgets(char* buf, int n, FILE* stream)

讀 `stream`, until

    1) `讀 n-1 個(gè)字符`
    
    2) 遇 newline
    3) 遇 end-of-file 

    whichever happens first

(2) char* gets (char* buf) // stdin

讀 `stdin`, until
    1) 遇 newline
    2) 遇 end-of-file 

    whichever happens first
#include <stdio.h>
int main()
{
    char str[50];
    gets(str);
    printf("%s", str);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市预茄,隨后出現(xiàn)的幾起案子幅骄,更是在濱河造成了極大的恐慌,老刑警劉巖仲墨,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡色鸳,警方通過查閱死者的電腦和手機(jī)琉历,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門坠七,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人旗笔,你說我怎么就攤上這事彪置。” “怎么了蝇恶?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵拳魁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我撮弧,道長(zhǎng)潘懊,這世上最難降的妖魔是什么姚糊? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮授舟,結(jié)果婚禮上救恨,老公的妹妹穿的比我還像新娘。我一直安慰自己岂却,他們只是感情好忿薇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躏哩,像睡著了一般署浩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扫尺,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天筋栋,我揣著相機(jī)與錄音,去河邊找鬼正驻。 笑死弊攘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姑曙。 我是一名探鬼主播襟交,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼伤靠!你這毒婦竟也來了捣域?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤宴合,失蹤者是張志新(化名)和其女友劉穎焕梅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卦洽,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贞言,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阀蒂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片该窗。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蚤霞,靈堂內(nèi)的尸體忽然破棺而出酗失,到底是詐尸還是另有隱情,我是刑警寧澤争便,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站断医,受9級(jí)特大地震影響滞乙,放射性物質(zhì)發(fā)生泄漏奏纪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一斩启、第九天 我趴在偏房一處隱蔽的房頂上張望序调。 院中可真熱鬧,春花似錦兔簇、人聲如沸发绢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)边酒。三九已至,卻和暖如春狸窘,著一層夾襖步出監(jiān)牢的瞬間墩朦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工翻擒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氓涣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓陋气,卻偏偏與公主長(zhǎng)得像劳吠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巩趁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容