Arjun Dhiman
Arjun Dhiman

Reputation: 154

How to read a specific amount of lines from a file in C

My question is that I am trying to read only a certain amount of files given n files.

For example, I have the two files with the following content inside then

test1:

A cat ran off

Apple

test2:

The boy went home

Apples are red

I want the output to be

test1: A cat ran off

Not

test1: A cat ran off

test2: Apples are red

This is the code that I have written so far:

#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);
}

Upvotes: 0

Views: 460

Answers (1)

David C. Rankin
David C. Rankin

Reputation: 84642

Continuing from the comments, and noting you will need to remove the trailing newline included by fgets, you could do something like the following:

#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;
}

Example Input Files

$ cat test1
A cat ran off
Apple

$ cat test2
The boy went home
Apples are red

Example Use/Output

You understand iterating with argc-- your files are processed in reverse, so you will end up with output like:

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

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

note: to process the files in order, just do something like for (i = 1; i < argc; i++) instead of while (argc--). Let me know if you have further questions.

Changing to the for loop instead of the while in main and inputting 10 as the number of occurrences to look for, all files are processed, e.g.:

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

Upvotes: 1

Related Questions