【问题标题】:How to read a specific amount of lines from a file in C如何从C中的文件中读取特定数量的行
【发布时间】:2016-06-26 06:26:06
【问题描述】:

我的问题是,在给定 n 个文件的情况下,我试图只读取一定数量的文件。

比如我有两个文件,里面内容如下

测试1:

一只猫跑了

苹果

测试2:

男孩回家了

苹果是红色的

我希望输出是

test1:一只猫跑掉了

不是

test1:一只猫跑掉了

test2:苹果是红色的

这是我目前写的代码:

#include <stdio.h>
#include <string.h>
int main (int argc, char ** argv)
 {
   extern int searcher(char * name, char*search,int amount);
   while(argc != 0){
   if(argv[argc] !=NULL)
     if(searcher(argv[argc],"a",1)) break;
     argc-- ;
   }
}

int searcher(char * name, char*search,int amount){

FILE *file = fopen (name, "r" );
int count = 0;

if (file != NULL) {
  char line [1000];
while(fgets(line,sizeof line,file)!= NULL && count != amount)
 {
  if(strstr(line,search) !=NULL){
    count++;
    if(count == amount){
      return(count);
    }
    printf("%s:%s\n", line,name);
  }
}

fclose(file);
}else {
    perror(name); //print the error message on stderr.
  }
 return(0);
}

【问题讨论】:

  • 记住fgets一次读一行,你可以轻松设置一个计数器并做while (count &lt; x &amp;&amp; fgets (.....)) {...}
  • 你能告诉我你的意思吗?请在上面的代码中添加编辑。
  • 当然,但在我举个例子之前,你想从每个文件中读取多少行?或者你是在每个文件中搜索一个术语。看起来您正在尝试搜索(这很好),但这与从文件中严格读取 X 行数是分开的。两者都需要吗?
  • 请更新您的问题并具体说明文件。目前,标题与问题第一行的内容不一致。此外,问题的任何澄清都需要在问题本身中,而不是在 cmets 中。
  • @Kusalananda:在获得答案之前进行了更改。由于时间短,目前处于dubio pro reo中。

标签: c file output


【解决方案1】:

从 cmets 继续,并注意您需要删除 fgets 包含的尾随 newline,您可以执行以下操作:

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

enum { MAXC = 1000 };

int searcher (char *name, char *search, int amount);
void rmlf (char *s);

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

    for (i = 1; i < argc; i++)
        if (searcher (argv[i], "a", 1))
            break;

    return 0;
}

int searcher (char *name, char *search, int amount)
{
    FILE *file = fopen (name, "r");
    int count = 0;

    if (!file) {
        fprintf (stderr, "error: file open failed '%s'.\n", name);
        return 0;
    }

    char line[MAXC] = "";
    while (count < amount && fgets (line, MAXC, file)) {
        rmlf (line);                    /* strip trailing \n from line */
        if (strstr (line, search)) {
            count++;
            printf ("%s: %s\n", name, line);
        }
    }

    fclose (file);
    return count == amount ? count : 0;
}

/** stip trailing newlines and carraige returns by overwriting with
 *  null-terminating char. str is modified in place.
 */
void rmlf (char *s)
{
    if (!s || !*s) return;
    for (; *s && *s != '\n'; s++) {}
    *s = 0;
}

输入文件示例

$ cat test1
A cat ran off
Apple

$ cat test2
The boy went home
Apples are red

使用/输出示例

您了解使用 argc-- 进行迭代,您的文件会被反向处理,因此您最终会得到如下输出:

$ ./bin/searcher test2 test1
test1: A cat ran off

$ ./bin/searcher test1 test2
test2: Apples are red

注意:要按顺序处理文件,只需执行for (i = 1; i &lt; argc; i++) 之类的操作,而不是while (argc--)。如果您还有其他问题,请告诉我。

更改为for 循环而不是main 中的while 并输入10 作为要查找的出现次数,处理所有 文件,例如:

$ ./bin/searcher test1 test2
test1: A cat ran off
test2: Apples are red

【讨论】:

  • 为什么去掉新行很重要?
  • 只需注释掉我的rmlf,然后告诉我:) 记住fgets line 中读取并包含尾随换行符。当您打印nameline 时会发生什么?
  • 真的需要枚举吗?我不能只使用 char size[1000] 然后 sizeof size;
  • 不需要,它只是声明多个常量的一种方便方式。您希望避免在整个代码中硬编码 magic numbers,但出于本示例的目的,您可以对其进行核对。
  • 当然,C 需要时间来学习。没有其他语言可以为您提供如此多的控制(除了汇编),并且随之而来的是很多责任。不要指望一晚上就能学会。祝你编码顺利。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多