Hi
see this code

#define	MAX_LINE_LENGTH		1024
#define	MAX_TOKEN_LENGTH	32

typedef struct max_min
{
	char maximum[MAX_TOKEN_LENGTH];
	char minimum[MAX_TOKEN_LENGTH];
} m_and_m;
enum data_type{enumber};

in your main program did this

m_and_m max_number;
	FILE *fp;
	int result;
	/*Open input file*/
	fp = fopen("read.csv","r");
	if (fp != NULL)
	{
	max_number = get_max_min(fp,11,5,enumber);
		rewind(fp);
		result = 0;
	}

this the file function

m_and_m *get_max_min(FILE *fp,unsigned start_from_line,unsigned start_from_column,enum data_type dtype)
{
	m_and_m *result;
	unsigned i;
	char current_max[MAX_TOKEN_LENGTH],current_min[MAX_TOKEN_LENGTH],*token;
	char current_line[MAX_LINE_LENGTH];

	/*Use fgets to get one line prior to the desired start line*/
	for (i = 0;i < start_from_line - 1;i++)
	{
		fgets(current_line,MAX_LINE_LENGTH,fp);
	}
	
	/*While there are lines to read*/
	while (fgets(current_line,MAX_LINE_LENGTH,fp))
	{
		/*Read tokens using strtok until you get to the desired start column*/
		i = 0;
		token = strtok(current_line,",");
		while (token != NULL && i < start_from_column - 1)
		{
			token = strtok(NULL,",");
			i++;
		}
		/*Do the actual comparisons to find current_max and current_min*/
		switch (dtype)
		{
		
		case (enumber) :
			printf ("Comparing numbers.\n");
			strcpy(current_max,compare_number(current_max,token));
			strcpy(current_min,compare_number(current_min,token));
			break;
		default :
			fprintf (stderr,"Undefined data type.\n");
			break;
		}
	}

	/*Store the result in an m_and_m type variable and return it*/
	result = (m_and_m *)malloc(sizeof(m_and_m));
	if (result != NULL)
	{
		strcpy(result->maximum,current_max);
	//	strcpy(result->minimum,current_min);
	}
	else
	{
		fprintf(stderr,"Failed to allocate memory.\n");
	}
	return (result);

}

now if you want to buit you max and min function.

char	*compare_number(char *first_number,char *second_number)
{
	char *result;

	
	return (result);
}

how you can build the above function copmare number

Dani AI

Generated

The code posted by has the right idea but a few definite causes of undefined behaviour and missing results: current_max/current_min are used before being initialized, compare_number is unimplemented, and the returned m_and_m only copies maximum (the minimum copy is commented out). was correct to flag conversion return values; for robust numeric comparison prefer strtol/strtod with endptr and errno checks rather than blind conversions.

A safe compare_number implementation should (1) treat NULL/empty tokens as “no value”, (2) validate conversion using endptr and errno, and (3) return a pointer to the token that should become the stored max/min (or better, return an integer comparison and let the caller copy into the fixed-size buffers). Example helper + compare function:

#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>

static int parse_int_str(const char *s, long *out)
{
    char *end;
    long v;
    if (!s || !*s) return 0;
    errno = 0;
    v = strtol(s, &end, 10);
    while (*end && isspace((unsigned char)*end)) end++;
    if (end == s || *end != '\0' || errno) return 0;
    if (out) *out = v;
    return 1;
}

char *compare_number(char *first, char *second)
{
    long a, b;
    int ok1 = parse_int_str(first, &a);
    int ok2 = parse_int_str(second, &b);
    if (!ok1 && !ok2) return first;   /* neither valid: keep existing */
    if (!ok1) return second;          /* only second valid */
    if (!ok2) return first;
    return (a >= b) ? first : second;
}

Other practical fixes: initialize current_max[0] = current_min[0] = '\0' and on the first valid numeric token copy it into both buffers using strncpy(..., MAX_TOKEN_LENGTH-1) and buffer[MAX_TOKEN_LENGTH-1] = '\0'. Always check token != NULL after strtok, trim whitespace/newlines before conversion, and ensure both maximum and minimum are copied into the malloc'ed m_and_m before returning. Compile with -Wall -Wextra and run under Valgrind to catch uninitialized reads. For CSVs with quoted fields, strtok is fragile; consider a proper CSV parser if fields may contain commas.

See the strtol manual for conversion/error details (strtol manpage) and the sscanf documentation if sticking with scanf-style parsing (sscanf manpage).

Recommended Answers

All 6 Replies

Hmm, I would say sscanf would be your best bet for a quick solution:

char	*compare_number(char *first_number,char *second_number)
{
  char *result;
  int x, y;

  sscanf ( first_number, "%d", &x );
  sscanf ( second_number, "%d", &y );

  return x < y ? first_number : second_number;
}

Naturally, you'll need to modify that to fit the needs of your code (I didn't test it) and add error checking.

Hi Narue
thank you for your help.
I am not sure if it is the right.

you'll need to modify that to fit the needs of your code (I didn't test it) and add error checking.

what do you mean add error checking.

thanks in advance

>what do you mean add error checking
The return value of sscanf will tell you if the conversion worked. If it didn't then the token wasn't a valid integer and you need to fix the error in your code that causes it to be invalid.

>what do you mean add error checking
The return value of sscanf will tell you if the conversion worked. If it didn't then the token wasn't a valid integer and you need to fix the error in your code that causes it to be invalid.

there she goes...on the ball!

:mrgreen:


p.s. oh and its about time you got a decent avatar....hehehe

Hi agian
It did not work with me, I amend to return the value but it not.

sscanf

>It did not work with me
That's an absolutely useless statement. If you want help, provide as much information as to how it doesn't work as you possibly can.

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.