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

  • Thread starter Thread starter nenyan
  • Start date Start date
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
6 replies · 3K views
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);

}
 
Physics 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.