Thread: need help with logic

  1. #1
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391

    need help with logic

    Hey all.

    I have a loop which opens up a file, reads a line from the file into an array, and searches the array for a search string.

    If it successfully finds the search string, it copies the filename(that contains the search string) to another array, and opens up a new file and repeats the process.

    If it can't find the search string in the line, it reads in another line, and repeats the process. When the end of the file is reached, it will open up a new file and start again.

    Here is the code, which works great.

    Code:
    	for( counter = 0; counter < lastfilenumber1; counter++) 
    	{	
    		if((p_openfile = fopen(LineData[counter].storefilename, "r")) == NULL)
    		{
    			perror("Error opening file");
    			exit(EXIT_FAILURE);
    		}
    
    		while((fgets(p_line, FILELINELENGTH, p_openfile)) != NULL) 	
    		{
    			if( (p_searchstring = strstr(p_line, p_searchtext) != NULL))
    			{
    				strcpy(LineData[counter1].filename1, LineData[counter].storefilename); 	
    				counter1++;
    				break;
    			}
    
    			else
    			{
    				continue;
    			}
    		}
    		fclose(p_openfile);
    	}
    	free(p_line);
    Here's what I would like to achieve:

    I would like to count the number of files that does not contain the search string. I would also like to record that filename.

    Here's the code I would like to use, but I can't logically see anywhere I can put it.

    Code:
    counter2 = 0;
    strcpy(LineData[counter2].filename2, LineData[counter].storefilename);
    counter2++;
    I know that the code needs to be in the for(), but also needs to be insulated too, otherwise counter2 will just be exactly the same as counter.

    Any hints?

    Thanks in advance.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Let's first point out the obvious "not needed" bit of code:
    Code:
    			else
    			{
    				continue;
    			}
    Your code will do EXACTLY the same thing if you have this code in or remove it - except it's four lines shorter and more obvious what you are trying to do without it.

    So, searching for "not present" involves going through until either:
    1. you have processed the WHOLE file and not found it.
    2. found what you are looking for.

    The general method is that you have a flag variable (an integer or bool), and set the flag to "not found" before the loop. If you find what you are "not looking for", then mark it as found, and break the loop. After the loop, check if you found what you are "not looking for", and if it was NOT found, then store the name of the file [or, if you are not needing it later on, just print the name and be done with 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. #3
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by matsp View Post
    The general method is that you have a flag variable (an integer or bool), and set the flag to "not found" before the loop. If you find what you are "not looking for", then mark it as found, and break the loop. After the loop, check if you found what you are "not looking for", and if it was NOT found, then store the name of the file [or, if you are not needing it later on, just print the name and be done with it].
    This must be the solution for experts, because I don't understand it. Seems like reverse psychology.

    As always, thanks for your help, Mats.

    Here's a newbie solution that I came up with, which seems to work.

    Code:
    for( counter = 0; counter < lastfilenumber1; counter++) 
    	{	
    		if((p_openfile = fopen(LineData[counter].storefilename, "r")) == NULL)
    		{
    			perror("Error opening file");
    			exit(EXIT_FAILURE);
    		}
    
    		while((fgets(p_line, FILELINELENGTH, p_openfile)) != NULL) 	
    		{
    			if((p_searchstring = strstr(p_line, p_searchtext) != NULL))
    			{
    				strcpy(LineData[counter1].filename1, LineData[counter].storefilename);
    				counter1++;
    				break;
    			}
    		}
    
    		if((fgets(p_line, FILELINELENGTH, p_openfile)) == NULL)
    		{
    			strcpy(LineData[counter2].filename2, LineData[counter].storefilename);
    			printf("\n%s", LineData[counter2].filename2);
    			counter2++;
    		}
    		fclose(p_openfile);
    	}

  4. #4
    Ugly C Lover audinue's Avatar
    Join Date
    Jun 2008
    Location
    Indonesia
    Posts
    489
    Quote Originally Posted by matsp
    The general method is that you have a flag variable (an integer or bool), and set the flag to "not found" before the loop. If you find what you are "not looking for", then mark it as found, and break the loop. After the loop, check if you found what you are "not looking for", and if it was NOT found, then store the name of the file [or, if you are not needing it later on, just print the name and be done with it].
    Which one you don't understand? It's only a flag.
    Code:
    int found = 0; //0 is "not found", -1 is "found"
    Just GET it OFF out my mind!!

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by happyclown View Post
    This must be the solution for experts, because I don't understand it. Seems like reverse psychology.

    As always, thanks for your help, Mats.

    Here's a newbie solution that I came up with, which seems to work.

    Code:
    <snip rest of code>
    		if((fgets(p_line, FILELINELENGTH, p_openfile)) == NULL)
    		{
    			strcpy(LineData[counter2].filename2, LineData[counter].storefilename);
    			printf("\n%s", LineData[counter2].filename2);
    			counter2++;
    		}
    The fgets(...) == NULL can be replaced with feof() - that will tell you if you reached the end of the file. This solution works, but you have already got a method for detecting if you found what you were looking for - so why not use that to indicate if it was found or not. If it was NOT found, then you print the filename.

    Like this (additional/changed code in red):
    Code:
    for( counter = 0; counter < lastfilenumber1; counter++) 
    	{	
                    int found = 0;
    		if((p_openfile = fopen(LineData[counter].storefilename, "r")) == NULL)
    		{
    			perror("Error opening file");
    			exit(EXIT_FAILURE);
    		}
    
                   
    		while((fgets(p_line, FILELINELENGTH, p_openfile)) != NULL) 	
    		{
    			if((p_searchstring = strstr(p_line, p_searchtext) != NULL))
    			{
    				strcpy(LineData[counter1].filename1, LineData[counter].storefilename);
    				counter1++;
                                    found = 1;
    				break;
    			}
    		}
    
                    if(!found)
                    {
    			strcpy(LineData[counter2].filename2, LineData[counter].storefilename);
    			printf("\n%s", LineData[counter2].filename2);
    			counter2++;
    		}
    		fclose(p_openfile);
    	}
    Your way is like walking to the right all the way around the block to get to the house to the left of yours. The feof() is slightly better, but still 10x slower (at least) than the flag solution above [going to the right, then realizing that's the wrong way and walking back again] - which is one extra instruction in when the string is found, and a single instruction instead of a function call to check if the condition is met.

    --
    Mats
    Last edited by matsp; 02-11-2009 at 03:39 AM.
    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.

  6. #6
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by matsp View Post

    Like this (additional/changed code in red):
    Code:
    for( counter = 0; counter < lastfilenumber1; counter++) 
    	{	
                    int found = 0;
    		if((p_openfile = fopen(LineData[counter].storefilename, "r")) == NULL)
    		{
    			perror("Error opening file");
    			exit(EXIT_FAILURE);
    		}
    
                   
    		while((fgets(p_line, FILELINELENGTH, p_openfile)) != NULL) 	
    		{
    			if((p_searchstring = strstr(p_line, p_searchtext) != NULL))
    			{
    				strcpy(LineData[counter1].filename1, LineData[counter].storefilename);
    				counter1++;
                                    found = 1;
    				break;
    			}
    		}
    
                    if(!found)
                    {
    			strcpy(LineData[counter2].filename2, LineData[counter].storefilename);
    			printf("\n%s", LineData[counter2].filename2);
    			counter2++;
    		}
    		fclose(p_openfile);
    	}
    Ah, now I understand!

    Awesome stuff!

    Thanks Mats!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Digital Logic
    By strokebow in forum Tech Board
    Replies: 3
    Last Post: 12-09-2006, 01:05 PM
  2. Logic
    By LordBronz in forum C++ Programming
    Replies: 6
    Last Post: 05-23-2006, 05:41 PM
  3. Actors, cues, event based logic.
    By Shamino in forum Game Programming
    Replies: 2
    Last Post: 04-27-2006, 10:58 PM
  4. Circular Logic
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 10-15-2001, 08:10 PM