Reputation: 1
I have a file storing data of students in the following order:
id
(space) name
(space) address
Below is the content of the file:
10 john manchester
11 sam springfield
12 samuel glasgow
Each data is stored in a newline.
I want to search the student with id
10 and display his/her details using the lseek
command, however I'm not to complete the task. Any help is appreciated.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void main() {
char line[50] = "";
char id[2] = "";
ssize_t fd = open("file.dat", O_RDONLY);
while(read(fd,line,sizeof(line))>0){
if (id[0] == '1' && id[1] == '0'){
printf("%s\n",line);
}
lseek(fd, 1 ,SEEK_CUR);
}
close(fd);
Upvotes: 0
Views: 970
Reputation: 12668
Your file has a first line that has 18 characters, a second line with the same number of characters, and a third one with one less (17) number of characters.
In case you have a four line in which the name for example makes the number of characters different, they should be appended to the file without any other structure.
Lines are delimited by \n
characters, that can appear at any point, so second line starts as soon as just behind the first appearance of the \n
char.
For this reason, you don't know the precise position where each line begins, and so you cannot know the exact position where each line begins, as the position of each line is (n + 1)
bytes forward from twhere the previous line started, where n
is the number of characters you put in the previous line, plus one (for the new line character).
You need an index, which is a file that allows you to get, on a fixed length record, to store the starting positions of each line in the data file. In this way, to read line i
, you access the index at position (record_index_size * i)
, and get the position of the starting point of line i
. Then you go to the data file, and position your file pointer to the value obtained from the las calculation, and read that with, for example fgets(3)
.
To build the index, you need to call ftell()
right before each call to fgets()
, because the call to fgets()
will move the pointer, and so the position obtained will not be correct. Try to write the position in a fixed length format, e.g. binary form, with:
write(ix_fd, position, sizeof position);
so the position of line i
, can be calculated by reading from index at position i * sizeof position
.
Upvotes: 0
Reputation: 5830
Use the right tools for the task. Hammer for nails, Screwdriver for screws.
lseek
is not the right tool here, since lseek
is for repositioning the file offset (which you do not have yet, you are looking for a specific position, when found, then you don't have a need for repositioning the file offset, since you are already there).
Ask yourself,
What is your task:
What do you have:
Your dataset is separated by a newline, and the id is the first field of that row. The keywords here are 'newline' and 'first field'.
The right procedure here would be:
fgets
)strcmp
)Example:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
//return value of main
int ret = EXIT_FAILURE;
//open filestream in read mode
FILE *f = fopen("file.dat", "r");
//string buffer
#define MAX_LEN 50
const char line[MAX_LEN];
char field[MAX_LEN];
//the id to search for
const char *id = "10";
//for each line
while (fgets(line, MAX_LEN, f)) {
//extract the first field ('%s' matches a sequence of non-white-space characters)
sscanf(line, "%s", field);
//compare the field with the desired id
if (strcmp(field, id) == 0) {
//if found print line
printf("%s", str);
//set result to success
ret = EXIT_SUCCESS;
//and exit
break;
}
}
//cleanup
fclose(f);
//return the result
return ret;
}
Upvotes: 1