Why is sscanf Causing an Error When Reading Data from a Text File?

  • Thread starter Thread starter nenyan
  • Start date Start date
AI Thread Summary
The discussion centers on a function designed to read data from a text file into a structured format. The data is formatted with fields separated by pipes (|), and the function encounters issues during parsing, specifically with the `sscanf` function. Debugging efforts indicate that the error arises from improper handling of memory allocation and string parsing. Key points include the need to allocate sufficient memory for the `catalog` structure and the suggestion to replace `fscanf` with a loop that reads entire lines into a string before parsing, which could mitigate buffer overflow issues. The current implementation attempts to read multiple fields into temporary variables, but the handling of these variables is flawed, leading to memory errors. It is also noted that the program should ensure that the correct array indexing is used when accessing elements of the `catalog`. Overall, the discussion emphasizes improving memory management and parsing logic to resolve the encountered errors.
nenyan
Messages
67
Reaction score
0
the function for read data from a txt.file.

the data looks like:

2|name|3.444|...|..|
3|name|5.344|...|..|

I use debugging tools and find the error occurred in sscanf. But I can not find the specific point. please help me.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define BUF 10240
#define pi 3.14159
#define SKYFILE "H1L1V1-LUMIN_cbc_trig-970399241-1.txt"
#define CATALOG "GWGCCatalog.txt"
#define ResultNumber 20


typedef struct catalogdata
{	char pgc[20];
	char name[100];
	double ra;
	double dec;
	double absmag;
	double dist;} cdata;

typedef struct catalogtemp
{	char pgc[20];
	char name[100];
	char ra[30];
	char dec[30];
	char absmag[20];
	char dist[20];} catatemp;






	/* This function is for readding catalog.*/
int
readevent( FILE *pFile, cdata **catalog)
{
	
	catatemp *ctemp, *ctemp1;  
	void *temp;
    int c, i=0, j, n=BUF;       /* n is the buffer. */
	
	if ( !(ctemp=(catatemp *)malloc(n*sizeof(catatemp))))  
		printf("memory error 1\n");                        //allocate memory.
	if ( !(temp=(char *)malloc(100)))  
		printf("memory error 1\n");                        //allocate memory for temp.

	do{
		c=getc(pFile);
	}while(c!='\n');                                   //skip the first line.

	while (!feof(pFile))
	{  
		/*read all data as a string*/
		fscanf(pFile, "%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|", &(ctemp->pgc), &(ctemp->name), &(ctemp->ra), &(ctemp->dec), temp, temp, temp, temp, temp, temp, temp, temp, temp, &(ctemp->absmag), &(ctemp->dist), temp, temp, temp);
		i++;
		
		if (i==(n-1))                              /*the number of lines is going to be longer than buffer. */
		{
			if(!(ctemp1=realloc(ctemp, 2*n*sizeof(cdata)))) {
				printf("memory error 2\n"); }
			ctemp=ctemp1;
			n*=2;   /*double the buffer*/
		}  

	}

	if ( !(*catalog=(cdata *)malloc(i*sizeof(cdata))))  
		printf("memory error 1\n");                        //allocate memory.

	/*convert string to data*/
	for(j=0;j<i;j++)
	{	
		sscanf((ctemp+j)->pgc, "%s", &((*catalog+j)->pgc));
		sscanf((ctemp+j)->name, "%s", &((*catalog+j)->name));
		sscanf((ctemp+j)->ra, "%lf", &((*catalog+j)->ra));
		sscanf((ctemp+j)->dec, "%lf", &((*catalog+j)->dec));
		if((ctemp+j)->absmag=="~")
			(*catalog+j)->absmag=10000.0;
		else
			sscanf((ctemp+j)->absmag, "%lf", &((*catalog+j)->absmag));
		if((ctemp+j)->dist=="~") 
			(*catalog+j)->dist=10000.0;
		else
			sscanf((ctemp+j)->dist, "%lf", &((*catalog+j)->dist));
	}

free(temp);
free(ctemp);
free(ctemp1);
return i;       
}

int
main()
{
	int i, n;
	cdata *catalog;
	FILE *pFile;
	
	if ( !( pFile=fopen(CATALOG, "r"))) {
		printf ("cannot open the cata_std.txt file\n");
		return 1;}
	n=readevent(pFile, &catalog);                         //catalog done.

	for(i=0; i<n; i++)
		printf("%s, %s, %e, %e, %e, %e\n", catalog[i].pgc, catalog[i].name, catalog[i].ra, catalog[i].dec, catalog[i].absmag, catalog[i].dist);

free(catalog);
fclose(pFile);

}
 
Technology news on Phys.org
You only allocate one instance of catalog in main, but you treat it as an array in readevent() when you reference ( ... catalog + j ...). It might also help to add temporary code to print out the structure for each loop in readevent().
 
I find something
&(ctemp->pgc), &(ctemp->name), should be (ctemp+i)->pgc
but still out of order
 
When you are using the debugger and see a problem with sscanf, which line is causing the problem, and what is the error that is generated?
 
i==14168 causing the problem
memory error...
 
in fact, the error occur in fscanf()
 
Here's my guess. The heap memory that temp points to consists of 100 bytes. One of the file reads (using fscanf) pulls in a string that's too big to fit in 100 bytes, which causes the problem you're seeing.

Instead of using fscanf to input to six variables you care about, and a slew of "don't care" variables, it might be better to have a loop. Each iteration of the loop could read one line of data from the file and store it in a string, and then parse the string.
 
Back
Top