C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here
  #1  
Old May 3rd, 2008, 04:25 AM
angel.white angel.white is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2008
Location: Kansas
Posts: 17 angel.white User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 h 40 m 44 sec
Reputation Power: 0
ANSI C: Checking for a blank line in an input file

Hello, I am trying to determine if the next line is blank in my input file, and seem to be having difficulty :/

Here is my function:

C Code:
Original - C Code
  1. BOOLEAN NextLineBlank( FILE **fin)
  2. {
  3.     if( getc(*fin)=='\n')
  4.         return TRUE;
  5.    
  6.     fseek(*fin, -1, ftell(*fin));
  7.     return FALSE;
  8. }


I figure if it is blank, it will eat up the \n in the getc, and then be at the correct location for the next line, but if it has data on that line then it will move the pointer back one character to the correct location for when it gets read in.

Unfortunately, it does not seem to be moving the pointer back at all, it always eats up that character, and so every non-blank line gets read in without the first character.

Reply With Quote
  #2  
Old May 3rd, 2008, 07:59 AM
clifford's Avatar
clifford clifford is offline
Contributing User
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: UK
Posts: 2,395 clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Week 6 Days 3 h 47 m 42 sec
Reputation Power: 320
Line ends in text files vary. The convention on Windows is to use CR-LF. That is "\r\n". You may need to take that into account. While in text mode getc() will convert CR-LF to '\n', but fseek() still regards it as two characters.


Clifford

Reply With Quote
  #3  
Old May 3rd, 2008, 03:48 PM
angel.white angel.white is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2008
Location: Kansas
Posts: 17 angel.white User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 h 40 m 44 sec
Reputation Power: 0
Quote:
Originally Posted by clifford
Line ends in text files vary. The convention on Windows is to use CR-LF. That is "\r\n". You may need to take that into account. While in text mode getc() will convert CR-LF to '\n', but fseek() still regards it as two characters.


Clifford

Thank you, Clofford.

I tested the newline in file with this function:
C Code:
Original - C Code
  1. void integers( char InputFile[])
  2. {
  3.     FILE *fin;
  4.     fin = fopen( InputFile, "r");
  5.     int c;
  6.    
  7.     while( (c=getc(fin)) != EOF)
  8.     {
  9.         if( c != '\n')    printf( "%3d ",  c);
  10.         else              printf( "%3d\n", c);
  11.     }
  12.     fclose(fin);
  13. return;
  14. }



Here is a segment of ouput:
Code:
119  97 114 112  45 100 114 105 118 101  32 109 111 116 111 114  10
 49  49  52  52  45  48  49  10
 66  48  49  55  10
 10
 10
 102 108  97 110 103 101  32 104 105 110 103 101  10


So I think it exclusively uses \n at the ends. This output should look like:

Quote:
Originally Posted by File Input
warp-drive motor
1144-01
B017


flange hinge


But instead is read in as:
Quote:
Originally Posted by Data After Reading In
arp-drive motor
1144-01
017
NA
NA
lange hinge
(note that I set unused values in my data type to be "NA", so every NA means there is no data, or for our purposes, a blank line)

So I could be confused, but I don't think the line ends are causing the problem, I think the problem is that my fseek function is wrong.



edit: Yes, that is the problem, I just tested it by adding the code
C Code:
Original - C Code
  1. printf( "c = %d\n", getc(fin));
  2. fseek(fin, -1, ftell(fin));
  3. printf( "c = %d\n", getc(fin));
  4. fseek(fin, -1, ftell(fin));


To the function that is reading in the data, I figure if it works, it will print the next character in the file, back up one character, and then print that one again, then back up again, so the output for the segment above should be
c=x
c=x
Where x is the next character being read in, but instead it is giving me
c=x
c=y
where x and y are not the same character.

So my fseek function must be incorrect.

Reply With Quote
  #4  
Old May 3rd, 2008, 08:41 PM
sizablegrin's Avatar
sizablegrin sizablegrin is offline
Stubborn ol' L'User
Click here for more information.
 
Join Date: Jun 2005
Posts: 3,062 sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 1 Day 9 h 53 m 2 sec
Reputation Power: 1441
I think that your problem is not thinking things through, despite hints. Have you visited the Commonly Asked Questions thread?

Would you care to post the EXACT contents of your target file and the EXACT code of your processor file? It's a huge pain in the *** for your respondents, but it's your best hope.
__________________
C/C++ pointers (Original in the "Commonly Asked Questions" thread).

Reply With Quote
  #5  
Old May 4th, 2008, 12:33 AM
angel.white angel.white is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2008
Location: Kansas
Posts: 17 angel.white User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 h 40 m 44 sec
Reputation Power: 0
Quote:
Originally Posted by sizablegrin
I think that your problem is not thinking things through, despite hints. Have you visited the Commonly Asked Questions thread?

Would you care to post the EXACT contents of your target file and the EXACT code of your processor file? It's a huge pain in the *** for your respondents, but it's your best hope.

Of course, and thank you.

Program definitions (defines boolean and my data structure: PARTS_RECORD)
C Code:
Original - C Code
  1. /* File prog_defs.h                                                        */
  2.  
  3. #ifndef PROG_DEFS_H
  4. #define PROG_DEFS_H
  5.  
  6.   /* Fundamental definitions for the program. */
  7.  
  8.   #define TABLE_SIZE  83
  9.  
  10.   #define EQ(a,b)  (strcmp((a),(b)) == 0)
  11.   #define LT(a,b)  (strcmp((a),(b)) < 0)
  12.   #define GT(a,b)  (strcmp((a),(b)) > 0)
  13.  
  14.   typedef enum boolean_type
  15.   { FALSE, TRUE }
  16.   BOOLEAN;
  17.  
  18.  
  19.   /* Typedefs for hash element */
  20.  
  21.   typedef char KEYTYPE[8]; /* keytype for arraylist*/
  22.  
  23.   typedef struct element_type
  24.   {
  25.      char partname[40];   /* part name */
  26.      KEYTYPE key;         /* part id */
  27.      char supp1[5];
  28.      char supp2[5];
  29.      char supp3[5];       /* up to 3 supplier codes */
  30.   }PARTS_RECORD;
  31.  
  32.   typedef PARTS_RECORD ELEMENT;  /* ELEMENT of type RECORD */
  33. #endif
  34.  


Header file:
C Code:
Original - C Code
  1. /* File program6.h                                                         */
  2.  
  3. #ifndef PROGRAM6_H
  4. #define PROGRAM6_H
  5.  
  6.   #include "prog_defs.h"
  7.  
  8.   /* Function Prototypes */
  9.  
  10.   void ReadInData( char InputFile[]);
  11.   int NextLineBlank( FILE **fin);
  12. #endif
  13.  


(note that the name and keytype lines will always have data, but there may be between 0 and 3 supplier codes, if there are 3 codes, each code has its own line, if there are fewer, the ones that do not exist are represented with a blank line)

My C file:
C Code:
Original - C Code
  1. #include <stdio.h>
  2.  
  3. #include "prog_defs.h"
  4. #include "program6.h"
  5. #include "hash.h"
  6.  
  7. int main()
  8. {
  9.     char InputFile[] = "parts.data";
  10.     ReadInData( InputFile);
  11.  
  12. return 0;
  13. }
  14.  
  15.  
  16. /* This function reads data from the data file to the hash table */
  17. void ReadInData( char InputFile[])
  18. {
  19.     FILE *fin;
  20.     fin = fopen( InputFile, "r");
  21.     PARTS_RECORD TempRec;
  22.  
  23.     /* Empty File */
  24.     if( getc(fin) == EOF) return;
  25.    
  26.     /* Read in each part from the data file */
  27.     while(TRUE)
  28.     {
  29.       /* Read in part name and parts code (keytype) */
  30.       fscanf( fin, "%[^\n]s", TempRec.partname); getc(fin);
  31.       fscanf( fin, "%[^\n]s", TempRec.key); getc(fin);
  32.  
  33.       /* Read in supplier code 1 */
  34.       if( NextLineBlank(&fin))
  35.             sprintf( TempRec.supp1, "%s", "NA" );
  36.       else{ 
  37.             fscanf ( fin, "%[^\n]s", TempRec.supp1); getc(fin);}
  38.  
  39.       /* Read in supplier code 2 */     
  40.       if( NextLineBlank(&fin))
  41.             sprintf( TempRec.supp2, "%s", "NA" );
  42.       else{ 
  43.             fscanf ( fin, "%[^\n]s", TempRec.supp2); getc(fin);}
  44.  
  45.       /* Read in supplier code 3 */
  46.       if( NextLineBlank(&fin))
  47.             sprintf( TempRec.supp3, "%s", "NA" );
  48.       else{ 
  49.             fscanf ( fin, "%[^\n]s", TempRec.supp3 );}
  50.  
  51.       /* Determine whether to read in more data */
  52.       if(   getc(fin) == EOF) {  break;                       }
  53.       else                    {  fseek(fin, -1, ftell(fin))}
  54.    
  55.       /* This output is for testing purposes only */
  56.       printf( "%s\n", TempRec.partname);
  57.       printf( "%s\n", TempRec.key);
  58.       printf( "%s\n", TempRec.supp1);
  59.       printf( "%s\n", TempRec.supp2);
  60.       printf( "%s\n", TempRec.supp3);
  61.     }
  62.     fclose( fin);
  63. }
  64.  
  65.  
  66.  
  67. /* Checks if next line is blank (no data)
  68. *     if blank  return TRUE
  69. *     if ~blank return FALSE                  */
  70. int NextLineBlank( FILE **fin)
  71. {
  72.     BOOLEAN IsBlank;
  73.  
  74.     if( getc(*fin)=='\n')
  75.         IsBlank = TRUE;                /* Next line IS blank     */
  76.     else
  77.     {
  78.         fseek(*fin, -1, ftell(*fin))/* reset file pointer     */
  79.         IsBlank = FALSE;               /* Next line IS NOT blank */
  80.     }
  81.     return IsBlank;