[英]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.