Thread: reading file characters into an int array

  1. #1
    Codus Conjectus spongefreddie's Avatar
    Join Date
    Sep 2010
    Location
    USA
    Posts
    86

    reading file characters into an int array

    Hey All,

    I'm going through C Primer Plus (4th Edition). Chapter 13 is about File Input/Output. The 12th exercise is totally stumping me, and here's why...

    It wants me to open an already existing text file (that I created as per book instruction), and then copy the characters into an int array. Then, I'm supposed to take that array, and create another array (this time type char), with which I can trade out characters during transfer, thus making a crude digital picture. The pre-existing text file has a 20x30 array of single digits separated by spaces (making the lines 60 characters long).

    Example line from text file (first line out of 20):
    0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0

    The problem is I've already figured out how to open the file, alter the data and print it to either the screen or a new file... but only if I skip the extra step of copying the original text file characters to the int array.

    I feel like it must be important for some reason for me to be able to copy text characters into an int array from an open file stream, otherwise the book wouldn't ask me to do it.

    Here's one of my failed solutions so far:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define LINES 20
    #define CHARS 30
    
    
    int main(void)
    {
    	int ch;				// doesn't work with 'char ch' either
    	int a, b;
    	FILE * fpsrc;
    	int numbers[LINES][CHARS];			// array to hold all file characters as integers
    
    
    	if ((fpsrc = fopen("picture1.txt", "r")) == NULL)			// open to read-only
    	{
    		printf("Sorry, couldn't find or open \"%s\".\n", "picture1.txt");
    		exit(EXIT_FAILURE);
    	}
    
    	while ((ch = fgetc(fpsrc)) != EOF)   // doesn't work with getc() either
    	{
    		if (ch == 32)
    			continue;
    		else if (ch == 48)
    		{
    			numbers[a][b] = 0;
    			b++;
    			continue;
    		}
    		else if (ch == 49)
    		{
    			numbers[a][b] = 1;
    			b++;
    			continue;
    		}
    		else if (ch == 50)
    		{
    			numbers[a][b] = 2;
    			b++;
    			continue;
    		}
    		else if (ch == 51)
    		{
    			numbers[a][b] = 3;
    			b++;
    			continue;
    		}
    		else if (ch == 52)
    		{
    			numbers[a][b] = 4;
    			b++;
    			continue;
    		}
    		else if (ch == 53)
    		{
    			numbers[a][b] = 5;
    			b++;
    			continue;
    		}
    		else if (ch == 54)
    		{
    			numbers[a][b] = 6;
    			b++;
    			continue;
    		}
    		else if (ch == 55)
    		{
    			numbers[a][b] = 7;
    			b++;
    			continue;
    		}
    		else if (ch == 56)
    		{
    			numbers[a][b] = 8;
    			b++;
    			continue;
    		}
    		else if (ch == 57)
    		{
    			numbers[a][b] = 9;
    			b++;
    			continue;
    		}
    		else if (ch == '\n')
    		{
    			a++;
    			continue;
    		}
    		
    	}
    
    	if (fclose(fpsrc) != 0)
    		fprintf(stderr, "Error closing file.\n");
    
    	return 0;
    }
    This doesn't include the rest of the stuff, but like I said, moving the data onto the screen or into a new file has been the easy part.

    I've tried other while loops, using fscanf() and others using fgets(). No dice.

    I'm not looking for actual code, just some advice as to why I'm failing so miserably in simply transferring data from a stream to an int array.

    Thanks!

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    I feel like it must be important for some reason for me to be able to copy text characters into an int array from an open file stream, otherwise the book wouldn't ask me to do it.
    Explain what do you mean by copy text characters into an int array.
    Did you mean 'Store ints from a file to an array' ?
    fscanf() would do that. Lookup the doc.

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    You also need to intiailize your a and b array coordinates... when it enters your switch statement the first time, the values of a and b are undefined.

  4. #4
    Codus Conjectus spongefreddie's Avatar
    Join Date
    Sep 2010
    Location
    USA
    Posts
    86
    Quote Originally Posted by Bayint Naung View Post
    Explain what do you mean by copy text characters into an int array.
    Did you mean 'Store ints from a file to an array' ?
    fscanf() would do that. Lookup the doc.
    Well, the confusing thing about the exercise is that instead of just copying the contents of the text file from one file pointer to another, and changing the character values on the fly, I'm first supposed to read the 20x30 array of digits (separated by single spaces) from the already existing text file. Then, while it's open, I'm supposed to copy the contents of the text file (characters) into an array of int. Then after that, I'm supposed to transfer that int array into a character array, while trading out the different digits for graphical characters, like '#'.

    Anyway, the part I still can't figure out is how to successfully store the characters from the original file in an array of ints. It doesn't make sense to me, but the book is requesting it, unfortunately, so I'm thinking it's something I need to know how to do.

    -spongefreddie

  5. #5
    Codus Conjectus spongefreddie's Avatar
    Join Date
    Sep 2010
    Location
    USA
    Posts
    86

    reply to CommonTater

    Quote Originally Posted by CommonTater View Post
    You also need to intiailize your a and b array coordinates... when it enters your switch statement the first time, the values of a and b are undefined.
    Oops, lol. I did actually initialize a and b, but when I was editing my testing stuff out of the file to display it in the forum, I accidentally took out the line:

    a = b = 0;

    which appeared right before my failed while loop.

  6. #6
    Codus Conjectus spongefreddie's Avatar
    Join Date
    Sep 2010
    Location
    USA
    Posts
    86

    Solved!!!

    Thanks for everyone's input, especially Bayint Naung's!!!

    I took the advice regarding fscanf(), and came up with this code, that WORKED!!!!! :

    Code:
    while (fscanf(fpsrc, "%d", &num) == 1)
       {
    		numbers[a][b] = num;
    		b++;
    		if (num == ' ')
    			;
    		if (num == '\n')
    			a++;
          
       }
    To test it, some simple nested for loops:

    Code:
    for (a = 0; a < LINES; a++)
    	{
    		for (b = 0; b < CHARS; b++)
    		{
    			printf("%d", numbers[a][b]);
    		}
    		printf("\n");
    	}
    I LOVE THIS FORUM!!! You guys have no idea how much I intend to repay in kind eventually, when I actually know what I'm doing...

    Thanks again!

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Well,

    Welcome to the forum, Spongefreddie!

    Glad you like it.

  8. #8
    Codus Conjectus spongefreddie's Avatar
    Join Date
    Sep 2010
    Location
    USA
    Posts
    86

    more streamlined code for anyone still interested

    If anyone is still interested in this little exercise...

    In the same way that using fscanf() allowed me to approach the problem from a different direction, thus cutting down the necessary code significantly, I realized that my approach to changing the characters had bloated code as well.

    Here's a simpler way to transfer the "altered" integers in the (int) 'numbers' array to the char 'array', using nested 'for' loops instead of the 'while' statement (with all that extra b++; continue; crap) I was using in the initial example in this post:

    Code:
    for (a = 0; a < LINES; a++)      // These nested 'for' loops "alter" the digits in the int array
    {                                // called 'numbers[][]' as they are transferred to the char
       for (b = 0; b < CHARS; b++)   // array called 'array[][]'
       {
          num = numbers[a][b];
    
          if (num == 0)
             array[a][b] = ' ';
    
          if (num == 1)
             array[a][b] = '-';
    
          if (num == 2)
             array[a][b] = '*';
    
          if (num == 3)
             array[a][b] = '=';
    
          if (num == 4)
             array[a][b] = 'x';
    
          if (num == 5)
             array[a][b] = 'Q';
    
          if (num == 6)
             array[a][b] = '$';
    
          if (num == 7)
             array[a][b] = '&';
    
          if (num == 8)
             array[a][b] = '%';
    
          if (num == 9)
             array[a][b] = '#';
       }
    }
    I realize I should be using a 'switch' statement instead of a bunch of 'if' statements, but I figured I wouldn't really save much typing anyway.

    sf

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I realize I should be using a 'switch' statement instead of a bunch of 'if' statements, but I figured I wouldn't really save much typing anyway.
    In this case you could use an array to simplify, e.g.,
    Code:
    const char characters[] = " -*=xQ$&%#";
    const size_t characters_count = sizeof(characters) - 1; /* sizeof(char) == 1, ignore null character */
    
    /* Assign to array based on the corresponding digits in numbers. */
    for (a = 0; a < LINES; a++)
    {
        for (b = 0; b < CHARS; b++)
        {
            if (numbers[a][b] >= 0 && numbers[a][b] < characters_count)
            {
                array[a][b] = characters[numbers[a][b]];
            }
        }
    }
    Last edited by laserlight; 10-28-2010 at 01:06 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Codus Conjectus spongefreddie's Avatar
    Join Date
    Sep 2010
    Location
    USA
    Posts
    86

    WOW!

    Quote Originally Posted by laserlight View Post
    In this case you could use an array to simplify, e.g.,
    Code:
    const char characters[] = " -*=xQ$&%#";
    const size_t characters_count = sizeof(characters) - 1; /* sizeof(char) == 1, ignore null character */
    
    /* Assign to array based on the corresponding digits in numbers. */
    for (a = 0; a < LINES; a++)
    {
        for (b = 0; b < CHARS; b++)
        {
            if (numbers[a][b] >= 0 && numbers[a][b] < characters_count)
            {
                array[a][b] = characters[numbers[a][b]];
            }
        }
    }
    Very, very cool! For just a brief flash last night I wondered if I could use some sort of loop configuration (since there is a 1:1, sequential character-to-digit ratio), but I hadn't the *slightest* idea how to approach it, so I went ahead and did the 'if' statements.

    Thank you for posting this!

    After examining your code, I feel like I just learned a valuable lesson in optimization. It never occurred to me to use one array's int value for another array's index.

    Thanks again!
    sf

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can anyone help?
    By javalurnin in forum C Programming
    Replies: 11
    Last Post: 12-02-2009, 06:02 AM
  2. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  3. Working with random like dice
    By SebastionV3 in forum C++ Programming
    Replies: 10
    Last Post: 05-26-2006, 09:16 PM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. Replies: 4
    Last Post: 11-23-2003, 07:15 AM