grep Simulation Using Only Unbuffered I/O - C

 
Thread Tools Search this Thread
Homework and Emergencies Homework & Coursework Questions grep Simulation Using Only Unbuffered I/O - C
# 1  
Old 04-17-2011
Data grep Simulation Using Only Unbuffered I/O - C

1. The problem statement, all variables and given/known data:
Basically, I'm trying to search for a particular string pattern within a text file and print "textfile: line_no line". I need to read this in line at a time, but I'm restricted to using unbuffered I/O functions. I'm not sure if I'm missing something minor or if I'm misunderstanding how this works. The idea was to read() a small buffer (size 50), then to move the buffer over character at a time into a temp array until a newline is reached. Then use strstr to determine if the pattern occurs in the temp array, and if so, print the temp array to the screen.

I am reasonably sure that the problem lies within moving the buffer over to a temp array, and possibly with memset. Also, possible with read, because I keep getting a byte of trash every time I read into buf.

The output I'm getting for buf makes it appear that lseek is working perfectly fine, however, the temp array appears to be getting buf twice.

2. Relevant commands, code, scripts, algorithms:
Command used in bash shell: ./mycp <pattern> <filename>

3. The attempts at a solution (include all code and scripts):
I've attempted altering this line several times:
Code:
while (buf[i] != NULL)

In place of "NULL", I've also used '/0' and '/n'. I've also tried strcpy() instead of copying over one character at a time. I get similar output, but amount of trash varies.

Code:
// includes
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

// defines
#define max             50

int main(int argc, char *argv[])
{
        char    *buf[max];
        char    *temp[max];
        char    *ptr;
        int     *infile;
        int     n;
        int     i = 0;
        //int     j = 0;
        int     count = 0;              // track line number
        int     occurences = 0;         // track # of occurences
        int     offsetSum = 0;          // track file offset position

        if (argc != 3)
        {
                printf("usage: ./mygrep pattern filename\n");
                exit(1);
        }

        if ((infile = open(argv[2], O_RDONLY)) == -1)
        {
                printf("Unable to open file: %s\n", argv[2]);
                exit(1);
        }

        memset(temp, '\0', max);                // set for first use

        while ((n = read(infile, buf, max)) > 0 /*&& j < 10*/)  // while !EOF
        {
                count++;        // keep up with line number
                while (buf[i] != NULL)                                  // while in buf & not end of line
                {
                        temp[i] = buf[i];                               // copy one char at time into temp
                        i++;
                        offsetSum++;
                }
                if ((ptr = strstr(temp, argv[1])) != NULL);             // if pattern found
                {
                        printf("%s: %d %s\n", argv[2], count, temp);
                        occurences++;
                }

                if (lseek(infile, offsetSum, SEEK_SET) < 0)             // reset file position for
                        error("Error while reading file: ", infile);    // next read
                i = 0;                          // reset for next use
                memset(temp, '\0', max);        // reset for next use
                //j++;
        }
        printf("Number of occurences of %s : %d\n", argv[1], occurences);
        close(infile);
        return 0;
}


4. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course):
Arkansas State University, Jonesboro, AR, USA - Dr. Jiang CS4223

Thank you in advance for any help you can offer!
# 2  
Old 04-17-2011
read() doesn't add NULLs to the end of your array, so checking for NULL won't work. read() DOES return how many bytes it read, so you could just stop there instead, but --

read() doesn't stop at the end of a line, either. You should read one by one and check for newlines yourself. You could try something like this:

Code:
// reads a line of text in a manner sort of like fgets, and adds null.
// returns the # of bytes read, 0 means error.
int my_getline(int fd, char *buf, int max)
{
        int n;
        // read until end of file, or newline, or max
        for(n=0; n<(max-1); n++)
        {
                 ssize_t b=read(fd, buf+n, 1); // read one byte
                 if(b <= 0) // end of file or error
                 {
                         buf[n]='\0'; // add null
                         return(n);
                 }
                 if(buf[n] == '\n') // end of line
                 {
                         buf[n+1]='\0'; // add null AFTER \n
                         return(n);
                 }
        }

        buf[n]='\0';
        return(n);
}

This User Gave Thanks to Corona688 For This Post:
# 3  
Old 04-17-2011
Thank you for the help! Using your suggestion, I rewrote my own getline to serve the purpose I needed:

Code:
int getline(int infile, char *buf, char *pattern)
{
        int n;
        int count = 0;          // track line number
        int occurences = 0;     // track number of occurences

        for (n = 0; n < (max - 1); n++) // while not EOF--b will grab each read
        {

                // point of this section is to read one byte at a time until end of line
                ssize_t b = read(infile, buf + n, 1);   // read one byte at a time
                if (b <= 0)                     // EOF or error
                {
                        buf[n] = '\0';
                        if (b == -1)
                                error("Error while reading file %s\n", infile);
                }

                if (buf[n] == '\n')     // end of line
                {
                        count++;
                        buf[n+1] = '\0';
                        occurences += checkPattern(pattern, buf, count);
                        n = -1;
                }
        }

        buf[n] = '\0';
        return occurences;
}

# 4  
Old 04-18-2011
You forgot to break on error or end-of-line, if you don't your for() loop won't actually stop.

Also this: buf[n+1] = '\0'; Remember, the code you copied that from added the \n to the data. That's why it needed +1, to not overwrite th \n. When not adding the \n, n+1 goes one too far, leaving a garbage byte in your string.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Cybersecurity

DDoS Simulation Tools

are there any popular DDoS simulation tools to test my own infrastructure? Anyone tried to setup all these in AWS EC2? (1 Reply)
Discussion started by: boriskong
1 Replies

2. IP Networking

OLSR simulation in ns2

# Create the simulator object that we need in order to run NS set ns # Set the parameters that we will use for wireless communications set val(chan) Channel/WirelessChannel ;# channel type set val(prop) Propagation/TwoRayGround ;# radio-propagation model set... (0 Replies)
Discussion started by: amithkhandakar
0 Replies

3. UNIX for Dummies Questions & Answers

Simulation of an ATM interface

Hi guys, I recently discovered this problem and any help would be great. 1) Create a file in vi named Accounts_File with the following data: The user, the name, the pin number, current balance and transaction history. There are 3 users who need to be inputted with all their PIN, etc... (1 Reply)
Discussion started by: Jimmy_c
1 Replies

4. UNIX and Linux Applications

2D collision simulation-programming

Hello, everybody, I'm thankful for the great helps you gave during the past year. Now I'm facing a serious problem: I was obliged to write a 2D collision simulation applet, and my experience is only in C,C++,Intelx86 assembly. I have no experience in Java and the like, and I don't know... (2 Replies)
Discussion started by: JackCrital2005
2 Replies

5. Programming

Simulation using C/C++ and Java

Hi, I'm just start to learning simulate a network protocol using C/C++ and Java from scratch. Actually, I want to make two nodes can communicate using TCP and UDP protocol, for example http connection and video streaming, respectively. Can anyone help me find several references or guidance... (0 Replies)
Discussion started by: nica
0 Replies

6. Shell Programming and Scripting

Remote simulation and 'at' command

Hey, Task seems to be quite easy, but I'm still a bit green in shell scripting. I hope you can help me a bit. I have to run some simulation at the distance by remote terminal. Normally when I'm working on the server directly I just type: mpirun -np 8 compressibleInterFoam -parallel > log.txt... (7 Replies)
Discussion started by: PiPrus
7 Replies

7. Solaris

Results Load Simulation

If i simulate a load on a solaris system to choke the system to 90% CPU usage .. what is likely to increase .. my systems fan rpms, cpu temperature, power drawn .. Can anybody tell me (4 Replies)
Discussion started by: fugitive
4 Replies

8. Windows & DOS: Issues & Discussions

unix simulation

hello everybody.. im new to this forum.. i have sme basic knowledge about unix.. but not too much.. i would like to practice shell programs n perl using a unix simulator.. but then i don't know wht a unix simulator means? just a bald definition that it creates a unix working environment in windows... (5 Replies)
Discussion started by: esash
5 Replies

9. Programming

unbuffered streams.

#include "../ourhdr.h" int main(void) { int c; char *buf; setvbuf(stdin,buf,_IONBF,10); setvbuf(stdout,buf,_IONBF,10); while((c=getc(stdin)) != EOF) { if(putc(c,stdout) == EOF) err_sys("output... (2 Replies)
Discussion started by: gandhevinod
2 Replies

10. Shell Programming and Scripting

Help capturing and reformatting buffered and unbuffered output

Ok, so I have a shell script which runs a specific command, and that command sends it's output to the display. At certain times, the command sends buffered output, and at other times, the command sends unbuffered output in the form of a % progress bar, so if I run the command, the output I receive... (0 Replies)
Discussion started by: vikingshelmut
0 Replies
Login or Register to Ask a Question