Thread: ASCII File Copy Problem: Expand tabs to multiple spaces

  1. #1
    Registered User matrixx333's Avatar
    Join Date
    Mar 2009
    Posts
    67

    ASCII File Copy Problem: Expand tabs to multiple spaces

    Hello everyone,

    I am working an an example in the book I am studying and the question is:

    Write a program to copy a file, expanding all tabs to multiple spaces.

    I have a text file in my directory called 14E02_in.txt that has two lines:

    This is the first line to text. (spaces are actually tabs)
    This is the second line of text. (spaces are actually tabs)

    In trying to figure this out, I did some googling and came across someone else trying to do something similar. The advice that was given explained that a '\t' in memory is stored as 1 byte and expanding the tab to 8 spaces would take up 8 bytes, so instead of trying to operate in memory, he suggested:

    My suggestion: Rather than trying to operate in place (or trying to operate in memory, even) I would suggest writing this as a filter -- reading from stdin and writing to stdout one character at a time; that way you don't need to worry about memory allocation or deallocation....
    This is exactly what I am trying to accomplish in my program, instead of reading from stdin and writing to stdout I am reading from in_file and writing to out_file. Here is the code I've come up with so far:

    Code:
    #include <stdio.h>
    
    int main(void)
    {
    		char in_name[] = "14E02_in.txt";
    		char out_name[] = "14E02_out.txt";
    		char space_str[] = "        "; // 8 spaces
    		FILE *in_file;
    		FILE *out_file;
    		int ch1; // used for fgetc
    		
    		in_file = fopen(in_name, "r");
    		if (in_file == NULL) {
    				fprintf(stderr, "Error: Unable to open %s\n", in_name);
    				exit (8);
    		}
    		
    		out_file = fopen(out_name, "w");
    		if (out_file == NULL) {
    				fprintf(stderr, "Error: Unable to write to %s\n", out_name);
    				exit (8);
    		}
    		
    		while (1) {
    				ch1 = fgetc(in_file);
    				if (ch1 == '\t') 
    						ch1 = ' ';
    				if (ch1 == EOF)
    						break;
    						
    				fputc(ch1, out_file);
    		}
    			
    		fclose(in_file);
    		fclose(out_file);
    		
    		return 0;
    }
    This works, but as you can see, it is replacing the tabs with only one space. I know I can't declare:

    Code:
    if (ch1 == '\t') 
    		ch1 = "        ";
    because I will get an error trying to assign a string value to an int. There's something eluding me and any help pointing me in the right direction would be appreciated.

  2. #2
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Here is a slightly modified version of your program:
    Code:
    #include <stdio.h>                
    #include <stdlib.h>               
    
    int main(void)
    {             
        char in_name[] = "14E02_in.txt";
        char out_name[] = "14E02_out.txt";
        FILE *in_file;
        FILE *out_file;
        int ch1;                    // used for fgetc
        int i;
        int spaces = 8;
    
        in_file = fopen(in_name, "r");
        if (in_file == NULL) {
            fprintf(stderr, "Error: Unable to open %s\n", in_name);
            exit(8);
        }
    
        out_file = fopen(out_name, "w");
        if (out_file == NULL) {
            fprintf(stderr, "Error: Unable to write to %s\n", out_name);
            exit(8);
        }
    
        while (1) {
            ch1 = fgetc(in_file);
            if (ch1 == '\t') {      /* Now we want to insert 8 spaces to replace the tab */
                ch1 = ' ';
                for (i = 0; i < spaces; i++) {
                    fputc(ch1, out_file);
                }
            }
            if (ch1 == EOF)
                break;
    
            fputc(ch1, out_file);
        }
    
        fclose(in_file);
        fclose(out_file);
    
        return 0;
    }
    I also removed your one unused variable,
    Code:
    char space_str[] = "        "; // 8 spaces
    Is that what you were thinking of?
    Last edited by kermit; 10-20-2009 at 04:41 AM.

  3. #3
    Registered User matrixx333's Avatar
    Join Date
    Mar 2009
    Posts
    67


    That's exactly the answer I was looking for! Thank you for your help. I understand how you came to the conclusion.

    Just curious, why did you include:

    Code:
    #include <stdlib.h>

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    I #included that to catch your call to the exit function. What compiler are you using? Do you have the warnings turned on? That would tell you when you forget things not including the proper header files.

  5. #5
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I don't think the above programs are right. A TAB is not always expanded to eight (8) spaces. It depends on the current position... Tabs are fixed column positions, so you may have to calculate just how many spaces to insert until the next modulo 8 position. Only thereafter, each naked tab would indeed expand to 8 spaces.

  6. #6
    Registered User matrixx333's Avatar
    Join Date
    Mar 2009
    Posts
    67
    Quote Originally Posted by kermit View Post
    I #included that to catch your call to the exit function. What compiler are you using? Do you have the warnings turned on? That would tell you when you forget things not including the proper header files.
    Kermit, I see what you are talking about now. I am using:

    Compiler: gcc version 3.4.4

    I did not have warnings turned on. I recompiled the file without the including stdlib.h, turned warnings on, and indeed received a warning:

    warning: implicit declaration of function `exit'

    I then looked up some reference material and found that the exit function is defined in stdlib.h, explaining why I was getting the warning without including it before. Thank you for pointing that out.

    Quote Originally Posted by nonoob View Post
    I don't think the above programs are right. A TAB is not always expanded to eight (8) spaces. It depends on the current position... Tabs are fixed column positions, so you may have to calculate just how many spaces to insert until the next modulo 8 position. Only thereafter, each naked tab would indeed expand to 8 spaces.
    Thank you for your input nonoob!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  4. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM