我知道 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 @ 虽然它不是电子邮件地址,但我讨厌@如果你看到了我的电子邮件地址 悄悄话。 Gary.zenkel@nbcuni.com然而,仅输入变量 包含第一行:'嗨,我的电子邮件地址是 h.potter@hogwarts.edu和1a @ 2b3c @ lkj @'
如何让输入变量包含其他两行?
答案 0 :(得分:0)
几乎。虽然实际上可能没有以这种方式定义,scanf(...)
基本上等同于fscanf(stdin, ...)
。类似于gets
/ fgets
。您应该能够使用其中一个来读取标准输入流。
答案 1 :(得分:0)
对于我有限的知识(我可能是错的),使用标准的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;
}