使用龟etc逐行读取C文件行() [英] Reading c file line by line using fgetc()

查看:108
本文介绍了使用龟etc逐行读取C文件行()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是多么我已经做到了,但我不知道这是preferred成语:

This is how I've done it but I'm not sure this is the preferred idiom:

FILE *fp = fopen(argv[0], "r");
// handle fopen() returning NULL

while (!feof(fp)) {
    char buffer[80]; // statically allocated, may replace this later with some more sophisticated approach
    int num_chars = 0;

    for (int ch = fgetc(fp); ch != EOF && ch != '\n'; ch = fgetc()) {
        buffer[num_chars++] = ch;
    }

    // null-terminate the string
    buffer[num_chars] = '\0';

    printf("%s\n", buffer);
}

这是好的,任何改善这个建议吗?

Is this okay, any suggestions to improve this?

推荐答案

如果你不打算使用与fgets()(可能是因为你要删除的换行符,或者你要处理的为\\ r\\ n\\ r \\ N行尾,或者你想知道有多少个字符分别读),你可以使用这个作为骨架功能:

If you are not going to use fgets() (perhaps because you want to remove the newline, or you want to deal with "\r", "\n" or "\r\n" line endings, or you want to know how many characters were read), you can use this as a skeleton function:

int get_line(FILE *fp, char *buffer, size_t buflen)
{
    char *end = buffer + buflen - 1; /* Allow space for null terminator */
    char *dst = buffer;
    int c;
    while ((c = getc(fp)) != EOF && c != '\n' && dst < end)
        *dst++ = c;
    *dst = '\0';
    return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}

据只承认换行的行末;它丢弃的换行符。它不溢出缓冲区;它不丢弃多余的字符,所以如果被要求阅读一个很长的线,它会读取数据块的行;它返回读取的字符的数目。如果你需要的溢出和恰好是缓冲区的长度的线来区分 - 1,那么你可能需要preserve换行符 - 与code相应的修改:

It recognizes only newline as the end of line; it drops the newline. It does not overflow the buffer; it does not discard excess characters, so if called upon to read a very long line, it will read the line in chunks; it returns the number of characters read. If you need to distinguish between overflow and a line that happens to be the length of the buffer - 1, then you probably need to preserve the newline - with consequential changes in the code:

int get_line(FILE *fp, char *buffer, size_t buflen)
{
    char *end = buffer + buflen - 1; /* Allow space for null terminator */
    char *dst = buffer;
    int c;
    while ((c = getc(fp)) != EOF && dst < end)
    {
        if ((*dst++ = c) == '\n')
            break;
    }
    *dst = '\0';
    return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}

有在这无尽的轻微变种,如丢弃任何多余的字符,如果该行已被截断。如果你想处理DOS,(旧)的Mac或Unix行结尾,然后借用叶出从的编程的实践由Kernighan的&放的;派克(的优秀图书),并使用:

There are endless minor variants on this, such as discarding any excess characters if the line has to be truncated. If you want to handle DOS, (old) Mac or Unix line endings, then borrow a leaf out of the CSV code from "The Practice of Programming" by Kernighan & Pike (an excellent book) and use:

static int endofline(FILE *ifp, int c)
{
    int eol = (c == '\r' || c == '\n');
    if (c == '\r')
    {
        c = getc(ifp);
        if (c != '\n' && c != EOF)
            ungetc(c, ifp);
    }
    return(eol);
}

然后你可以使用代替的C ='\\ n'测试:

int get_line(FILE *fp, char *buffer, size_t buflen)
{
    char *end = buffer + buflen - 1; /* Allow space for null terminator */
    char *dst = buffer;
    int c;
    while ((c = getc(fp)) != EOF && !endofline(fp, c) && dst < end)
        *dst++ = c;
    *dst = '\0';
    return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}


在整个过程处理使用的其他替代方法 FREAD()的fwrite()

void copy_file(FILE *in, FILE *out)
{
    char buffer[4096];
    size_t nbytes;
    while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), in)) != 0)
    {
        if (fwrite(buffer, sizeof(char), nbytes, out) != nbytes)
            err_error("Failed to write %zu bytes\n", nbytes);
    }
}

在上下文中,你会打开该文件,并检查其有效性,然后调用:

In context, you'd open the file and check it for validity, then call:

copy_file(fp, stdout);

这篇关于使用龟etc逐行读取C文件行()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆