Thread: A text file is written to another text file, at a sentence per line: one line works

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    308

    A text file is written to another text file, at a sentence per line: one line works

    Here is my code:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define LINES 4096
      
    /* function prototype for percentage calculation */
    void percentage_calculation_numbers(char*, int, char*);
     
    /* function prototype to count the number of characters in a string */
    int countchar (char []);
     
    /* function prototype to find the first and last letter in the word */
    char find_letter (char* a, char* b);
    char red;
     
    /* function prototype to reverse the letters in the word */
    char* rev(char* str);
    char* reverse;
     
    /* function so I don't have to type getch all over the place */
    void MyExit(void) { system("pause"); }
       
    /* the main program */
    int numchar;
     
    int main ()
    {   
         /* declaring and initiaizing variables */
         FILE *book;
    	 FILE *book2;
         int i;
         char *filedata = malloc(4096);    
         char buffer[LINES];
         atexit(MyExit);    
         i = 0;
         /* open text file or report error */
         book = fopen("readtext1.txt", "r+");
         book2 = fopen("readtext.txt", "a+"); 
         if(!book)   
         {   
              perror("Error: file readtext1.txt was not found or opened");   
              return 0;   
         }
         if(!book2)   
         {   
              perror("Error: file readtext.txt was not found or opened");   
              return 0;   
         } 
         /* read from file */
                  while(fgets(buffer, sizeof(buffer), book)!=NULL)
                  { 
    				  for (  i = 0; i < 4096; ++i )
    				  {
    					  if ( buffer[i] == '.' )
    					  {
    						  buffer[i] = '\n';
    						  fprintf(book2, "%s\n", buffer);
    						  /* we're done, so just exit the function by returning */
    						  return; 
    					  }
    				  }
                  }
                   
                  fclose(book);
    			  fclose(book2);
         return 0;
    }
    Here is readtext1.txt contents:

    Code:
    car ran.car ran. jeremy car ran ran.
    Here is the contents of readtext after running the program:

    Code:
    car ran
    car ran. jeremy car ran ran.
    What I want readtex to look like is:

    Code:
    car ran
    car ran 
    jeremy car ran ran
    Can you just give me the code for this problem, I see you do that sometimes in some threads. If not how about a code example?

  2. #2
    Registered User
    Join Date
    Apr 2011
    Posts
    308
    I am now able to get the input out put the way I want, see my code below:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define LINES 4096
      
    /* function prototype for percentage calculation */
    void percentage_calculation_numbers(char*, int, char*);
     
    /* function prototype to count the number of characters in a string */
    int countchar (char []);
     
    /* function prototype to find the first and last letter in the word */
    char find_letter (char* a, char* b);
    char red;
     
    /* function prototype to reverse the letters in the word */
    char* rev(char* str);
    char* reverse;
     
    /* function so I don't have to type getch all over the place */
    void MyExit(void) { system("pause"); }
       
    /* the main program */
    int numchar;
     
    int main ()
    {   
         /* declaring and initiaizing variables */
         FILE *book;
    	 FILE *book2;
         int i;
         char *filedata = malloc(4096);    
         char buffer[LINES];
         atexit(MyExit);    
         i = 0;
         /* open text file or report error */
         book = fopen("readtext1.txt", "r+");
         book2 = fopen("readtext.txt", "a+"); 
         if(!book)   
         {   
              perror("Error: file readtext1.txt was not found or opened");   
              return 0;   
         }
         if(!book2)   
         {   
              perror("Error: file readtext.txt was not found or opened");   
              return 0;   
         } 
         /* read from file */
                  while(fgets(buffer, sizeof(buffer), book)!=NULL)
                  { 
    				  for (  i = 0; i < 4096; ++i )
    				  {
    					  if (buffer[i] == '\0')
    					  {
                                 break;
    					  }
    					  else if ( buffer[i] == '.' )
    					  {
    						  buffer[i] = '\n';
    						  fprintf(book2, "%s\n", buffer);
    					  }
    				  }
                  }
                   
                  fclose(book);
    			  fclose(book2);
         return 0;
    }
    But I have an error in my output, it repeats.

    Code:
    car ran
    car ran. jeremy car ran ran.
    
    car ran
    car ran
     jeremy car ran ran.
    
    car ran
    car ran
     jeremy car ran ran
    So something is still not working.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Code:
    /* read from file */
                  while(fgets(buffer, sizeof(buffer), book)!=NULL)
                  { 
    				  for (  i = 0; i < 4096; ++i )
    				  {
    					  if (buffer[i] == '\0')
    					  {
                                 break;
    					  }
    					  else if ( buffer[i] == '.' )
    					  {
    						  buffer[i] = '\n';
    						  fprintf(book2, "%s\n", buffer);
    					  }
    				  }
                  }
    This is your main reading loop, is it not?

    A few suggestions:

    1) You are taking in a full line of text, then when you find a period, you are printing out to a file, that sentence.

    What happens to the rest of the row of text?

    2) You have a while loop to get each line of text. You also have an inner loop to handle the char's in each line of text - but where's the beef? Where's the call to your other functions to handle the char's? Where's the code in the inner loop to do much of anything?

    It's a desert of logic inside that inner for loop!


    3) You hard code in 4096 char's, but wouldn't it be more robust to just make the loop stop logically?

    Code:
    for(i=0;buff[i]!= '\0';i++)
    I see the problem that your processing loop is rather empty.

    You may be processing a newline only. That IS a line of text, but obviously not a line of text you want to deal with inside the inner for loop. This will stop most or all of that:

    First line of code, inside the out while loop:

    <your while loop is here>
    Code:
       if(buff[0]=='\n')
          continue;   //continue, not break!
    <your for loop is down here>

  4. #4
    Registered User
    Join Date
    Apr 2011
    Posts
    308
    Here is the code with your modifications:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define LINES 4096
      
    /* function prototype for percentage calculation */
    void percentage_calculation_numbers(char*, int, char*);
     
    /* function prototype to count the number of characters in a string */
    int countchar (char []);
     
    /* function prototype to find the first and last letter in the word */
    char find_letter (char* a, char* b);
    char red;
     
    /* function prototype to reverse the letters in the word */
    char* rev(char* str);
    char* reverse;
     
    /* function so I don't have to type getch all over the place */
    void MyExit(void) { system("pause"); }
       
    /* the main program */
    int numchar;
     
    int main ()
    {   
         /* declaring and initiaizing variables */
         FILE *book;
    	 FILE *book2;
         int i;
         char *filedata = malloc(4096);    
         char buffer[LINES];
         atexit(MyExit);    
         i = 0;
         /* open text file or report error */
         book = fopen("readtext1.txt", "r+");
         book2 = fopen("readtext.txt", "a+"); 
         if(!book)   
         {   
              perror("Error: file readtext1.txt was not found or opened");   
              return 0;   
         }
         if(!book2)   
         {   
              perror("Error: file readtext.txt was not found or opened");   
              return 0;   
         } 
         /* read from file */
    	 while(fgets(buffer, sizeof(buffer), book)!=NULL)
    	 {
    		 if(buffer[0]=='\n')
    			 continue;   //continue, not break!
    		 for(i=0;buffer[i]!= '\0';i++)
    		 {
    			 if ( buffer[i] == '.' )
    			 {
    				 buffer[i] = '\n';
    				 fprintf(book2, "%s\n", buffer);
    			 }
    		 }
    	 }
    	 fclose(book);
    	 fclose(book2);
         return 0;
    }
    The results:

    Code:
    car ran
    car ran. jeremy car ran ran.
    
    car ran
    car ran
     jeremy car ran ran.
    
    car ran
    car ran
     jeremy car ran ran
    Thanks for the tips though. Any more advice?
    Last edited by jeremy duncan; 11-11-2011 at 01:16 PM.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You're caught up in the "sentence versus line of text" problem. Since a line of text may have parts of more than one sentence, you're getting multiple print outs of buffer.

    How do you want to handle the rest of the line of text, when a period has been encountered in the middle of the line? You can't keep printing out buffer, after the first sentence in buffer has been handled. You need to move a pointer or an index number, up to the current data still not handled by the program (One position after the period).

    That's why I suggested handling rows of text, and not sentences. A sentence might go on for two or three rows of text - now how are you going to handle that?

    It's not like, by using rows of text instead of sentences, that any sentence will be skipped - they'll all be looked at and counted up. What you have now is awkward.

    fgets() is a fine way to do this, but if you can't accept using rows as your unit for processing, then you may need to change from using fgets() to using int c=fgetc(), kind of input. That will also eliminate your inner for loop, so that would be a slight gain.

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    308
    Would int c=fgetc() get all the strings in the sentence though? I read some of the documentation for fgetc and it can find a characte in a string but it didn't say it returned all other strings before that character. I'm not interested in processing the sum of the words, but a sentence at a time.
    So if fgetc can't do what I need then I will have to open the file and manually make the sentences one per line.
    Thanks for the reply, any code examples on how to setup fgetc so it gets the sentence?

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You'll need to supply a text file for this. I used the Gettysburg Address.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main(void) {
       int i, n=0;
       char buff[1024];
       FILE *fp=fopen("Gettysburg.txt", "r");
       if(!fp) {printf("Error: unable to open input file!\n"); return 1;}
    
       while(n!=EOF) {
          buff[0]='\0';
          for(i=0;i<sizeof(buff);i++) {
             n=fgetc(fp);
             if(n==EOF)
                break;
             
             if(n=='.') {
                buff[i]='\0';   
                break; 
             }
             if(ispunct(n)) {
                --i;
                continue;
             }
             buff[i]=n;
          }
          if(n==EOF) 
             break;
          printf("%s\n",buff);
          getchar(); 
       }
       fclose(fp);
       putchar('\n');
       return 0;
    }

  8. #8
    Registered User
    Join Date
    Apr 2011
    Posts
    308
    Thank you Adak, that works great. Problem solved.

  9. #9
    Registered User
    Join Date
    Apr 2011
    Posts
    308
    I reindented the code and renamed it's variables.
    This way if somebody wants to understand it and doesn't know how C works they can better understand it now.

    Thanks again Adak.

    Code:
    #include <stdio.h>
    #include <ctype.h>
     
    int main(void)
    {
    	int character, file_character=0;
    	char buffer[1024];
    	FILE *fp=fopen("readtext.txt", "r");
    	if(!fp) {printf("Error: unable to open input file!\n"); return 1;}
    	
    	while(file_character!=EOF)
    	{
    		buffer[0]='\0';
             for(character=0;character<sizeof(buffer);character++) 
    	              {
    					  file_character=fgetc(fp);
    				      if(file_character==EOF)
    						  break;
    
    				      if(file_character=='.')
    					  {
    							  buffer[character]='\0';  
    							  break;
    					  }
    				      if(ispunct(file_character)) 
    					  {
    							  --character;
    							  continue;
    					  }
    
    				      buffer[character]=file_character;
                      }
    		 if(file_character==EOF)
    			 break;
             printf("%s\n",buffer);
             getchar();
    	}
       fclose(fp);
       putchar('\n');
    
       return 0;
    }

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You're welcome Jeremy.

    Try not to sound so surprised it worked great, OK?

    Those huge indentations may look great atm, but they will run your line of text right off the far right of the page, on most kinds of serious programming.

    "file_character" for a variable name? Really? You must be a good keyboarder, Jeremy!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read text file line by line and write lines to other files
    By magische_vogel in forum C Programming
    Replies: 10
    Last Post: 01-23-2011, 10:51 AM
  2. Replies: 7
    Last Post: 12-13-2010, 02:13 PM
  3. end of line in text file
    By spveer in forum C Programming
    Replies: 5
    Last Post: 08-18-2005, 12:43 AM
  4. Position FILE pointer to a specified line of Text file
    By jessica_xie in forum C Programming
    Replies: 2
    Last Post: 02-04-2005, 03:52 PM
  5. Getting one line of a text file
    By Okiesmokie in forum C++ Programming
    Replies: 3
    Last Post: 03-01-2002, 09:26 PM