Array writing - I give up

Discussion in 'Mac Programming' started by farmerdoug, Feb 14, 2010.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    If I write to the array as below

    Code:
    
    if((d == 1)  && (t == 0))
    		{	
    		sprintf(&PCR1[no*pagesize], "%s",arr[3]);
    		no++;
    		/*	if (strcmp(arr[6],"P") == 0)
    			{
    				amount = atoi(arr[19]);
    				sprintf(&PCR1[(no++)*pagesize + d*rowsize + t*element], "%d", amount);
    			}
    			else
    			{
    				amount = atoi(arr[19]);
    				sprintf(&PCR1[(no++)*pagesize + (d+1)*rowsize * t*element], "%d", amount);
    			}
    		*/
    
    and print of the results in PCR1[i*pagesize] I get a only arr[3] values. When I take out the comments, the PCR1[i*pagesize] has other values.

    The entire code is here
    Code:
    
    
    #define dates 3
    #define times 3
    #define time1 "0940"
    #define time2 "1430"
    #define time3 "1550"
    #define pages 2500
    #define rows 3
    #define cols 3
    #define element 12
    #define pagesize (rows*cols*element)
    #define rowsize (cols*element)
    #define size (pages*rows*cols*element)
    
    char *PCRminus1;
    char *PCRminus2;
    char *PCRminus3;
    
    
    char *PCR1;
    
    int main (int argc, const char * argv[]) {
       
        int i, d, t, n, found, amount, no, p; 
    	char *filename, ** arr, *line;//, *symo;
    	FILE  *datafile, *outputfile;
    	
    	if (argc != (dates + 1))
    	{
    		printf(" Enter Three Dates, latest first\n");
    		return(0);
    	}	
    		
    	line = (char*)calloc(1024, sizeof(char));
    	filename = (char*)calloc(150, sizeof(char));
    	
    	strcpy(filename,filedir);
    	strcat(filename, argv[1]);
    	strcat(filename, "_results.csv");
    	outputfile = fopen(filename, "w");	
    		
    	PCRminus3 = allocate_memory((char*)PCRminus3);
    	PCRminus2 = allocate_memory((char*)PCRminus2);
    	PCRminus1 = allocate_memory((char*)PCRminus1);
    	PCR1 = allocate_memory((char*)PCR1);
    	
    	
    	
    for (d = 1; d <= dates; d++)
    		for (t = 0; t < times; t++)
    		{
    			strcpy(filename,data);
    			strcat(filename,namestart);
    			strcat(filename,argv[d]);
    			strcat(filename,"_");
    			switch (t) {
    				case	2: strcat(filename,(char*) time1);
    				break;
    				case	1: strcat(filename,(char*) time2);
    				break;
    				case	0: strcat(filename,(char*) time3);
    				break;
    		}
    		
    		strcat(filename,".csv");
    		printf("file %s\n", filename);
    		if ((datafile = fopen(filename, "r")) == NULL)
    			{
    			printf("Couldn't open file %s\n", filename);
    			exit(0);
    			}
    		fgets(line,1024,datafile);// discard first line And start comparing
    				
    		while( (fgets(line,1024,datafile) != 0))	
    		{	
    			found = 0;
    			arr = parse(line,",");
    			for (i = 0; i < no + 1; i++)
    				{	
    				if (strcmp (&PCR1[i*pagesize + 0*rowsize + 0*element], arr[3]) == 0)
    					{	
    					found = 1;
    					p = i;
    					i = no + 4;
    					}
    				}
    			if (!found)
    				if ( (atoi(arr[2]) == 1) && ((atoi(arr[7]) == 3) || (atoi(arr[7]) == 4) || (atoi(arr[7]) == 5)) && (atoi(arr[8]) < 35) )
    				
    				{
    				if((d == 1)  && (t == 0))
    					{	
    					sprintf(&PCR1[no*pagesize], "%s",arr[3]);
    						if (strcmp(arr[6],"P") == 0)
    						{
    							amount = atoi(arr[19]);
    							sprintf(&PCR1[(no++)*pagesize + d*rowsize + t*element], "%d", amount);
    						}
    						else
    						{
    							amount = atoi(arr[19]);
    							sprintf(&PCR1[(no++)*pagesize + (d+1)*rowsize * t*element], "%d", amount);
    						}
    					
    						} //if found on day 1 end of day
    				}
    			
    			
    	} //while fgets
    		fclose(datafile);
    	
    	} // t times
    	printf("%d \n", no);
    	n = 0;
    	for ( i = 0; i  < no; i++)
    	{ 
    		if (i == 0)
    			fprintf(outputfile, "%s", &PCR1[i*pagesize]);
    			else 
    			fprintf(outputfile, "\n%s ", &PCR1[i*pagesize]);		   }	
    	
    	free(PCR1);
    	free(filename);
    	for (i= 0; i <100; i++) 
    	{
    		free(arr[i]);
    	}
    	free(arr);
    	fclose(outputfile);
    	printf("%d \n", n - 1);
    	return 0;
    }
    
    
    
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    Your code doesn't compile.

    First, you haven't included any of the necessary #includes:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    

    Second, even with the #includes, this command:
    Code:
    gcc fdoug2.c
    
    produces these errors:
    Code:
    fdoug2.c: In function 'main':
    fdoug2.c:41: error: 'filedir' undeclared (first use in this function)
    fdoug2.c:41: error: (Each undeclared identifier is reported only once
    fdoug2.c:41: error: for each function it appears in.)
    fdoug2.c:46: warning: assignment makes pointer from integer without a cast
    fdoug2.c:47: warning: assignment makes pointer from integer without a cast
    fdoug2.c:48: warning: assignment makes pointer from integer without a cast
    fdoug2.c:49: warning: assignment makes pointer from integer without a cast
    fdoug2.c:56: error: 'data' undeclared (first use in this function)
    fdoug2.c:57: error: 'namestart' undeclared (first use in this function)
    fdoug2.c:81: warning: assignment makes pointer from integer without a cast
    
    Clearly, something is missing.

    If you're using Xcode, and you have a precompiled header, then you should either post the contents of that header, or turn that feature off.

    If you're using the command-line (which includes 'make'), then you should post the missing parts, or at least tell us what they are.

    If the above compilation errors have no bearing on the problem you posted about, then please post revised source code with all irrelevant parts removed or commented out.
     
  3. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #3
    farmerdoug,

    Plainly stated - if the supposedly complete code you're posting can't be compiled, linked and runnable as a whole before you post it then there is no science here as we will not be able to reproduce your results.
     
  4. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #4
    You can be reasonable sure that unless I say there are compilation problems, then I'm talking about running errors.

    I tracked the error down to the parse routine. It doesn't also work although I had no problems with it in two earlier programs.


    I've also cleaned the files so that there is nothing confidential in them.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <math.h>
    #define filedir "/Users/data/"
    #define data "/Users/data/data/"
    #define namestart "OpenFile_"
    #define dates 3
    #define times 3
    #define time1 "0940"
    #define time2 "1430"
    #define time3 "1550"
    #define pages 2500
    #define rows 3
    #define cols 3
    #define element 12
    #define pagesize (rows*cols*element)
    #define rowsize (cols*element)
    #define size (pages*rows*cols*element)

    char *PCRminus1;
    char *PCRminus2;
    char *PCRminus3;


    char *PCR1;



    char * allocate_memory (char *array);
    FILE * fileopen_r( char * type, char *date);
    FILE * makelist( char date[]);
    char ** parse( char *record, char *delim);
    int search(char* array, int asize, int *n, char * target);
    void sort ( char* array, int n, int p, int q);


    Code:
    
    char ** parse( char *record, char *delim)
    
    
    {
    	
    	char **tarr;
    	char *p;//=strtok(record,delim);
    	int i,fld=0;
    	if ( (p = (char *) calloc(element, sizeof(char))) == NULL)
    		printf("no memory for p");
    	tarr = (char **)calloc(100, sizeof(char*));
    	for (i = 0; i < 100; i ++){
    		if( (tarr[i] = (char*)calloc(element, sizeof(char))) == NULL)
    			printf("no memory allocated for arr\n");
    	}
    	
    	p = strtok(record,delim);
    	
    	while(p)
    	{	
    		strcpy(tarr[fld],p);
    		
    		fld++;
    		p=strtok('\0',delim);	
    	}
    	//printf("%s\n", tarr[1]);
    	return (tarr);	
    }
    char * allocate_memory (char *array)
    
    {
    	
    	
    	if( (array = (char *) calloc(size,sizeof(char))) == NULL)
    	{	
    		printf("no memory");
    		return(0);
    	}	
    	
    	return ((char*)array);
    	
    }
    FILE * fileopen_r( char * type, char *date) 
    
    {
    	
    	FILE *fp;
    	char filename[75];
    	strcpy(filename,data);
    	strcat(filename, type);
    	strcat(filename,"_");
    	strcat(filename	, date);
    	strcat(filename,".txt");
    	printf("%s\n",filename);
    	if ((fp = fopen(filename,"r")) == NULL)
    	{
    		printf(" File not opened\n");
    		perror(filename);
    	}
    	
    	return (fp);
    	
    }
    
    char datafile[200];  
    
    FILE * makelist( char  date[])
    {
    	char list[50];
    	char cmd[200];
    	FILE *fp;
    	
    	strcpy (datafile, namestart);
    	strcat (datafile, date);
    	
    	strcpy (cmd, "rm -f");
    	strcat (cmd, data);
    	strcat (cmd, "/data.lis");
    	
    	strcpy (cmd, "ls ");
    	strcat (cmd, data);
    	strcat (cmd, "/");
    	strcat (cmd, datafile);
    	strcat (cmd, "* > ");
    	strcat (cmd, data);
    	strcat (cmd, "/data.lis");	
    	system (cmd);
    	strcpy(list, data);
    	strcat(list, "/data.lis");
    	if ((fp = fopen(list,"r")) == NULL)
    		{
    		printf("could open list");
    			exit(0);
    		}	
    	return (fp);	
    	
    }
    
    
    char ** parse( char *record, char *delim)
    
    
    {
    	
    	char **tarr;
    	char *p;//=strtok(record,delim);
    	int i,fld=0;
    	if ( (p = (char *) calloc(element, sizeof(char))) == NULL)
    		printf("no memory for p");
    	tarr = (char **)calloc(100, sizeof(char*));
    	for (i = 0; i < 100; i ++){
    		if( (tarr[i] = (char*)calloc(element, sizeof(char))) == NULL)
    			printf("no memory allocated for arr\n");
    	}
    	
    	p = strtok(record,delim);
    	
    	while(p)
    	{	
    		strcpy(tarr[fld],p);
    		
    		fld++;
    		p=strtok('\0',delim);	
    	}
    	//printf("%s\n", tarr[1]);
    	return (tarr);	
    }
    
    
    int search(char* array, int asize, int *n, char * target)
    // asize is size not size - 1 
    {
    	
    	int start, mid, end;
    	int found = 0;
    	//printf("asize = %d\n", asize);
    	*n = 0;
    	start = 0;
    	end = asize - 1;
    	mid = asize/2;
    //	printf("start search %d\n", asize);
    	
    /*	if (asize ==  0) 
    	{
    		*n = 0;
    		printf("1 asize = %d\n", asize);
    		return (0);
    	}
    	
    	if ((asize == 1) || (asize == 2)) //|| (asize ==3) )
    	{
    		printf(" 1 %d %s %s\n", i, &array[i*pagesize], target);
    		if(
    		   (strcmp(&array[(0)*pagesize], target) == 0)|| 
    		   (strcmp(&array[(1)*pagesize], target) == 0)||
    		   (strcmp(&array[(1)*pagesize], target) == 0))
    			return(1);	
    		
    	}
    	 else {
    	// printf("no asize = 1\n");
    	 return(0);	
    	 
    	 }
    /*	if ((asize <= 2) && (asize > 0))
    		for (i = 0; i< asize; i++) 
    			if( strcmp(&array[i*pagesize], target) == 0)
    			{	
    				printf(" 1 %d %s %s\n", i, &array[i*pagesize], target);
    				*n = i;
    				return(1);	
    			}
    			else 
    			{
    				printf("0 %d %s %s\n", i, &array[i*pagesize], target);	 
    				return(0);	
    			}
    */	while ( !found ) 
    	{
    		if( strcmp(&array[mid*pagesize], target) >= 0)   		{
    			end = mid ;
    			mid = floor((mid + start)/2);
    			printf("here\n");
    			if (strcmp(&array[mid*pagesize], target) == 0)
    			{
    				*n = mid; 
    				//		printf("1 %d %d %d %d %s %s \n", *n, start, mid, end,&array[mid*pagesize + 2*element], target);
    				return (1); 
    			}
    		}
    		else 
    		{
    			start = mid;
    			mid = floor((end + mid)/2);
    			if (strcmp(&array[mid*pagesize], target) == 0)
    			{printf("here\n");
    				*n = mid;
    				
    				//		printf("2 %d %d %d %d %s %s \n", *n, start, mid, end,&array[mid*pagesize + 2*element], target);
    				return (1); 
    			}
    			
    			
    		}
    		
    		
    		if ((end == mid) || (start == mid))
    			
    		{	
    			
    				
    			//printf("3 %d %d %d %d %s %s \n", *n, start, mid, end,&array[mid*pagesize + 2*element], target);
    			*n = 0;
    			return (0); 
    		}
    		
    	}		
    	return(0);
    }			
    
    
    
    void sort ( char* array, int n, int p, int q) //number of items to sort p, q are rows and columns
    {
    	
    	char *tmp = NULL;
    	int j, i,k;
    	for ( i = 0; i < n; i++)
    		
    		tmp = (char*)calloc(pagesize,sizeof(char));
    	
    	
    	
    	for(j= (n- 1); j >= 0; j-- ) 
    		for(k = 1; k <= j; k++)	
    			if( strcmp((array+ (k-1)*pagesize+p*rowsize+q*element),(array+(k)*pagesize+p*rowsize+q*element) )> 0)
    			{	
    				memcpy(tmp, (array +(k - 1)*pagesize),sizeof(char)*pagesize);
    				memcpy( (array +(k - 1)*pagesize), (array+(k)*pagesize),sizeof(char)*pagesize);
    				memcpy( (array+(k)*pagesize) ,tmp,sizeof(char)*pagesize);	
    				
    			}	
    	
    }
    
    
    
     
  5. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #5
    We're not talking about "compilation problems" on your end. We're talking about "compilation problems" on our end. We can't reproduce the problems therefore we can't debug the problems. The 'fragments' you do post are NOT enough to assist you!

    If you post code that WE can compile, link and run, then and only then, can we really provide any useful assistance. Anything less is simply a guessing game.
     
  6. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #6
    I guess everyone is rather fed up with it right now. Pray tell us what happens when you set a breakpoint on the first line in your main function and start stepping through your code? Does it do what you think it should do? Or have you never heard of "debugging"?
     
  7. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #7
    Fed up, no. Frustrated that I (we) can't assist with what IS given yes.

    This along with the fact that I (we) can't convince him to to reduce the problem to a REPRODUCIBLE AND COMPLETE set of code and data that replicates the issue. Doing this step will greatly assist both himself directly, he'll have a better understand of where the problem is likely located, and indirectly in that I (we) have the same EXACT code in front of us with which to assist him.
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    Why do you think the error is in the parse() function? You should have some evidence or logic that supports this.

    I see nothing in parse() that would cause an error like you've described in the main() function. There is a memory leak in parse(), but memory leaks aren't the problem. Besides, parse()'s memory leak is the smallest of the leaks I can see, so even if leaking is a problem, it's not the biggest problem.

    There is a latent data-dependent bug in parse(): if the parsed line contains more than 100 comma-separated values, then it will overrun its calloc()'ed array (tarr) and begin destroying memory.

    Since you didn't post any sample input data, I'll assume that none of your input lines passed to parse() contains more than 100 comma-separated values. You might want to confirm that for your actual input data.
     
  9. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #9
    Which will not happen as long as he gets away with it. He's learnt a slow and expensive (to anyone else) method for debugging his code: Post it on MacRumors. As long as this method works, he won't feel any motivation to switch to a more efficient method, like pressing Command-Y in XCode.

    And I have a serious problem with doing _work_ for others. Helping them to learn is something completely different. Explaining why something works this way and not that way, what you need to do to achieve something, advice what to learn and what not to learn. In general, helping to improve people's knowledge and abilities is very worthwhile. But doug doesn't want any of that, he is just unwilling to learn. It's like you are trying to teach someone to drive a car in a straight line, but they refuse to learn it after you pulled them out of a ditch for the fourth time. Or you try to teach them to use more than just first gear in their car, and they refuse to listen and instead ask you to replace their engine when it explodes.

    Well, we could ask him if he can find the memory leak in parse ().
    Or the _massive_ memory leak in sort ().
    Or why the system () call will never delete the files he thinks it should delete.
    Or why the system () call will never write a directory listing to an output file.

    Which might actually be the cause of his problem :)

    chown33: Even if his program was working, it wouldn't work for _you_ unless you are an android on board of the Enterprise. (I guess you'll figure it out).
     
  10. miles01110 macrumors Core

    miles01110

    Joined:
    Jul 24, 2006
    Location:
    The Ivory Tower (I'm not coming down)
    #10
    Wow, this sounds strangely familiar.

    The number Mac Programming frequenters seems to be pretty small; why not just refuse to answer unless he posts complete, compilable code to begin with instead of wringing your hands every time? :confused:

    btw farmerdoug; if your data is "classified" in the US government sense you're not even allowed to discuss methods for dealing with that data with anyone without NTK. Discussing methods for working with classified data is grounds for revocation of whatever clearance you might currently hold.
     
  11. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #11
    It's simple in that part of "his" re-training needs to be behavior modification. Ignoring this particular person, in my opinion, is NOT the kind of help he needs and will change nothing.

    He's a Academic used to having Grad Students to hand these kinds of things off to.

    On the other hand if you want me to cut back on attempts at throttling him into submission ...
     
  12. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #12
    A. Training sometimes takes repetition.

    B. Things don't always work out the way one hopes.

    C. Are you sure "hand-wringing" isn't one of the contributor's training tactics?

    D. Farmerdoug never said "classified". All he said was "confidential".
     
  13. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #13
    int,init,*,+

    My kid is learning Objective C. "Daddy can you come here". It took be about 5 minutes to find where int should have been init.
    So how some it took me a day and a half to find the * that should have been a +? Arrgh.
     
  14. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #14
    1. Familiarity can be a type of blindness. You see what you intend, not what is. Unfortunately, the compiler only sees what is, not what you intended.

    2. Habits like inadequate spacing, too-terse naming, too-repetitive code, variables defined far from first use, minimal braces, poor indentation, etc. all contribute to unnoticeable errors. Sanitation is important to software health.

    I'm not being facetious about those. Learning how to write clear code is an important part of programming apprenticeship. Clarity isn't just for others, it's for the future version of yourself who has to read, debug, and revise what you write today.


    And where in your posted code was the * that should have been a +?
     
  15. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #15
    I know you are not being facetious but I have the slob gene, the careless gene, and probably a few other helpful ones as well. You've seen very little of it but I used to write very structured code. I had a boss whose code was so structured that each function was nearly a single line.

    If you look at the first post in this thread, in the first piece of code, you will find the * that should be a +. As an addition hint, the error resulted in an array address not changing.
     
  16. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #16
    Thanks, I'll look. Was that the only bug?
     
  17. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #17
    Thanks.

    As long as I don't make stupid mistakes, I should be okay.
     
  18. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #18
    Code:
    else
    {
    	amount = atoi(arr[19]);
    	sprintf(&PCR1[(no++)*pagesize + (d+1)*rowsize * t*element], "%d", amount);
    }
    
    The * between rowsize and t is the one that should be +.

    BTW, I don't think you've assigned a value to the 'no' variable before using it. That means it could contain anything, and it only contains the correct initial value by accident (if it contains the correct initial value at all).
     
  19. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #19
    It may have been there at one time and then got lost. Its there now.
     
  20. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #20
    Funny. But the compiler had no way of knowing that!
     
  21. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #21
    farmerdoug,

    The use of preprocessor macros would help minimize that type of problem.

    From something I posted in one of you other threads.

    Code:
    #define kPAGES                  (2000)
    #define kROWS                   (10)
    #define kCOLUMNS                (45)
    #define kBYTE_COUNT_PER_COLUMN  (12 * sizeof(char))
    #define kBYTE_COUNT_PER_ROW     (kCOLUMNS * kBYTE_COUNT_PER_COLUMN)
    #define kBYTE_COUNT_PER_PAGE    (kROWS * kBYTE_COUNT_PER_ROW)
    
    #define INDEX(PP,RR,CC) (((PP) * kBYTE_COUNT_PER_PAGE) + (((RR) * kBYTE_COUNT_PER_ROW) + ((CC) * kBYTE_COUNT_PER_COLUMN)))
    
    sprintf(&PCR1[INDEX(no++, d, t)], "%d", amount);
    
    Note the use of the macro INDEX localizes the calculation to one location cutting down on typing mistakes that often introduces bugs.

    EDIT: As pointed out by chown33

    Fixed the very bad macro expansion bug I was trying to show how to avoid in a previous thread.
    One should never post untested code after having been distracted.
     
  22. Sander macrumors 6502

    Joined:
    Apr 24, 2008
    #22
    Brrr, post-increments in a macro expansion...
     
  23. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #23
    Agreed, could be a problems depending upon the macro. On problem at a time...
     
  24. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #24
    Code:
    #define INDEX(PP,RR,CC) ((PP * kBYTE_COUNT_PER_PAGE) + ((RR * kBYTE_COUNT_PER_ROW) + (CC * kBYTE_COUNT_PER_COLUMN)))
    
    sprintf(&PCR1[INDEX(no++, d, t)], "%d", amount);
    
    Looks neat but I'm not sure what it does. Does no++ ,d and,t actually replace PP,RR and CC respectively? That would be a great help.
     
  25. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #25
    There is an insidious bug in the INDEX macro. It manifests in cases like this:
    Code:
    sprintf(&PCR1[INDEX(no, d+1, t)], "%d", amount);
    
    If the problem isn't obvious, I recommend manually expanding the macro to see it.

    Hint: rhymes with "crop aerator decadence".
     

Share This Page