#include <stdio.h>
#include <stdbool.h>
#define HASH_SIZE 10
int hash(int value);
void dfs(FILE *file, int value);
int main()
{
FILE *file = fopen("DATA_FILE.csv", "r");
if (file == NULL)
{
perror("Error while opening the file");
return 1;
}
int value = -685434;
dfs(file, value);
fclose(file);
return 0;
}
void dfs(FILE *file, int value)
{
bool visited[HASH_SIZE] = { false };
// Read the first value from the file
int currentValue;
fscanf(file, "%d", ¤tValue);
while (currentValue != value && !feof(file))
{
int key = hash(currentValue);
visited[key] = true;
fscanf(file, "%d", ¤tValue);
if (visited[hash(currentValue)])
{
fscanf(file, "%d", ¤tValue);
}
}
if (currentValue == value)
{
printf("Value found in file: %d\n", currentValue);
}
}
int hash(int value)
{
return value % HASH_SIZE;
}
While the instruction says, "The data file has two pairs of columns, the first of which has the number you're seeking for and the second of which contains the paired numbers you need to retrieve and show. In this instance, you need to use data scanning for the file by reading row by row to find the data
Here is what is expected to work from the code: Your code receives input from command line arguments. The format in command line as follow find [-s | -t] number description: number : is the number that you must find inside the data file [ … | …. ] : is the searching techniqye option that you need to choose one of the parameters. -s : you will search inside data file using file scanning row by row. -t : you will search using your solution
Here is the input and output:
- find -s 12345 Found 12345 with data on second column is 987234 Time elapsed 200 ms or
- find -t 12345 Found 12345 with data on second column is 987234 Time elapsed 1 ms
if an error occurs, it will say: No method defined Proper Syntax is find [ -s | -t ] number
CodePudding user response:
/* find_value.c */
#include <stdio.h>
int main()
{
FILE *file;
file = fopen("DATA_FILE.csv", "r");
if (!file)
{
perror("DATA_FILE.csv");
return 1;
}
int n;
int find_value = 32;
while(fscanf(file, "%d", &n) == 1) {
if(n == find_value) {
printf("%d\n", n);
}
}
fclose(file);
return 0;
}
CodePudding user response:
From my top comments ...
- From the problem description, the input [
.csv
] file is a series of lines of the form:key,value
. - Your code should be doing (e.g.):
fscanf(file,"%d,%d",&curkey,¤tValue)
, so you are reading the file incorrectly. - What you call
value
, I would calldesired_key
as it needs to match the key [and not the value] and if a match is found on the key, you want to print the value. - You have to do this line-by-line if given -s as a command line arg.
- If given -t, you have to reading the file and store the key/value pairs in an array. You need a struct such as:
struct row { int key; int value; };
- The problem statement doesn't mention a hash.
- I don't see a need for
visited
at all. To me, that's some extraneous code from a shortest path algorithm (e.g. Dijkstra's or A*). - Your code doesn't look at
argc/argv
at all. So, you can't select the method from-s
or-t
and get the desired key value to search for.
Here is the corrected code. It is annotated:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int opt_s;
int opt_t;
// key/value item
struct keyval {
int key;
int val;
};
struct keyval *csvdata; // array of all pairs in file
int csvcount; // number of pairs in array
// method_s -- match on a line-by-line basis
int
method_s(FILE *file,int desired_key,int *retval)
{
int curkey;
int curval;
int found = 0;
// read all lines of the form:
// key,val
while (fscanf(file,"%d,%d",&curkey,&curval) == 2) {
found = (curkey == desired_key);
if (found)
break;
}
// return the value if a match
if (found)
*retval = curval;
return found;
}
// load_t -- load up CSV array
int
load_t(FILE *file)
{
int cap = 0;
int curkey;
int curval;
struct keyval *pair;
csvdata = NULL;
csvcount = 0;
while (fscanf(file,"%d,%d",&curkey,&curval) == 2) {
if (csvcount >= cap) {
cap = 10;
csvdata = realloc(csvdata,sizeof(*csvdata) * cap);
if (csvdata == NULL) {
perror("realloc");
exit(1);
}
}
pair = &csvdata[csvcount ];
pair->key = curkey;
pair->val = curval;
}
// trim array to actual size used
csvdata = realloc(csvdata,sizeof(*csvdata) * csvcount);
if (csvdata == NULL) {
perror("realloc");
exit(1);
}
}
// method_t -- match on a stored array basis
int
method_t(FILE *file,int desired_key,int *retval)
{
struct keyval *pair;
int found = 0;
// load up the array
load_t(file);
// loop through the stored array, looking for a match
for (int idx = 0; idx < csvcount; idx) {
pair = &csvdata[idx];
found = (pair->key == desired_key);
if (found)
break;
}
// return the value if a match
if (found)
*retval = pair->val;
return found;
}
int
timems(void)
{
struct timespec ts;
long long nsec;
static long long timebase = 0;
clock_gettime(CLOCK_MONOTONIC,&ts);
nsec = ts.tv_sec;
nsec *= 1000000000;
nsec = ts.tv_nsec;
if (timebase == 0)
timebase = nsec;
nsec -= timebase;
nsec /= 1000000;
return nsec;
}
int
main(int argc,char **argv)
{
int err = 0;
--argc;
argv;
for (; argc > 0; --argc, argv) {
char *cp = *argv;
if (cp[0] != '-')
break;
if ((cp[1] == '-') && (cp[2] == 0))
break;
cp = 2;
switch (cp[-1]) {
case 's':
opt_s = 1;
break;
case 't':
opt_t = 1;
break;
default:
err = 1;
break;
}
}
if (opt_s && opt_t)
err = 1;
if (! (opt_s || opt_t))
err = 1;
int desired_key = -1;
if (argc != 1)
err = 1;
else
desired_key = atoi(*argv);
if (err) {
printf("No method defined Proper Syntax is find [ -s | -t ] number\n");
exit(1);
}
FILE *file = fopen("DATA_FILE.csv", "r");
if (file == NULL) {
perror("Error while opening the file");
return 1;
}
int found = 0;
int retval = 0;
int msbeg = timems();
do {
if (opt_s) {
found = method_s(file,desired_key,&retval);
break;
}
if (opt_t) {
found = method_t(file,desired_key,&retval);
break;
}
} while (0);
int msend = timems();
fclose(file);
if (found)
printf("Found %d with data on second column is %d Time elapsed %d ms\n",
desired_key,retval,msend - msbeg);
return 0;
}
Here is the sample input (DATA_FILE.csv
) file I used:
46079,96649
71463,62685
81995,47037
50876,79762
95492,88344
45272,72553
41950,80235
81543,99066
67329,78252
79563,36472
63549,83972
94173,58525
81532,25036
39514,94603
90454,25278
33306,95455
85052,5202
49451,58592
69333,80996
94039,34855
Here is the output for ./find -s 67329
:
Found 67329 with data on second column is 78252 Time elapsed 0 ms
Here is the output for ./find -t 67329
:
Found 67329 with data on second column is 78252 Time elapsed 0 ms