2

我需要读入一个文件,然后将其打印到 STDOUT 但双倍行距。到目前为止,我所拥有的是:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define BUFSZ 1024

int main(int argc, char* argv[]){

int n, fdin;
char buf[BUFSZ];

if ((fdin=open(argv[1],O_RDONLY))<0){
  perror(argv[1]);
  exit(-1);
}
while(( n = read(fdin, buf, BUFSZ))>0){
 if(write(STDOUT_FILENO,buf,n) != n){
  fprintf(stderr, "Write Error\n");
  exit(-1);
 }
 printf("\n");
}
close(fdin);
return(0);
}

我是 C 新手,不知道如何将 \n 实现到代码中,我的 printf("\n") 在尝试将整个文件的内容加倍时毫无用处。我想我必须将 \n 添加到读取中?但我不完全确定这是否正确或如何去做。

4

3 回答 3

7

read()遇到换行符时不会停止读取,因此发布代码中的算法很容易错过写入空行,因为它read()可以读取多行。

更简单的方法是使用fgets()

FILE* f = fopen(argv[1], "r");
if (f)
{
    char buf[BUFSZ];
    while (fgets(buf, BUFSZ, f))
    {
        printf("%s", buf);

        /* fgets() may not have read a full line if the
           length of the line was greater than BUFSZ,
           so check it did before double spacing. */
        if (strrchr(buf, '\n')) printf("\n");
    }
    fclose(f);
}
于 2012-11-01T22:27:55.930 回答
2

openclose和函数是 Unix 特有的(实际上是 POSIX)readwriteC 语言标准提供了一组更高级别的函数(fopenfclose以及许多输入和输出函数),这里没有充分的理由不使用它们。任何具有 POSIX 特定函数的系统都将具有标准的 C 函数;反过来不一定正确。

我不确定我应该给你完整解决方案的代码(这是作业吗?),但我会给你一个快速的大纲。

无需读取和写入整行。这个问题很容易通过读取和写入单个字符来解决——C 的 I/O 函数会进行隐式缓冲,因此不会导致任何重大的性能问题。

“行”只是由换行符终止的字符序列'\n'。(不必担心不同的行尾表示,例如\r\nWindows 使用的;如果您以文本模式打开文件,C 库将负责与 C 的内部'\n'表示进行转换。)

从输入文件中一次读取一个字符。对于您读取的每个字符,将相同的字符写入您的标准输出。此外,如果输入字符是,则将一秒'\n'写入标准输出。 '\n'

有类似的问题需要一次将整行读取到内存中(这意味着您需要担心一行可以有多长),但对于这个特定问题,这不是必需的。

于 2012-11-01T22:47:43.360 回答
1

使用 fgets puts 和 putc,它更简单和缓冲。并且 fgets 读取行,

int main(int argc, char* argv[]){
    FILE *fp;
    char *s;
    char buf[BUFSZ];
    if ((fp = fopen(argv[1],"r")) == NULL) {
        fprintf(stderr, "Error opening %s\n", argv[1] );
        exit(-1);
    }
    while((s = fgets(buf, sizeof buf, fp)) != NULL){
        puts(s);
        putchar('\n');
    }
    fclose(fp);
    return(0);
}
于 2012-11-01T22:29:28.557 回答