簡體   English   中英

閱讀文本文件 C 編程中的下一行

[英]Read next line in Text file C Programming

我知道fscanf()、fgets()和其他用於讀取文本文件下一行的函數。 但是,如果您通過'cat msg1.txt |獲得一個文本文件 ./anonymizer'你會使用相同的功能嗎? 對於我的程序,主要代碼是:

int main (void)
{
    char input[1000]= {'\0'}; //the sentence the user will enter
    printf("Enter a sentence:");
    scanf("%[^\n]", input);
    char newSentence[1000]={'\0'};
    sentence=(char *) &newSentence;
    line=getText(input,0);
    divide(input);
    printf("%s\n",sentence);
    return 0;
}

在命令行中我輸入:

gcc -o anonymizer anonymizer.c
cat msg1.txt | ./anonymizer

我的 msg1 文本文件包含:

嗨,我的電子郵件地址是 h.potter@hogwarts.edu 和 1a@2b3c@lkj@ 雖然它不是電子郵件地址,但我不喜歡如果@你看到我的秘密@word。 Gary.zenkel@nbcuni.comHoever,輸入變量只包含第一行:'嗨,我的電子郵件地址是 h.potter@hogwarts.edu 和 1a@2b3c@lkj@'

如何讓輸入變量包含其他兩行?

幾乎。 雖然它實際上可能不是以這種方式定義的,但scanf(...)本質上等同於fscanf(stdin, ...) 類似於gets / fgets 您應該能夠使用其中任何一個來讀取您的標准輸入流。

據我有限的知識(我可能是錯的),使用標准 libc,當您不知道最大行長度時,沒有有效的方法來讀取一行。 scanf()gets()可能會導致內存溢出,因為它們不檢查緩沖區的長度。 如果您使用fgets() ,您可能會在頻繁使用strlen()realloc()上浪費時間。 如果您使用fgetc() ,它會很慢,因為fgetc()有巨大的開銷。

為了有效地讀取行,我們必須保留一些中間信息。 這並不容易。 我正在附上一個實現。 它相當復雜,但非常高效和通用。 如果你不關心細節,你可能只關注main()函數關於如何使用例程。

試試這個程序:

gcc -Wall prog.c; ./a.out < input.txt > output.txt

程序:

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

#ifndef kroundup32
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
#endif

#define kstype_t FILE* // type of file handler
#define ksread_f(fp, buf, len) fread((buf), 1, (len), (fp)) // function to read a data chunk

typedef struct {
    int l, m; // l: length of string; m: allocated size
    char *s; // string
} kstring_t;

typedef struct {
    kstype_t f; // file handler
    int begin, end, is_eof, bufsize;
    unsigned char *buf; // buffer
} kstream_t;

kstream_t *ks_open(kstype_t fp, int bufsize)
{
    kstream_t *ks;
    ks = (kstream_t*)calloc(1, sizeof(kstream_t));
    ks->bufsize = bufsize;
    ks->buf = (unsigned char*)malloc(bufsize);
    ks->f = fp;
    return ks;
}

void ks_close(kstream_t *ks)
{
    free(ks->buf); free(ks);
}

int ks_readline(kstream_t *ks, int delimiter, kstring_t *str)
{
    str->l = 0;
    if (ks->begin >= ks->end && ks->is_eof) return -1;
    for (;;) {
        int i;
        if (ks->begin >= ks->end) {
            if (!ks->is_eof) {
                ks->begin = 0;
                ks->end = ksread_f(ks->f, ks->buf, ks->bufsize);
                if (ks->end < ks->bufsize) ks->is_eof = 1;
                if (ks->end == 0) break;
            } else break;
        }
        for (i = ks->begin; i < ks->end; ++i)
            if (ks->buf[i] == delimiter) break;
        if (str->m - str->l < i - ks->begin + 1) {
            str->m = str->l + (i - ks->begin) + 1;
            kroundup32(str->m);
            str->s = (char*)realloc(str->s, str->m);
        }
        memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin);
        str->l = str->l + (i - ks->begin);
        ks->begin = i + 1;
        if (i < ks->end) break;
    }
    if (str->s == 0) {
        str->m = 1;
        str->s = (char*)calloc(1, 1);
    }
    str->s[str->l] = '\0';
    return str->l;
}

int main()
{
    kstream_t *ks;
    kstring_t str;
    str.l = str.m = 0; str.s = 0; // initialize the string struct
    ks = ks_open(stdin, 4096); // initialize the file handler
    while (ks_readline(ks, '\n', &str) >= 0) // read each line
        puts(str.s); // print it out
    ks_close(ks); free(str.s); // free
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM