file I/O

This is a discussion on file I/O within the C Programming forums, part of the General Programming Boards category; Code: #include<stdio.h> #include <string.h> #include <ctype.h> main( void) { char ch; long position; FILE *ofp1; position = sizeof(ch); if ( ...

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    133

    file I/O

    Code:
    #include<stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    main( void)
    {
    	char ch;
    	long position;
    	FILE *ofp1;
    	
    	position = sizeof(ch);
    	if ( (ofp1 = fopen("tmp1","r+") )== NULL )
    	{printf("File cannot be opened.\n");
    	return 0;}
    		
    	
    		while ( !feof(ofp1) )
    	{	
    		ch = fgetc(ofp1);
    		if (islower(ch))
    		{
    		ch = toupper(ch);
    		fseek(ofp1,-position,SEEK_CUR);
    		fputc(ch,ofp1);}
    	}
    		
    	
    	
    	
    	fclose(ofp1);
    
    	
    
    	return 0;
    }
    File tmp1 only contain a stream of text character. I wrote the above code in an attempt to change all the characters that are in lowercase to uppercase. But i realise the line
    Code:
    fputc(ch,ofp1);
    never seem execute. Can someone tell me why?

  2. #2
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Ok, i just realise it will if i fflush the "ofp1" right after the fputc().
    But i dont understand the reason why it works. I am not clear of how buffering works. Can someone help?

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    >char ch;

    fgetc returns an int. You may want to look at this.

    >while ( !feof(ofp1) )

    Why it's bad to use feof() to control a loop

    >Can someone tell me why?

    http://www.eskimo.com/~scs/C-faq/q12.30.html
    Here it says that "an fseek or fflush is always required between reading and writing in the read/write "+" modes".

    All together then, I might try something like this.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main(void)
    {
       FILE *ofp1 = fopen("tmp1","r+");
       if ( ofp1 == NULL )
       {
          printf("File cannot be opened.\n");
       }
       else
       {
          int ch;
          while( (ch = fgetc(ofp1)) != EOF )
          {
             if ( islower(ch) )
             {
                ch = toupper(ch);
                fseek(ofp1,-1,SEEK_CUR);
                fputc(ch,ofp1);
                fflush(ofp1);
                fseek(ofp1,0,SEEK_CUR);
             }
          }
          fclose(ofp1);
       }
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Code:
    ch = toupper(ch);
                fseek(ofp1,-1,SEEK_CUR);
                fputc(ch,ofp1);
                fflush(ofp1);
                fseek(ofp1,0,SEEK_CUR);
    Dave,

    Why would you want to do " fseek(ofp1,0,SEEK_CUR);"
    for? I dont quite get it. And for "fseek(ofp1,-1,SEEK_CUR);", you mean i dont have to specify the amount of bytes i want to move?
    I try with the '-1' as you did and it works but i cant figure out why too.

    Thanks for ur help so far.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Here's his code explained:
    Code:
    get one character from file, until we're at the end of the file
        if it's lower case
            back up one space, because reading moves the file pointer ahead by the number read
            put the upper case version back in the file
            flush the file
            seek back to where we were just at, ie: the next characte to read
    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Thanks Quzah. I understand that, but why does -1 works? I am taught that you have to specify the amount bytes you to move back. So is he assumming that 1 char is 1byte? So in

    Code:
    fseek(ofp1,-1,SEEK_CUR);
    I can intepret it as move 1byte back from current position?

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>I can intepret it as move 1byte back from current position?<<
    Yes, but you didn't open the file stream in binary mode, so you're using undefined behaviour:
    7.19.9.2 The fseek function
    Synopsis
    1 #include <stdio.h>
    int fseek(FILE *stream, long int offset, int whence);

    For a text stream, either offset shall be zero, or offset shall be a value returned by
    an earlier successful call to the ftell function on a stream associated with the same file
    and whence shall be SEEK_SET.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    >but you didn't open the file stream in binary mode, so you're using undefined behaviour

    Doh!

    >So is he assumming that 1 char is 1byte?

    Yes -- sizeof(char) is 1 by definition. The original code used sizeof(ch), which is a different animal. With ch declared as a char, it would resolve to 1 as intended. But since I had to change it to an int, it might no longer be 1. And since the goal was to move back one character, I just avoided a middle step.

    >Why would you want to do " fseek(ofp1,0,SEEK_CUR);" for?

    Starting from your original, I made the changes I suggested for ch and the loop. When it found a lowercase letter to change to uppercase it broke the loop -- it only changed one lowercase character in the whole file. The fflush(stdout) did not remedy this.

    Now I'm certainly no authority on working with files -- I'm playing along to learn some new things myself.

    From the comp.lang.c FAQ, I tried the second remedy. I may have tried a whence of 1 but quickly noticed that skipped every other lowercase letter. Zero resulted in the correct output.

    At the time I posted, I knew I hadn't done my homework well, but I knew that any oversights would be noticed here. But as a starting point I wanted to point out that ch should have been an int, the issue with controlling a loop with feof, and mention a related FAQ.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Dave,
    From the links you gave me, I gathered that if EOF is assigned to an unsigned char variable, the value is demoted so that the unsigned char variable can store the value. Thereafter if you want to use that char variable to compare with the value EOF, the char variable is then promoted again. Whether it becomes a signed or unsigned value is compiler dependent. However, isnt char variable by default signed? So such promotion wont happened?

    e.g.


    Code:
    char c; /* this declaration creates a signed char variable */
      
    while ((c = fgetc(fp)) != EOF) 
    /* when fgetc(fp) assigned EOF to c , it wont demote */
    /* hence c can be safely compared to EOF without worrying that promoting char c will result in indeterminate sign of the variable */
    
    {
      putchar (c);
    }

  10. #10
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>However, isnt char variable by default signed?
    Read the FAQ (again)
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  11. #11
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Code:
    #include <stdio.h> 
    
    int main(void)
    {
      FILE *fp;
      unsigned char c;
        
      if ((fp = fopen("myfile.txt", "rb")) == NULL)
      {
        perror ("myfile.txt");
        return 0;
      }
      
      while ((c = fgetc(fp)) != EOF)
      {
        putchar (c);
      }
      
      fclose(fp);
      return 0;
    }

    - EOF (0xff 0xff) is returned by fgetc() due to end of input
    - Value demoted to 0xff to be stored in unsigned char c
    - unsigned char c promoted to an int, value goes from 0xff to 0x00 0xff
    - EOF is compared with c, meaning comparison is between 0xff 0xff and 0x00 0xff.
    - The result is FALSE (the values are different), which is undesirable.
    - fgetc() is called again, and still returns EOF. The endless loop begins.
    Sorry Hammer. I am really a lost and slow-thinking sheep here. What did i fail to understand? You illustrated the process with an unsigned char c. But i am trying to say my declaration of char c is a signed variable, so i feel that it should work all the time.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    >However, isnt char variable by default signed?

    Short answer: no.

    Long answer.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    Oh ok. I'm just barely 3months into C. Sorry for my ignorance on that part. So if i declare my char c as signed.e.g.
    Code:
    signed char c;
      
    while ((c = fgetc(fp)) != EOF)
    {
      putchar (c);
    }
    This will always work fine as in the case whereby i declare c as int?

  14. #14
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    >This will always work fine as in the case whereby i declare c as int?

    No, not always. EOF could be a negative value that cannot be represented in a signed char.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  15. #15
    Registered User
    Join Date
    Sep 2003
    Posts
    133
    No, not always. EOF could be a negative value that cannot be represented in a signed char.
    Sigh. I am very confused, but i guess that's because EOF is a macro? I havent learn about that. I did a little readup that says EOF is a macro defined as

    Code:
    #define EOF (-1)
    So what other values could EOF be? In what case can it be other values?

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 08:35 AM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 01:53 AM
  3. 2 questions surrounding an I/O file
    By Guti14 in forum C Programming
    Replies: 2
    Last Post: 08-30-2004, 11:21 PM
  4. File I/O problems!!! Help!!!
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 05-17-2002, 08:09 PM
  5. advice on file i/o
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-29-2001, 04:56 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21