Thread: why this while condition doesnt stop the loop??

  1. #31
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i looked at his code
    and you open the same file
    i changed that and i open 3 different files(that we used earlyer)
    and then your code gets a run time error
    and when i degubbed it
    smallest functions gets 3 NULLs instead of data

    ??
    Code:
    #define _CRT_SECURE_NO_WARNINGS
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct FileData
    {
    	FILE *f;
    	char *s;
    };
    
    void readOneStr(struct FileData *fd)
    {
    	char temp[100];
    	if (fgets(temp, sizeof(temp), fd->f))
    	{
    		temp[strlen(temp)-1] = 0;
    		fd->s = realloc(fd->s, strlen(temp)+1);
    		strcpy(fd->s, temp);
    	}
    	else
    	{
    		free(fd->s);
    		fd->s = NULL;
    	}
    }
    
    char *findSmallest(char *s1, char *s2, char *s3)
    {
    	char *smallest = s1;
    	if (!smallest || (s2 && (strcmp(s2, smallest) < 0)))
    	{
    		smallest = s2;
    	}
    	if (!smallest || (s3 && (strcmp(s3, smallest) < 0)))
    	{
    		smallest = s3;
    	}
    	return smallest;
    }	
    
    
    void readStrs(struct FileData *f)
    {
    	char *smallest = findSmallest(f[0].s, f[1].s, f[2].s);
    	int i;
    	for(i = 0; i < 3; i++)
    	if (!f[i].s || !strcmp(f[i].s, smallest))
    		readOneStr(&f[i]);
    }
    
    void compareAndOutput(FILE *out, struct FileData *f)
    {
    	if (f[0].s && f[1].s && !strcmp(f[0].s, f[1].s))
    	{
    		fprintf(out, "%s\n", f[0].s);
    		return;
    	}
    	if (f[0].s && f[2].s && !strcmp(f[0].s, f[2].s))
    	{
    		fprintf(out, "%s\n", f[0].s);
    		return;
    	}
    	if (f[1].s && f[2].s && !strcmp(f[1].s, f[2].s))
    	{
    		fprintf(out, "%s\n", f[1].s);
    		return;
    	}
    }
    
    int main()
    {
    	struct FileData f[3] = { NULL };
    	FILE *out = fopen("g:\\out.txt", "w");
    
    	f[0].f = fopen("g:\\file1.txt", "r");
    	f[1].f = fopen("g:\\file2.txt", "r");
    	f[2].f = fopen("g:\\file3.txt", "r");
    
    	do
    	{
    		readStrs(f);
    		compareAndOutput(out, f);
    	} while(f[0].s && f[1].s && f[2].s);
    	return 0;
    }

  2. #32
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    findsmallest is expected to have three NULLs in it.

    What compiler are you using?

    Edit: I just copied the content from above, removed the g:\\ part of the filename and ran it on my machine. No runtime error or anything like it.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #33
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i am using visual studio 2005
    "findsmallest is expected to have three NULLs in it. "

    your code clearly shows that you are comparing them in order to find the smallest
    so if you get all of them to be NULL then
    there is no smallest
    ??

  4. #34
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    	char *smallest = s1;
    	if (!smallest || (s2 && (strcmp(s2, smallest) < 0)))
    	{
    		smallest = s2;
    	}
    This code will not make strcmp if smallest [which is the value of s1] or s2 is NULL. The same applies for the next if-statement.

    Where does it actually crash?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #35
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    in some point (line57 ) i get this
    http://img26.imageshack.us/img26/3346/56201931.gif

  6. #36
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, there is only one fgets() in the source, and the only argument that could perceivably be NULL is the fd->f - so perhaps it can't open one of the input files? Try looking at the f variable in main after the three calls to fopen()?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #37
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i debugged this code
    what2(root, "") just puts 1 into the root->value


    what2(root, "a") just puts 1 into the root->sons[0]->value
    but that doesnt give me a pattern
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #define N 3
    typedef struct tree {
       int value;
       struct tree **sons;  // array of pointers 
    } tree;
    
    tree * CreateLeaf(){
       int i;
       tree *temp = (tree *)malloc(sizeof(tree));
    if(!temp) exit(1);
       temp->value=0;
       temp->sons = (tree **)malloc(N * sizeof(tree *)); 
       if(!temp->sons) exit(1);
       for(i=0; i<N; i++)
      temp->sons[i]=NULL;
       return temp;
    }
    
    void what2(tree *root, char *text){
       if(!(*text)){
          root->value++;
          return;
       }
       if(!root->sons[*text-'a'])   
    root->sons[*text-'a']= CreateLeaf();
       what2(root->sons[*text-'a'],text+1);
    }
    
    void what3(tree *root){
       int i;
       if(!root) return;
       printf("%d ",root->value);
       for(i=0; i<N; i++)
          what3(root->sons[i]);
    }
    
    void main(){
    tree *root= CreateLeaf();
    what2(root, "");
    //what2(root, "a");
     
    
    }
    another problem is understanding the structure
    Code:
    temp->sons = (tree **)malloc(N * sizeof(tree *));
    temp->sons is now a pointer to a pointer to an node
    then they say
    Code:
    root->sons[*text-'a']= CreateLeaf();
    suppose that *text='a'
    so
    Code:
    root->sons[0]= CreateLeaf();
    what is sons[0]

    sons[0] is row 0 its a whole row of members
    its not one node for which we can make it to point to something else

    a whole row cannot point to anything
    this line
    Code:
    root->sons[0]= CreateLeaf();
    makes no sense
    ??

  8. #38
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Now you are mixing your threads up.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #39
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    this is the formal solution:

    i cant understand the red marked part

    what is the purpose
    Code:
    typedef struct vote {
    	char name [30];
    	int id,type,candidate;
    } vote;
    void report(FILE* college[3], FILE* arr[10], char* canceled){
    // Fuction returns the minimal id
    int getMin(int eof[],vote [],int *);
    // Function checks a vote record correct
    int votecheck(vote ,vote [],int i);
    // Function reads the next record from "college" file
    int readFrom(FILE *,vote [],int);
    
    void  report(FILE *college[3], FILE *arr[10], char*canceled){
    	FILE *cancel;
    	vote currtable[3], // array for three current "college" records
    		votable[3],    // array for checking the records with the same "id"
    		current;	   // struct for the current "college" record	
    	int i,j,idmin,index,flag,eof[3];
    	if(!(cancel=fopen(canceled,"w"))) exit(1);
    	
    	for(i=0;i<3;i++)
    		eof[i]= readFrom(college[i],currtable,i);
    // main loop	
    	while(eof[0]!=EOF||eof[1]!=EOF||eof[2]!=EOF){
    		idmin=getMin(eof,currtable,&index);
    		for(i=flag=0;i<3;i++)
    			if(i!=index && eof[i]!=EOF && currtable[i].id==idmin)
    				flag=3;
    		if(flag){
    		fprintf(cancel,"%s%d%d\n",currtable[index].name,idmin,flag);
    			for(i=0;i<3;i++)
    				while(eof[i]!=EOF && currtable[i].id==idmin)
    				eof[i]=readFrom(college[i],currtable,i);
    			continue;
    		}
    //Filling struct table for the minimal id
    		votable[0]=currtable[index];
    		i=1;
    		while(eof[index]!=EOF && i<3){						eof[index]=fscanf(college[index],"%30[^\n]%9d%1d%1d%*c",
    current.name,&current.id,&current.type,&current.candidate);
    		if(current.id!=idmin){
    			for(j=0;j<i;j++)									fprintf(arr[votable[j].candidate],"%9d%d%d\n",
    idmin,index,votable[j].type);
    		currtable[index]=current;
    		break;
    		}
    		else{
    			flag=votecheck(current,votable,i);
    			if(flag){				fprintf(cancel,"%s%d%d\n",currtable[index].name,idmin,flag);
    			while(eof[index]!=EOF && currtable[index].id==idmin)
    			eof[index]=readFrom(college[index],currtable,index);
    			break;
    			}
    			else
    				votable[i++]=current;
    		}//else
    	}//while
    	if(i<3)  continue;
    		if(eof[index]!=EOF)
    		eof[index]=fscanf(college[index],"%30[^\n]%9d%1d%1d%*c",
    current.name,&current.id,&current.type,&current.candidate);
    		if(eof[index]==EOF ||current.id!=idmin ){
    			for(j=0;j<i;j++)
    				fprintf(arr[votable[j].candidate],"%9d%d%d\n",
    idmin,index,votable[j].type);		
    			currtable[index]=current;
    		}
    		else{			fprintf(cancel,"%s%d%d\n",votable[0].name,idmin,2);
    	while(eof[index]!=EOF && currtable[index].id==idmin)				eof[index]=readFrom(college[index],currtable,index);
    		}
    	}// main loop - while
    	fclose(cancel);
    }// report
    
    int votecheck(vote curr,vote arr[],int i){
    	int j,count;
    	for(j=count=0;j<i;j++){
    		if(curr.candidate==arr[j].candidate)
    			return 1;
    		if(curr.type==1 && arr[j].type==1)
    			return 2;
    		if(curr.type==2 && arr[j].type==2)
    			count++;
    		if(count>1)	return 2;
    	}
    	return 0;
    }
    
    int readFrom(FILE *coll,vote table[],int i){
    	return fscanf(coll,"%30[^\n]%9d%1d%1d%*c",table[i].name,
    				&table[i].id,&table[i].type,&table[i].candidate);
    }	
    
    int getMin(int eof[],vote table[],int *index){
    	int i,idmin;
    	for(i=0,idmin=999999999;i<3;i++)
    		if(eof[i]!=EOF && table[i].id<idmin){
    				idmin=table[i].id;
    				*index=i;
    		}
    	return idmin;			
    }

  10. #40
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    This clearly solves a different problem than what you asked about - since it is reading 4 fields rather than the one string that I produced.

    As to what the lines in red does: Read a line from each file and produce the output results. The entire logic of the solution is in those few lines - the rest of the code is just setup, helper functions and tear-down.

    I don't like the fact that
    Code:
    eof[index]=fscanf(college[index],"%30[^\n]%9d%1d%1d%*c",
    current.name,&current.id,&current.type,&current.candidate);
    is essentially done 3 times in the file - why not call the one helper function readFrom in all the places?

    You will have to ask more specific questions if you want to get a more specific answer.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #41
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    there are places which i dont know what is the purpose in that part,
    i will try to explain myself every part:
    Code:
    	for(i=0;i<3;i++)
    		eof[i]= readFrom(college[i],currtable,i);
    it reads one line from each college file and puts it into currtable.
    Code:
    	while(eof[0]!=EOF||eof[1]!=EOF||eof[2]!=EOF){
    		idmin=getMin(eof,currtable,&index);
    		for(i=flag=0;i<3;i++)
    			if(i!=index && eof[i]!=EOF && currtable[i].id==idmin)
    				flag=3;
    		if(flag){
    		fprintf(cancel,"%s%d%d\n",currtable[index].name,idmin,flag);
    			for(i=0;i<3;i++)
    				while(eof[i]!=EOF && currtable[i].id==idmin)
    				eof[i]=readFrom(college[i],currtable,i);
    			continue;
    		}
    idmin is a minimal id.
    index represents the file from which the minimal id came from.
    if there the same id from there is another then flag=3
    and it puts the whole minimal row to cancel file.
    then i am not sure but they take the next line of idmin

    but index is holding the number of file from which idmin came from
    i cant understand this last while??

    and why they use continue;
    ??

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  2. nested loop, simple but i'm missing it
    By big_brother in forum C Programming
    Replies: 19
    Last Post: 10-23-2006, 10:21 PM
  3. Replies: 26
    Last Post: 06-15-2005, 02:38 PM
  4. How to change recursive loop to non recursive loop
    By ooosawaddee3 in forum C Programming
    Replies: 1
    Last Post: 06-24-2002, 08:15 AM
  5. 2 largest elements; -1 to stop loop
    By Peachy in forum C Programming
    Replies: 4
    Last Post: 09-16-2001, 05:16 AM