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

  1. #1
    Banned
    Join Date
    Oct 2008
    Posts
    1,535

    why this while condition doesnt stop the loop??

    i told it that when it reaches EOF then stop but it keeps putting 005 over and over ...
    why ??
    it should get out of the loop after it wrote 005
    ???

    file1
    000
    001
    002
    003
    005

    file2
    003
    004
    005

    file3
    005
    006
    007


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define false 0
    #define true 1
    
    int equal(char*f1,char*f2,char*f3);
      int smallest(char*f1,char*f2,char*f3);
    int main()
    {
    
       FILE *file[3];
       FILE *common;
       
       char f[3][20];
        
       int small;
        int equall;    
       file[0]=fopen("g:\\1.txt","r");
       file[1]=fopen("g:\\2.txt","r");
       file[2]=fopen("g:\\3.txt","r");
       common=fopen("g:\\common.txt","w");
       fscanf(file[0],"%9s",f[0]);
       fscanf(file[1],"%9s",f[1]);
       fscanf(file[2],"%9s",f[2]);
       while(fgetc(file[0])!=EOF||fgetc(file[1])!=EOF||fgetc(file[2])!=EOF)
       {
           small=smallest(f[0],f[1],f[2]);
           equall=equal(f[0],f[1],f[2]);
          if(equall!=-1)
    	  {
            fputs(f[equall],common);
            fscanf(file[equall],"%20s",f[equall]);
    		fputc('\n',common);
    	  }
    
          
          fscanf(file[small],"%20s",f[small]);
       } 
    
       fclose(file[1]);
       fclose(file[2]);
       fclose(file[0]);
       return 0;
    }
    
    int smallest(char* f_a,char* f_b,char* f_c)
    {
         int i=0;
        char* pLowest = f_a;
         if(strcmp(pLowest, f_b) > 0)
        {   
           i=1;
          pLowest = f_b;
        }
          if(strcmp(pLowest, f_c) > 0)
         {
           pLowest = f_c;
         i=2;
         }
          return i;
    }
    
      int equal(char* f1,char*f2,char*f3)
      {
          
         if(strcmp(f1,f3)==0)
        {
           return  0;
        }
        if(strcmp(f1,f2)==0)
        {
           return  1;
        }
         if(strcmp(f2,f3)==0)
        {
           return  2;
        }
         return -1;
      }
    Last edited by transgalactic2; 03-30-2009 at 05:41 AM.

  2. #2
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Your loop will only end when all file streams have returned EOF (at the same time). Maybe you meant to use && instead of ||?

  3. #3
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    no i want it to kep till there are two files
    which i could compare them.
    but its not logical thet i have 10 EOF
    no file has 10 rows
    ???

  4. #4
    apprentiCe
    Join Date
    Oct 2008
    Location
    Hyderabad,India
    Posts
    136
    you opened "common" but never closed it
    Code:
    printf("%c%c%c%c%c%c%c",0x68,0x68^0xd,0x68|0x4,0x68|0x4,0x68|0xf,0x68^0x49,0x68^0x62);

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Okay, let's say you got to the state
    005 005 005

    Then, you read from the first, but it's an end of file. But the content will still be 005. So upon next searching which is lowest, it will try to read from the first file again. Again, the data won't change, since it's an end of file.
    --> infinite loop

    @creeping death:
    I think it's always closed implicitly on the end of the program. I'm not sure if this is required, however, and while it is better practice to close it, on all architectures I know of and with all compiles I know of it runs fine without closing.

  6. #6
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    so what you suggest
    ??

    how do i change it sol it will compre the two left files
    ??

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Why not keep the whie-condition, and if a file has reached EOF, you set the content value of that file to something incredibly high? That way, you will keep reading the other files.

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

  8. #8
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i am not allowed to change the input files

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by transgalactic2 View Post
    i am not allowed to change the input files
    No, that's not what I meant. If you READ from the file and find that you didn't get anything back (the function returns EOF), then you set the value to indicate that "this file reached the end" and by using the right value here you can keep going, reading from the other files. When all your values are "reached the end", you can stop.

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

  10. #10
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    but i do the EOF check in the while condition

    i can check if it reached EOF but how to make it compare only two files now??

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by transgalactic2 View Post
    but i do the EOF check in the while condition

    i can check if it reached EOF but how to make it compare only two files now??
    Yes, you are checking if ALL files are EOF. But all files won't be EOF if the lowest value right now is in a file that has already reached EOF (because that variable will never reach a new value to allow the other two files to be read). This is why I suggested that when you reach EOF in a particular file, you set the corresponding string to something that is always going to be considered high - that way, you will end up with all files being read until the end.

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

  12. #12
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i tried this but it gives me a bug
    what is the right way?
    Code:
    if(getc(file[small])!=EOF)
    	  {
             fscanf(file[small],"%20s",f[small]);
    	  }
    	  else
    	  {  
            f[small]="999999"; 
    	  }

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    use strcpy() to assign strings.

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

  14. #14
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    ok i did that
    but i dont get
    003
    005
    file .
    intead i get
    005
    999999
    999999

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define false 0
    #define true 1
    
    int equal(char*f1,char*f2,char*f3);
      int smallest(char*f1,char*f2,char*f3);
    int main()
    {
    
       FILE *file[3];
       FILE *common;
       
       char f[3][20];
        
       int small;
        int equall;    
       file[0]=fopen("g:\\1.txt","r");
       file[1]=fopen("g:\\2.txt","r");
       file[2]=fopen("g:\\3.txt","r");
       common=fopen("g:\\common.txt","w");
       fscanf(file[0],"%9s",f[0]);
       fscanf(file[1],"%9s",f[1]);
       fscanf(file[2],"%9s",f[2]);
       while(fgetc(file[0])!=EOF||fgetc(file[1])!=EOF||fgetc(file[2])!=EOF)
       {
           small=smallest(f[0],f[1],f[2]);
           equall=equal(f[0],f[1],f[2]);
          if(equall!=-1)
    	  {
            fputs(f[equall],common);
            fscanf(file[equall],"%20s",f[equall]);
    		fputc('\n',common);
    	  }
    
          if(getc(file[small])!=EOF)
    	  {
             fscanf(file[small],"%20s",f[small]);
    	  }
    	  else
    	  {  
            strcpy(f[small],"999999"); 
    	  }
       } 
    
       fclose(file[1]);
       fclose(file[2]);
       fclose(file[0]);
       fclose(common);
       return 0;
    }
    
    int smallest(char* f_a,char* f_b,char* f_c)
    {
         int i=0;
        char* pLowest = f_a;
         if(strcmp(pLowest, f_b) > 0)
        {   
           i=1;
          pLowest = f_b;
        }
          if(strcmp(pLowest, f_c) > 0)
         {
           pLowest = f_c;
         i=2;
         }
          return i;
    }
    
      int equal(char* f1,char*f2,char*f3)
      {
          
         if(strcmp(f1,f3)==0)
        {
           return  0;
        }
        if(strcmp(f1,f2)==0)
        {
           return  1;
        }
         if(strcmp(f2,f3)==0)
        {
           return  2;
        }
         return -1;
      }

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, I think your equal function needs to take the special 9999 into account and not make it equal even if it is.

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

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