Here is my program so far:

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

#define max 200

typedef struct {
	char triple[6];
	unsigned index;
	unsigned lower;
	unsigned upper;
}	mpn;

unsigned load_MPN_table (mpn *mpn_table[], FILE* input, unsigned max_size)
{
	unsigned i;

	for (i=0; i<max_size; i++) {
		fscanf(input, "%s%u%u%u", mpn_table[i]->triple, &mpn_table[i]->index, &mpn_table[i]->lower, &mpn_table[i]->upper);
//		if (mpn_table[i]->triple ==0) {
//			return i-1;
//		}	
	}

	return max_size;
}
unsigned search (mpn *mpn_table, char *search_value, unsigned max_size)
{
	unsigned row=0;

	while (strcmp(mpn_table[row].triple,search_value)!=0) {
		row++;
		if (row==max_size) {
			return -1;
		}
	}

	return row-1;
}

void print_row (mpn *mpn_table, unsigned row)
{
	printf("For %s, MPN = %u; 95 percent of samples contain between %u and %u bacteria/ml\n", 
		mpn_table[row].triple, mpn_table[row].index, mpn_table[row].lower, mpn_table[row].upper);
}
int main (void)
{
	mpn mpn_table[max];
	unsigned max_size=max;
	char search_value[6];
	unsigned row;
	FILE* input;

	input=fopen("mpntable.txt", "r");

	max_size=load_MPN_table(mpn_table, input, max_size);

	printf("%u\n", max_size);
	
	printf("For %s, MPN = %u; 95 percent of samples contain between %u and %u bacteria/ml\n", //test
 		mpn_table[1].triple, mpn_table[1].index, mpn_table[1].lower, mpn_table[1].upper);
	printf("For %s, MPN = %u; 95 percent of samples contain between %u and %u bacteria/ml\n", //test
 		mpn_table[4].triple, mpn_table[4].index, mpn_table[4].lower, mpn_table[4].upper);

	while (1) {
		printf("What value is to be searched? press 'Q' to quit. -> ");
		scanf("%s", &search_value);
		if (*search_value=='q' || *search_value=='Q') { 
			break; 
		}
		if (search(mpn_table, search_value, max_size)==-1) {
			printf("Triple not found!\n");
		} else {
			print_row(mpn_table, search(mpn_table, search_value, max_size));
		}
	}
	return 0;
}

Here is my input file:

4-2-0 22 9 56
4-2-1 26 12 65
4-3-0 27 12 67
4-3-1 33 15 77
4-4-0 34 16 80
5-0-0 23 9 86
5-0-1 30 10 110
5-0-2 40 20 140
5-1-0 30 10 120
5-1-1 50 20  150
5-1-2 60 30 180
5-2-0 50 20 170
5-2-1 70 30 210
5-2-2 90 40 250
5-3-0 80 30 250
5-3-1 110 40 300
5-3-2 140 60 360

The program is supposed to scan the entire file and then be able to search an mpn triple eg 5-3-2 and display the results where 140 is the mpn index and 60 and 360 are the lower and upper limits of the 95 percentile. This is all relating to some bacteria experiment.

The problem that I'm working on now is that it doesn't seem to scan correctly. I think I'm getting addresses instead of the number. I'm just to the point where I'm so fried and fed up with it. Any help would be greatly appreciated.

As of now i am unsure whether or not the search or printrow functions work but im not worrying about them yet.

Dani AI

Generated

Good instincts from @Dave Sinkula on reducing indirection. The core issue was mixing an array of structs with an array of pointers to structs. If you declare mpn mpn_table[max]; in main, then pass and use it as a flat array (use . not ->). While you are at it, bound your string reads and always check the result of fscanf to avoid partial reads and buffer overruns. A small, robust loader might look like this:

#include <string.h>

size_t load_mpn(mpn table[], FILE *in, size_t cap) {
    size_t n = 0;
    while (n < cap) {
        char t[6];                  /* fits "5-3-2" plus '\0' */
        unsigned idx, lo, hi;
        int got = fscanf(in, "%5s %u %u %u", t, &idx, &lo, &hi);
        if (got == EOF) break;      /* end of file */
        if (got != 4) break;        /* malformed line */
        strcpy(table[n].triple, t); /* safe because of %5s */
        table[n].index = idx;
        table[n].lower = lo;
        table[n].upper = hi;
        ++n;
    }
    return n;
}

A few quick fixes to apply alongside this:

  • Open defensively: check input != NULL before loading, and print a clear error if it fails.
  • Limit user input and pass the right pointer type: scanf("%5s", search_value); (no & for arrays).
  • Fix the search return: when you find a match, return the current index, not row-1. Keep a -1 sentinel for not found.
  • Size matters: triple[6] only fits patterns up to 5 chars like 9-9-9. If your triples can be longer (e.g., 10-10-10), increase the array and adjust the %Ns width accordingly.
  • Validate reads: fscanf returns how many fields were converted; use that to stop cleanly and to diagnose malformed lines quickly.

These small changes will make the loader reliable and the search/print logic behave as intended.

Recommended Answers

All 6 Replies

main.c:55: warning: passing arg 1 of `load_MPN_table' from incompatible pointer type
main.c:66: warning: char format, different type arg (arg 2)
main.c:50: warning: unused variable `row'

All i get as a warning is suspicious pointer conversion on line 55 but i don't know what I'm doing wrong. Ive tried multiple combinations of ampersands and asterisks. I also tried this which yielded no warnings but the results were still undesirable:

unsigned load_MPN_table (mpn mpn_table[], FILE* input, unsigned max_size)
{
	unsigned i;

	for (i=0; i<max_size; i++) {
		fscanf(input, "%s%u%u%u", mpn_table[i].triple, &mpn_table[i].index, &mpn_table[i].lower, &mpn_table[i].upper);
//		if (mpn_table[i]->triple ==0) {
//			return i-1;
//		}	
	}

	return max_size;
}

All i get as a warning is suspicious pointer conversion on line 55 but i don't know what I'm doing wrong. Ive tried multiple combinations of ampersands and asterisks.

That's what it looks like -- throwing a bunch of syntax at the code and praying for it to work. Less indirection might be better than more.

That was after some time of confusion and frustration the two candidates above were what i was working on for any substantial amount of time.

Keep in mind i am very new to programming. We were recently introduced to structures and this is one of the practice problems for a homework assignment. Programming is not my forte...

You have it correct for the print function -- what happened?
You have it done well for the search function -- what happened?

If I spoonfed you with this, could be manage to make the other changes?

unsigned load_MPN_table (mpn *mpn_table, FILE* input, unsigned max_size)

Try to engage your brain rather than resorting to tossing syntax at the code.

commented: This for giving me negative rep about gets() -5

solved, the problem was my input file. it was named mpntable.txt.txt

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.