LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-26-2005, 12:31 PM   #1
Mistro116@yahoo.com
Member
 
Registered: Sep 2005
Posts: 118

Rep: Reputation: 15
Two Dimensional Character Problem


The situation is as follows:

I am writing a function to read in a 15 x 15 grid of characters from an inputfile, which looks like this:

Code:
EHUKXDICNMYTYLF
WOCJSKLTIMHONII
NOTGNIHSAWZIFNP
IRBWNIIWPPIERCE
BMETVELIIOKOWOK
QUOWCLEVELANDLN
VNCCOORTHTSNUNA
AMKHRHFELSIONOM
DULNAANETXUQNSU
AIOATNVEORKBARR
MMPZVEANSUALBET
SYSDSWGNBITCLFI
OHZOMYDENNEKWFD
IAOTNARGRNVTFEF
KRRVFVEEDMBDMJZ
I am, however, declaring my two-dimensional array of characters as a char array[17][17], to give a buffer all the way around the grid of characters. I'm trying to initialize this buffer to be a simple ' ' character, (just a space character), but when I try to output the results, my algorithm "looks as if it has failed". Could someone take a look at my functions and see what I may be doing wrong?

My function to red in the list of letters, and declare spaces around the grid of characters is:

Code:
void ReadLetterList (FILE *inputFile, char puzzle 
		     [LETTERARRAYROWSIZE][LETTERARRAYCOLUMNSIZE])
{
   int puzzleRowIndex;
   int puzzleColumnIndex;
   
   for (puzzleRowIndex = 0; puzzleRowIndex < LETTERARRAYROWSIZE;
	puzzleRowIndex++)
   {
      for (puzzleColumnIndex = 0; puzzleColumnIndex < 
	   LETTERARRAYCOLUMNSIZE; puzzleColumnIndex++)
      {
	 if (puzzleRowIndex < 1 || puzzleRowIndex > 15 ||
	     puzzleColumnIndex < 1 || puzzleColumnIndex > 15)
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] = ' ';
	 }
	 else
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] =
	    fgetc (inputFile);
	 }
      }
   }
}
My high level function that implements its usage is:

Code:
void GenerateLetterList  (char inputFileName [ ])
{
   FILE *inputFile;
   char puzzle [LETTERARRAYROWSIZE][LETTERARRAYCOLUMNSIZE];
   
   inputFile = fopen (inputFileName, READFILE);
   
   if (inputFile == NULL)
   {
      fprintf (stderr, "Error - Cannot open %s for reading!\n", 
	       inputFileName);
      
      exit (-1);
   }
   
   ReadLetterList (inputFile, puzzle);
   
   int i, j;
   for (i = 0; i < LETTERARRAYROWSIZE; i++)
   {
      for (j = 0; j < LETTERARRAYCOLUMNSIZE; j++)
      {
	 printf("%c", puzzle[i][j]);
      }
      
      if (i < 1 || i > 15)
      {
	 printf ("\n\n");
      }
   }
   
   printf ("\n\n");
   printf("%c\n\n", puzzle[0][0]);
   
   /*for (i = 1; i <= 15; i++)
    {
      for (j = 1; j <= 15; j++)
      {
	 printf("%c", puzzle[i][j]);
      }
      }*/
   /*DisplayLetterList (puzzle);*/
}
When I run the program and try to display the grid of letters, I get this:

Code:
 
 EHUKXDICNMYTYLF
WOCJSKLTIMHONI  I
NOTGNIHSAWZIF  NP
IRBWNIIWPPIE  RCE
BMETVELIIOK  OWOK
QUOWCLEVEL  ANDLN
VNCCOORTH  TSNUNA
AMKHRHFE  LSIONOM
DULNAAN  ETXUQNSU
AIOATN  VEORKBARR
MMPZV  EANSUALBET
SYSD  SWGNBITCLFI
OHZ  OMYDENNEKWFD
IA  OTNARGRNVTFEF
K
I want it to look like my grid of characters has a buffer all the way around, full of spaces, when it is output to the console.

Am I doing something wrong with code implementation, or perhaps output. If any of the functions are commented out in the high-level generate words function, it is because they are not being used at this time, and it is in its primordial test phase.

Thanks for your help,

Mistro116
 
Old 11-26-2005, 01:52 PM   #2
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
The problem lies in getting input. Specifically, the algorithm uses fgetc() and stores the return value in the array no matter what. Now look back at the input file. It may look like there are not other characters in the file, but what about newlines and EOF?
 
Old 11-26-2005, 03:28 PM   #3
Mistro116@yahoo.com
Member
 
Registered: Sep 2005
Posts: 118

Original Poster
Rep: Reputation: 15
I tried to make the following changes to address the problem you spoke of:

Code:
void ReadLetterList (FILE *inputFile, char puzzle 
		     [LETTERARRAYROWSIZE][LETTERARRAYCOLUMNSIZE])
{
   int puzzleRowIndex;
   int puzzleColumnIndex;
   char characterCopy;
   
   for (puzzleRowIndex = 0; puzzleRowIndex < LETTERARRAYROWSIZE;
	puzzleRowIndex++)
   {
      for (puzzleColumnIndex = 0; puzzleColumnIndex < 
	   LETTERARRAYCOLUMNSIZE; puzzleColumnIndex++)
      {
	 if (puzzleRowIndex < 1 || puzzleRowIndex > 15 ||
	     puzzleColumnIndex < 1 || puzzleColumnIndex > 15)
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] = ' ';
	 }
	 else if ((characterCopy = fgetc (inputFile)) != '\n' &&
		  (characterCopy != EOF))
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] =
	    characterCopy;
	 }
      }
   }
}
But I still got invalid format:

Code:
                  
 EHUKXDICNMYTYLF
 WOCJSKLTIMHONI
 I�NOTGNIHSAWZIF
 NIRBWNIIWPPIE
 RCEBMETVELIIOK
 OWOK@QUOWCLEVEL
 ANDLNVNCCOORTH
 TSNUNAMKHRHFE
 LSIONOMDULNAAN
 ETXUQNSUAIOATN
 VEORKBARRMMPZV
 EANSUALBET@SYSD
 SWGNBITCLFIOHZ
 OMYDENNEKWFDIA
 OTNARGRNVTFEF�K
What am I doing wrong?

Mistro116
 
Old 11-26-2005, 04:47 PM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Take a look at the code you added. What happens when the character pulled in is a newline? What gets stored in that array location? That's the reason why your output has weird characters in it (like '?' and '@'). If a newline character is read in, the program correctly ignores it. However, the program incorrectly advances to the next array location without putting anything in the array; the location that would have stored the newline is left with random, uninitialized garbage.

The program will need to wait until characterCopy contains a legitimate value, copy that value into the character array, and then advance to the next array location.
 
Old 11-26-2005, 07:03 PM   #5
Mistro116@yahoo.com
Member
 
Registered: Sep 2005
Posts: 118

Original Poster
Rep: Reputation: 15
Is there a way to do this while keeping the two for-loops, I tried thinking about it using a while loop in my nested for loops, but this doesnt seem to work:

Code:
void ReadLetterList (FILE *inputFile, char puzzle 
		     [LETTERARRAYROWSIZE][LETTERARRAYCOLUMNSIZE])
{
   int puzzleRowIndex;
   int puzzleColumnIndex;
   int characterCopy;
   
   for (puzzleRowIndex = 0; puzzleRowIndex < LETTERARRAYROWSIZE;
	puzzleRowIndex++)
   {
      for (puzzleColumnIndex = 0; puzzleColumnIndex < 
	   LETTERARRAYCOLUMNSIZE; puzzleColumnIndex++)
      {
	 if (puzzleRowIndex < 1 || puzzleRowIndex > 15 ||
	     puzzleColumnIndex < 1 || puzzleColumnIndex > 15)
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] = 'x';
	 }
	 else
	 {
	    if ((characterCopy = fgetc (inputFile)) != '\n' ||
		(characterCopy != EOF))
	    {
	       puzzle [puzzleRowIndex][puzzleColumnIndex] =
	       characterCopy;
	    }
	    else
	    {
	       characterCopy = fgetc (inputFile);
	       
	       puzzle [puzzleRowIndex][puzzleColumnIndex] =
	       characterCopy;
	    } 
	 }
      }
   }
}
This gives me output similar to the first time I tried to run it.

How exactly do I implement this method?

Mistro116
 
Old 11-26-2005, 07:36 PM   #6
Mistro116@yahoo.com
Member
 
Registered: Sep 2005
Posts: 118

Original Poster
Rep: Reputation: 15
I've worked on it a little bit more, and I am getting closer, but I don't understand why some of the characters are not being read and stored properly:

Code:
void ReadLetterList (FILE *inputFile, char puzzle 
		     [LETTERARRAYROWSIZE][LETTERARRAYCOLUMNSIZE])
{
   int puzzleRowIndex;
   int puzzleColumnIndex;
   int characterCopy;
   
   for (puzzleRowIndex = 0; puzzleRowIndex < LETTERARRAYROWSIZE;
	puzzleRowIndex++)
   {
      for (puzzleColumnIndex = 0; puzzleColumnIndex < 
	   LETTERARRAYCOLUMNSIZE; puzzleColumnIndex++)
      {
	 if (puzzleRowIndex < 1 || puzzleRowIndex > 15 ||
	     puzzleColumnIndex < 1 || puzzleColumnIndex > 15)
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] = 'x';
	 }
	 else
	 {
	    while ((characterCopy = fgetc (inputFile)) == '\0' ||
		   (characterCopy == '\n'))
	    {
	       characterCopy = fgetc (inputFile);
	    }
	    
	    puzzle [puzzleRowIndex][puzzleColumnIndex] =
	    characterCopy;
	 }
      }
   }
}
This is the updated version of my code, and the output I get is:

Code:
xxxxxxxxxxxxxxxxx
xEHUKXDICNMYTYLFx
xOCJSKLTIMHONIIOx
xTGNIHSAWZIFNPRBx
xWNIIWPPIERCEMETx
xVELIIOKOWOKUOWCx
xLEVELANDLNNCCOOx
xRTHTSNUNAMKHRHFx
xELSIONOMULNAANEx
xTXUQNSUIOATNVEOx
xRKBARRMPZVEANSUx
xALBETYSDSWGNBITx
xCLFIHZOMYDENNEKx
xWFDAOTNARGRNVTFx
xEFRRVFVEEDMBDMJx
xZ��������������x
xxxxxxxxxxxxxxxxx
We're getting closer, but theres like 10 or so characters that aren't being read, and some are being input to the array at the wrong time why is this:

The original file is this, and needs a buffer of x's surrounding it:

Code:
EHUKXDICNMYTYLF
WOCJSKLTIMHONII
NOTGNIHSAWZIFNP
IRBWNIIWPPIERCE
BMETVELIIOKOWOK
QUOWCLEVELANDLN
VNCCOORTHTSNUNA
AMKHRHFELSIONOM
DULNAANETXUQNSU
AIOATNVEORKBARR
MMPZVEANSUALBET
SYSDSWGNBITCLFI
OHZOMYDENNEKWFD
IAOTNARGRNVTFEF
KRRVFVEEDMBDMJZ
Does anyone know?

Thanks,

Mistro116
 
Old 11-26-2005, 07:55 PM   #7
Mistro116@yahoo.com
Member
 
Registered: Sep 2005
Posts: 118

Original Poster
Rep: Reputation: 15
I figured out the problem, I wanted to do too much to fast basically. Thanks to dark_helmet for his guidance, it was extremely helpful.

I guess my urge to call functions like a billion times inside loops stems from my mathematical analysis of the problem, but after looking at it in incremental steps:

A working code was derived:

Code:
void ReadLetterList (FILE *inputFile, char puzzle 
		     [LETTERARRAYROWSIZE][LETTERARRAYCOLUMNSIZE])
{
   int puzzleRowIndex;
   int puzzleColumnIndex;
   int characterCopy;
   
   for (puzzleRowIndex = 0; puzzleRowIndex < LETTERARRAYROWSIZE;
	puzzleRowIndex++)
   {
      for (puzzleColumnIndex = 0; puzzleColumnIndex < 
	   LETTERARRAYCOLUMNSIZE; puzzleColumnIndex++)
      {
	 if (puzzleRowIndex < 1 || puzzleRowIndex > 15 ||
	     puzzleColumnIndex < 1 || puzzleColumnIndex > 15)
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] = 'x';
	 }
	 else
	 {
	    characterCopy = fgetc (inputFile);
	    
	    while ((characterCopy  == '\0' || 
		    characterCopy == '\n') &&
		   (characterCopy != EOF))
	    {
	       characterCopy = fgetc (inputFile);
	    }
	    
	    puzzle [puzzleRowIndex][puzzleColumnIndex] =
	    characterCopy;
	 }
      }
   }
}
For anyone that was interested.

Thanks to Dark_Helmet.

Mistro116
 
Old 11-26-2005, 08:01 PM   #8
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
You're making your life too complicated

Don't use an expression like this:
Code:
	    while ((characterCopy = fgetc (inputFile)) == '\0' ||
		   (characterCopy == '\n'))
The reason I say that is because it'sconfusing. What happens first? The assignment to characterCopy? The comparison between characterCopy and the newline?

Keep it simple. How about this?
Code:
   for (puzzleRowIndex = 0; puzzleRowIndex < LETTERARRAYROWSIZE;
	puzzleRowIndex++)
   {
      for (puzzleColumnIndex = 0; puzzleColumnIndex < 
	   LETTERARRAYCOLUMNSIZE; puzzleColumnIndex++)
      {
	 if (puzzleRowIndex == 0 ||
             puzzleRowIndex == ( LETTERARRAYROWSIZE - 1 ) ||
	     puzzleColumnIndex == 0 ||
             puzzleColumnIndex == ( LETTERARRAYCOLUMNSIZE - 1 ) )
	 {
	    puzzle [puzzleRowIndex][puzzleColumnIndex] = 'x';
	 }
	 else
	 {
            characterCopy = '\n';
            while( characterCopy == '\n' )
            {
               characterCopy = fgetc( inputFile );
	    }

	    puzzle [puzzleRowIndex][puzzleColumnIndex] = characterCopy;
         }
      }
   }
For the stuff in blue, I changed that simply because it makes more sense to me to use "==" comparisons rather than "<" or ">". Also, you created #defines for LETTERARRAYROWSIZE and LETTERARRAYCOLUMNSIZE... use them By using literal values of 15, your program breaks if you ever change the #define values. This way, you can change them to whatever you want and it'll still be happy. As a side note, I prefer underscores in all-caps #defines; it makes them easier to read.

For the stuff in green, this is a simple way to do it. If you want, you could add tests for EOF. However, the newlines are what throw your program off. It's just a bad idea to assign a value in a conditional and use that same value in the same statement. Fight the urge to make "condensed" code. Spell it out as simply as you can. Trust me, when you go back to look at it later, it will be extremely helpful. Condensed/obscure code is for competitions; not for real work.

---------

I see you beat me to it. Good job sniffing out!
 
Old 11-26-2005, 08:13 PM   #9
Mistro116@yahoo.com
Member
 
Registered: Sep 2005
Posts: 118

Original Poster
Rep: Reputation: 15
I see what you're saying. I changed some things to #defines for better readibility and understanding, but I prefer to keep my code for reading in the characters similar to the one I posted in my last post. I understand how both would work, and how yours is more efficient, but for logic purposes, it seems like the problem is better addressed by my code, if such a thing is possible.

I guess what I'm trying to say is both algorithms address the problem, but mine kind of addresses the problem in context more so than initializing characterCopy as '\n'

It seems:

Code:
else
	 {
	    characterCopy = fgetc (inputFile);
	    
	    while (characterCopy  == '\n' &&
		   characterCopy != EOF)
	    {
	       characterCopy = fgetc (inputFile);
	    }
	    
	    puzzle [puzzleRowIndex][puzzleColumnIndex] =
	    characterCopy;
	 }
Is pretty appropriate in my mind.

Much obliged Dark_Helmet, you're input on this issue has been greatly appreciated.

Mistro116
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Double pointers and two dimensional arrays in C kponenation Programming 23 03-16-2011 11:43 AM
building a three dimensional array in vb6 mrobertson Programming 0 08-18-2005 09:12 AM
Bash 2 dimensional array ldp Linux - General 5 07-29-2005 11:29 AM
memory managment problem; higher dimensional array doesn't delete qanopus Programming 5 06-15-2005 04:18 PM
3 dimensional array help leeach Programming 11 06-15-2005 10:46 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:06 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration