2016-02-10 47 views
2

我有一个关于文件指针的基本问题。在下面的代码中,我有一个while循环,然后是for循环。 for循环只会显示行数,除非我再次打开fopen - 是否正常?如果是这样,我应该预先在while循环之后吗?可能有一些我没有意识到的“倒带”功能,所以我的整个方法可能是错误的。我意识到while循环和for可以合并,但是这个我的问题是关于fopen,fclose并且再次使用来自fopen的数据。正确使用文件指针

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

#define MAXLEN 200 

enum { MAXLINES = 200 }; 
char lpath[MAXLINES][BUFSIZ]; 

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

     char c; 
     int l = 0, n = 0, i = 0, count = 0; 
     char lines[MAXLINES][BUFSIZ]; 

     FILE *fp = fopen(argv[1], "r"); 

     if (fp == 0) { 
       fprintf(stderr, "failed to open input.txt\n"); 
       exit(1); 
     } 

     while (l < MAXLINES && fgets(lines[l], sizeof(lines[0]), fp)) { 
       lines[l][strlen(lines[l])-1] = '\0'; 
       puts(lines[l]); 
       l++; 
     } 

     // fp = fopen(argv[1], "r"); // below won't output unless fopen again 
     for (c = getc(fp); c != EOF; c = getc(fp)) { 
      if (c == '\n') { 
       count++; 

     } 
     printf(">> line count: %i", count); 

     fclose(fp); 
} 

又看了看:Pointer best practice

+0

1)更好地利用'fgetc'。 2)'都返回一个'int',而不是'char。 3)因此,你的'EOF'测试是错误的,并且如果'char'是未签名的将会总是失败! – Olaf

+0

@Olaf:我从这里得到了这段代码:http://stackoverflow.com/a/4237107/5905926,所以也许让他们知道......谢谢 –

+0

“可能有一些”倒带“功能,我不知道“ - 有!事实上,它被称为“倒带”。 – immibis

回答

5

这是正常的,你需要rewind()文件。问题是,当for循环启动时文件已达到结尾,因此读取将失败,feof()将返回非零值。

两个选项

rewind(fp); 

或者

fseek(fp, 0L, SEEK_SET); 

当你调用fopen()再次因为您覆盖指针您泄漏资源,现在你不能fclose()第一fopen()编辑文件。

+0

谢谢 - 我想这是它) –

0

你可以使用rewind()作为@iharob建议,或者您也可以关闭并重新打开文件:

while (l < MAXLINES && fgets(lines[l], sizeof(lines[0]), fp)) { 
      lines[l][strlen(lines[l])-1] = '\0'; 
      puts(lines[l]); 
      l++; 
} 

fclose(fp); 
fp = fopen(argv[1], "r"); // below won't output unless fopen again 
for (c = getc(fp); c != EOF; c = getc(fp)) { 
    if (c == '\n') { 
     count++; 
    } 
}