0
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/types.h> 
#include <sys/stat.h>
#include <unistd.h>
#include<string.h>
#include <fcntl.h>

void match_pattern(char *argv[])
{
    int fd,r,j=0;
    char temp,line[100];
    if((fd=open(argv[2],O_RDONLY)) != -1)
    {
        while((r=read(fd,&temp,sizeof(char)))!= 0)
        {
            if(temp!='\n')
            {
                line[j]=temp;
                j++;
            }
            else
            {
                if(strstr(line,argv[1])!=NULL)
                    printf("%s\n",line);
                memset(line,0,sizeof(line));
                j=0;
            }

        }
    }   
}

main(int argc,char *argv[])
{
    struct stat stt;
    if(argc==3)
    {
        if(stat(argv[2],&stt)==0)
            match_pattern(argv);
        else 
        {
            perror("stat()");
            exit(1);
        }
    }
}

Contents of file:

arunds ghh
sdf
hi
hello dude
am arun

My output:

./mygrep arun file
arunds ghh
am arun

Am getting correct output

Content of file:

arun arundfdf arun
arunds ghh
sdf

My output:

./mygrep arun file
arun arundfdf arun �5
arunds ghh

I have no idea why some unwanted characters getting printed.

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • If performance is of any interest, read to buffer, and then get from buffer char-by-char. Overhead of read() is really quite big. So basically, reimplement stdio getchar. – hyde Feb 05 '13 at 16:46

2 Answers2

2

You never NULL-terminate your line buffer, so it will overflow after the end. Run the memset call also after you declared the line variable.

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • Thank you so much!! I added line[j]='\0' above if(strstr(line,argv[1])!=NULL) –  Feb 05 '13 at 15:18
0

You need to null-terminate the line but why do you read it one character at a time ? you could read whole lines with fgets() which will null-terminate the buffer for you:

while (fgets(line, sizeof(line), file)) {
   if (strstr(line, argv[1])) {
    ...
   }
}

Also this will make sure you don't overflow the 100 bytes buffer you allocate.

iabdalkader
  • 17,009
  • 4
  • 47
  • 74
  • @BartFriederichs yup that's another issue. – iabdalkader Feb 05 '13 at 15:26
  • actually I need to use only system calls –  Feb 05 '13 at 15:26
  • @user1958241 those are not system calls, those are functions in the standard C library even read() is a function :) anyway, at least make sure you don't read more than 99 bytes – iabdalkader Feb 05 '13 at 15:29
  • 1
    As far as i know, fgets() is a function and it is in Standard C but read() is a unix system call. –  Feb 05 '13 at 15:52
  • 1
    @user1958241 `read()` is just a wrapper that calls the kernel and passes the read system call number and arguments, I'm sure your assignment doesn't require using real system calls. see this if you want to understand the difference. http://stackoverflow.com/questions/2668747/system-call-vs-function-call – iabdalkader Feb 05 '13 at 15:58