bsearch problem in my code

L

lovecreatesbeauty

$ cat bse*
The bsearch call in below code doesn't find the correct record. When I
specify the name ie. "andrew" as the search key, it shows me with the
record "andrew   5000". Where am I wrong?
Thank for your time.
/************************************ 80 x
*************************************
* read lines from text file, bsearch by name then show whole line
containing
* the specified name. text file shows below:
*
*     jack     100000
*     bach     1 mil.
*     andrew   5000
*     michael  11222
************************************* 80 x
************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
#define LEN 128
int compar(const void *a, const void *b);
int main(int argc, char *argv[])
{
        FILE *file;
        char buf[N][LEN] = {'\0'};
        int n_cnt = 0;
        char *p = NULL;
        if (argc != 3){
        printf("Usage: %s  <input_file> <key>\n", argv[0]);
        return -1;
        }
        file = fopen(argv[1], "r");
        if (!file){
        printf("\"%s\" fopen error\n", argv[1]);
        return -1;
        }
        while (n_cnt < N && fgets(buf[n_cnt++], LEN - 1, file));
        fclose(file);
        qsort(buf[0], N, LEN, compar);
        if (p = bsearch(argv[2], buf[0], N, LEN, compar))
        printf("Found: %s:%d\n", p, strlen(p));
        else
        printf("Not Found\n");
        return 0;
}
int compar(const void *a, const void *b)
{
        const char *pa = a;
        const char *pb = b;
        int len_a = strlen(pa);
        int len_b = strlen(pb);
        int len = len_a < len_b ? len_a : len_b;
        return (strncmp(a, b, len));
}
$
 
W

William McNicol

$ cat bse*
The bsearch call in below code doesn't find the correct record. When I
specify the name ie. "andrew" as the search key, it shows me with the
record "andrew 5000". Where am I wrong?
Thank for your time.
if (p = bsearch(argv[2], buf[0], N, LEN, compar))

if (p = bsearch(argv[2], buf[0], n_cnt, LEN, compar))

Cheers,

William.
 
L

lovecreatesbeauty


if the input file has additional blank lines (input with the ENTER
key, or command o in vi), it works on Window. eg.

jack 100000
bach 1 mil.
andrew 5000
michael 11222
<ENTER>
<ENTER>

if there is no such extra blank lines at the end of file, the code
fails on some heading or trail records. where am i wrong? it has no
such a problem on Linux. thank you for your time.

/sent by google nexus one/
 
E

Eric Sosman

if the input file has additional blank lines (input with the ENTER
key, or command o in vi), it works on Window. eg.

jack 100000
bach 1 mil.
andrew 5000
michael 11222
<ENTER>
<ENTER>

if there is no such extra blank lines at the end of file, the code
fails on some heading or trail records. where am i wrong? it has no
such a problem on Linux. thank you for your time.

There's a lot of silliness in your code (as posted up-thread,
and perhaps changed in ways described else-thread but not shown),
and I'm not going to spend the time to do a complete analysis.
But here are a few notable points:

- The way you call fgets() shows that you don't understand
what the second argument means. Review your textbook.

- If fgets() returns NULL, n_cnt winds up being one *more*
than the number of lines read.

- It's not clear whether you're sorting n_cnt or N lines, but
either way you'll wind up including one or more empty lines
in the sorted array (unless you happen to fill the entire
array with input).

- Thanks to your oddball comparison function, an empty line
compares *equal* to all other lines, both in sorting and in
searching. This makes the behavior of both qsort() and
bsearch() undefined (because the comparator will report
that "A" and "B" are both equal to "", yet unequal to
each other).

- Since you use qsort() and bsearch() incorrectly (that is,
with a comparator that doesn't keep its side of the bargain),
it is unsurprising that the results are strange, and that
they differ from one platform to the next.

- The program termination status of -1 is not portable, and
in fact is not meaningful on any platform known to me (they
will all munge it in one way or another).

- The "%d" printf() conversion specifier is wrong for strlen(p).
 
L

lovecreatesbeauty

if the input file has additional blank lines (input with the ENTER
key, or command o in vi), it works on Window. eg.

     jack     100000
     bach     1 mil.
     andrew   5000
     michael  11222
     <ENTER>
     <ENTER>

if there is no such extra blank lines at the end of file, the code
fails on some heading or trail records. where am i wrong? it has no
such a problem on Linux. thank you for your time.

/sent by google nexus one/

$ cat bsearch*
/************************************ 80 x
*************************************
* read lines from text file, bsearch by name then show whole line
containing
* the specified name. text file shows below:
*
*     jack     100000
*     bach     1 mil.
*     andrew   5000
*     michael  11222
************************************* 80 x
************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 100
#define LEN 1024
int compar(const void *a, const void *b);

int main(int argc, char *argv[])
{
        FILE *file;
        char buf[N][LEN] = {{'\0'}};
        int n_cnt = 0;
        char *p = NULL;

        if (argc != 3){
                printf("Usage: %s  <input_file> <key>\n", argv[0]);
                return -1;
        }
        file = fopen(argv[1], "r");
        if (!file){
                printf("fopen error on %s\n", argv[1]);
                return -1;
        }
        while (n_cnt < N && fgets(buf[n_cnt], LEN - 1, file)) n_cnt++;
        fclose(file);
        qsort(buf, n_cnt, LEN, compar);
        p = bsearch(argv[2], buf, n_cnt, LEN, compar);
        if (p)        printf("Found: %s", p);
        else        printf("Not Found\n");
        return 0;
}

int compar(const void *a, const void *b)
{
        int na = strlen((char*)a);
        int nb = strlen((char*)b);
        int n = na < nb ? na : nb;

        return (strncmp(a, b, n));
}
$
 
L

lovecreatesbeauty

if the input file has additional blank lines (input with the ENTER
key, or command o in vi), it works on Window. eg.
     jack     100000
     bach     1 mil.
     andrew   5000
     michael  11222
     <ENTER>
     <ENTER>
if there is no such extra blank lines at the end of file, the code
fails on some heading or trail records. where am i wrong? it has no
such a problem on Linux. thank you for your time.
/sent by google nexus one/

$ cat bsearch*
/************************************ 80 x
*************************************
* read lines from text file, bsearch by name then show whole line
containing
* the specified name. text file shows below:
*
*     jack     100000
*     bach     1 mil.
*     andrew   5000
*     michael  11222
************************************* 80 x
************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 100
#define LEN 1024
int compar(const void *a, const void *b);

int main(int argc, char *argv[])
{
        FILE *file;
        char buf[N][LEN] = {{'\0'}};
        int n_cnt = 0;
        char *p = NULL;

        if (argc != 3){
                printf("Usage: %s  <input_file> <key>\n", argv[0]);
                return -1;
        }
        file = fopen(argv[1], "r");
        if (!file){
                printf("fopen error on %s\n", argv[1]);
                return -1;
        }
        while (n_cnt < N && fgets(buf[n_cnt], LEN - 1, file)) n_cnt++;
        fclose(file);
        qsort(buf, n_cnt, LEN, compar);
        p = bsearch(argv[2], buf, n_cnt, LEN, compar);
        if (p)        printf("Found: %s", p);
        else        printf("Not Found\n");
        return 0;

}

int compar(const void *a, const void *b)
{
        int na = strlen((char*)a);
        int nb = strlen((char*)b);
        int n = na < nb ? na : nb;

        return (strncmp(a, b, n));}

$

correct the corresponding line as this moving n_cnt++ outside the
subscription of buf[n_cnt/*++*/]:

while (n_cnt < N && fgets(buf[n_cnt], LEN - 1, file)) n_cnt++;
 
M

Moi

int compar(const void *a, const void *b)
{
        int na = strlen((char*)a);
        int nb = strlen((char*)b);
        int n = na < nb ? na : nb;

        return (strncmp(a, b, n));
}

You really want "abc" and "ab" to compare equal ?
(also strlen() returns size_t)

HTH,
AvK
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top