GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 04-Jun-2009, 13:44
clueless clueless is offline
New Member
 
Join Date: Jun 2009
Posts: 9
clueless is on a distinguished road

Filling 2D array with .txt file values


I'm trying to write a simple program that will take values from a .txt file that are seperated by tabs and put them into a 2D array. I'm using gcc to compile. I first need to find the dimensions (rows and columns) of the data in .txt file. Below is what I came up with - it almost works. Here's the problem I'm encountering: When I call finddimension_y() first I get ydim=11 (which is correct), and xdim=0 (obviously not correct). If I call finddimension_x() first I get xdim=501 (correct), and ydim=10(not correct). It seams to me that the library function getc() starting at the beginning of the file after the first function is called, it just continues getting characters from wherever it left off. If that's the problem any ideas how to fix it? The .txt file is attached and the code is below. Thanks.

CPP / C++ / C Code:
#include <stdio.h>

int finddimension_y (void);
int finddimension_x (void);
void fillarray (void);

FILE *fp;

main ()
{
	fp = fopen("Isml.txt", "r");
	finddimension_y();
	finddimension_x();
}

int finddimension_y (void)
{
	char ch;
	int ydim=0;

	ch = getc(fp);
	while (ch != EOF)
	{
		if (ch == '\n')
		{
			ydim++;
		}
		ch = getc(fp);
	}
	printf("ydim= %d\n",ydim);
	return ydim;
}

int finddimension_x (void)
{
	char ch;
	int xdim=0;
	
	ch = getc(fp);
	while (ch != EOF)
	{
		if (ch == '\t')
		{
			xdim++;
		}
		if (ch == '\n')
		{
			break;
		}
		ch = getc(fp);
	}
	printf("xdim= %d\n",xdim);
	return xdim;
}



~clueless
Attached Files
File Type: txt Isml.txt (91.5 KB, 7 views)
  #2  
Old 04-Jun-2009, 14:16
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,200
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Filling 2D array with .txt file values


Quote:
Originally Posted by clueless
...It seams to me that the library function getc()...just continues getting characters from wherever it left off.
How else could it work? Each call to getc() obtains the next character from the input stream.

See, for example: getc() Reference

Quote:
Originally Posted by clueless
...how to fix it?


Either:

1. Close the file after returning from one function and open it again before calling the other.

or, a little more elegantly:

2. Use rewind() to set the stream pointer back to the beginning of the file.

See, for example: rewind() Reference


You are going to have to do this again before reading file contents into your matrix, right?


Regards,

Dave
  #3  
Old 04-Jun-2009, 14:57
clueless clueless is offline
New Member
 
Join Date: Jun 2009
Posts: 9
clueless is on a distinguished road

Re: Filling 2D array with .txt file values


Great thanks!! It works perfectly...but you already knew that...ha ha.
Anyway, I'm not sure what you mean by your question. I haven't figured out how to populate the array now that I know its dimensions.

~I'm clueless
  #4  
Old 09-Jun-2009, 13:58
clueless clueless is offline
New Member
 
Join Date: Jun 2009
Posts: 9
clueless is on a distinguished road

Re: Filling 2D array with .txt file values


Thanks again for your help. I found that resource site very helpful.
I figured out how to fill in the array and it worked pretty well, so of course I decided to complicate things. I wnated to dynamically allocate the space for the 2D array. I read one of your previous posts on how to do that, and I think that part works, but something else happened along the way. When I execute the code below with the line 'image[R][C-1] = extractpixelvalue();' commented out, the values for R (row) and C (column) are currect, when I uncomment that line the values for R and C are no longer correct, and the matrix that prints in the output window is only partly correct.
Between my last version and this one I changed (among other things) the extractpixelvalue function. I was using a combination of fseek and fgetc, in this version I'm using fscanf. Are fgetc (from findtab()) and fseek (from extractpixelvalue()) conflicting with eachother? Thanks for any and all help.

CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>

int finddimension_y (void);
int finddimension_x (void);
void findtab (void);
unsigned char extractpixelvalue (void);

FILE *infile;
int *ydim_ptr, *xdim_ptr;
int R = 0;
int C = 0;
int CH;

int main ()
{
	int i, j;
	int **image;
	int ydim, xdim;
	
	infile = fopen("Isml.txt", "rb");
	ydim_ptr = &ydim;
	xdim_ptr = &xdim;
	ydim = finddimension_y();		//find the y dimension of infile
	xdim = finddimension_x();		//find the x dimension
	
	image = malloc(ydim_ptr[0] * sizeof(int *));				//dynamically allocating space for 2D array
	for (i=0; i<ydim_ptr[0]; i++)
		image[i] = malloc(xdim_ptr[0] * sizeof(int));
	
	while (R < ydim_ptr[0])
	{
		findtab();
		if (R == ydim_ptr[0] || CH == EOF)
			break;
		printf("%d  %d\n",R,C);
//		image[R][C-1] = extractpixelvalue();	//set elements in image[][] = the value of pixel at that location
	}	

	printf("\n");
	for (i = 0; i < ydim_ptr[0]; i++)	//prints the matrix to the output window
	{
		for (j = 0; j < xdim_ptr[0]; j++)
		{
			printf("%d\t",image[i][j]);
		}
		printf("\n");
	}

	for (i = 0; i < xdim_ptr[0]; i++)	//frees the space that was allocated
		free(image[i]);
	free(image);
	printf("\n\n**************!end!**************\n\n");
}

int finddimension_y (void)
{
	int y = 0;
	CH = getc(infile);
	while (CH != EOF)
	{
		if (CH == '\n')
		{
			y++;
		}
		CH = getc(infile);
	}
	rewind (infile);
	return y;
}

int finddimension_x (void)
{
	int x = 0;
	CH = getc(infile);
	while (CH != EOF)
	{
		if (CH == '\t')
		{
			x++;
		}
		if (CH == '\n')
		{
			break;
		}
		CH = getc(infile);
	}
	rewind (infile);
	return x;
}

void findtab (void)
{
	while (1)
	{
		CH = getc(infile);
		while (CH != '\t' && CH != '\n' && CH != EOF)
		{
			CH = getc(infile);
		}
		if (CH == '\t')
		{
			C++;
			break;
		}
		else if (CH == '\n')
		{
			R++;
			C = 0;
			break;
		}
		else if (CH == EOF)
		{
			break;
		}
	}
}

unsigned char extractpixelvalue (void)
{
	double pval;
	
	if (CH != '\n' && CH != EOF)
	{
		fscanf(infile, "%lf", &pval);
		return pval;
	}
}


~I'm Clueless
  #5  
Old 09-Jun-2009, 14:02
clueless clueless is offline
New Member
 
Join Date: Jun 2009
Posts: 9
clueless is on a distinguished road

Re: Filling 2D array with .txt file values


oh, sorry here's the .txt file.

Isml.txt
  #6  
Old 09-Jun-2009, 16:05
fakepoo fakepoo is offline
Regular Member
 
Join Date: Oct 2007
Posts: 696
fakepoo is a jewel in the roughfakepoo is a jewel in the roughfakepoo is a jewel in the rough

Re: Filling 2D array with .txt file values


I noticed a couple of things that may or may not be a problem for you. What happens when your text file has only one entry? Let's say it has a number with no tab or newline character. When you count the dimensions, you'll get zero for both of them. Secondly, your code becomes difficult to read through when you use pointers like that. You make it look like you have an array when you simply have a single value. To dereference a single int from an int*, use the * operator in front of it. Like:
CPP / C++ / C Code:
int x;
int *y = &x;
int z = *y; // instead of y[0]
But, why are you even using a pointer when you have the value accessible already?

Somebody please correct me if I'm wrong, but I believe that you can simply call fscanf() over and over again without removing characters manually. See this example:
CPP / C++ / C Code:
double d[4];
char s[64] = "8.512 5.667     -123.12             65.1";
for(int i=0;i<4;++i)
{
  sscanf( s, "%lf" , &d[i] ); // sscanf() is the same as fscanf() but done to a string instead of a stream
}
  #7  
Old 11-Jun-2009, 09:49
clueless clueless is offline
New Member
 
Join Date: Jun 2009
Posts: 9
clueless is on a distinguished road

Re: Filling 2D array with .txt file values


Thank you fakepoo.

I'm still struggling on the dynamically allocated array. I've been using this as a reference:
Quote:
Originally Posted by davekw7x
Now, if you want a 2D array of int, and the dimensions are not known at compile time, here's a way to do it.

Suppose we want an array[size_x][size_y] of int, where size_x and size_y are variables.
The "array" name will be a "pointer to a pointer to an int"
1. Allocate memory for size_x pointers to int. The address returned by malloc() will be the "array".
2. For each of the pointers, allocate memory for size_y ints.
Then address the individual elements with array[][] notation.
3. Free the memory allocated for the ints.
4. Free the memory allocated for the pointers.
Here's an example (I have given size_x and size_y specific values for purposes of illustration, but these could be obtained from user input or from other program calculations, or whatever.)

CPP / C++ / C Code:

/* illustration of dynamically allocated 2D array */
#include <stdio.h>
#include <stdlib.h>

int main()
{
  int i; /* general purpose variable used for loop index */
  int j; /* general purpose variable used for loop index */

  int **a;     /* this is the array name */
  int size_x; /* this variable will be used for the first  dimension */
  int size_y; /* this variable will be used for the second dimension */

  /* suppose we want an array of int: a[5][3] */
  size_x = 5;
  size_y = 3;

  /*  allocate storage for an array of pointers */
  a = malloc(size_x * sizeof(int *));

  /* for each pointer, allocate storage for an array of ints */
  for (i = 0; i < size_x; i++) {
    a[i] = malloc(size_y * sizeof(int));
  }

  /* just for kicks, show the addresses (note: not all sequential) */
  /* assign an arbitrary value to each element        */
  for (i = 0; i < size_x; i++) {
    for (j = 0; j < size_y; j++) {
      printf("&a[%d][%d] = %p\n", i, j, &a[i][j]); /* show the addresses */
      a[i][j] = i * size_y + j; /* just some unique number for each element */
    }
    printf ("\n");
  }

  /* now show the contents that were assigned */
  for (i = 0; i < size_x; i++) {
    for (j = 0; j < size_y; j++) {
      printf("a[%d][%d] = %2d\n", i, j, a[i][j]);
    }
    printf ("\n");
  }

  /* now for each pointer, free its array of ints */
  for (i = 0; i < size_y; i++) {
    free(a[i]);
  }
  /* now free the array of pointers */
  free(a);

  return 0;
}

I'm now trying to create a function called alloc that I can call multiple times from multiple .c files to allocate multiple arrays of different names and sizes. I really have no idea where to even start. Below is my function (taken from the example above), but I can't figure out how to pass in a different name for **a.
CPP / C++ / C Code:
void alloc (int size_y, int size_x)
{
	int i;
	int **a;
	
	a = malloc(size_x * sizeof(int *));
	for (i=0; i<size_y; i++)
		a[i] = malloc(size_x * sizeof(int));
}

On top of that, I need to be able to fill these arrays from different functions, so I think I need to use pointers to these arrays after they have been allocated. But the name of the array is already a "pointer to a pointer of an int" Can I point to a pointer to a pointer of an int? Is any of this even possible?

If it sounds like I have no idea what I'm doing, it's because I don't.
Any help would be greatly appreciated.

~I'm Clueless
  #8  
Old 11-Jun-2009, 10:14
fakepoo fakepoo is offline
Regular Member
 
Join Date: Oct 2007
Posts: 696
fakepoo is a jewel in the roughfakepoo is a jewel in the roughfakepoo is a jewel in the rough

Re: Filling 2D array with .txt file values


Try returning the pointer to the array. Then, if you want to do something like fill the array, pass the pointer into the function that fills it.

CPP / C++ / C Code:
//void alloc (int size_y, int size_x)
int **alloc(int size_y, int size_x)
{
	int i;
	int **a;
	
	//a = malloc(size_x * sizeof(int *)); // ERROR: <-- this should be size_y
	a = malloc(size_y * sizeof(int *));
	for (i=0; i<size_y; i++)
		a[i] = malloc(size_x * sizeof(int));
	return a;
}

void FillArray(int **a, int size_y, int size_x)
{
  int i,j;

  for(i=0;i<size_y;++i)
  {
    for(j=0;j<size_x;++j)
    {
      a[i][j] = i + j;
    {
  }  
}
  #9  
Old 16-Jun-2009, 10:22
clueless clueless is offline
New Member
 
Join Date: Jun 2009
Posts: 9
clueless is on a distinguished road

Re: Filling 2D array with .txt file values


Ok, sorry I can't figure this out. fakepoo, when I tried your exemple, I got an error that said "syntax error before '*' token". I'm not really sure what that code was suposed to do either. sorry.

Here's what I have now and it seems to be working, but I want to pass the name of an array into the function so I can allocate space for multiple arrays. It would also be handy if the arrays were global so I could read/write from different functions in different .c files.

CPP / C++ / C Code:
int alloc (size_y,size_x)
{
   int i, j;
   int **a;    /* this is the array name */
   //I want to pass this in from outside the function.//

   /*  allocate storage for an array of pointers */
   a = malloc(size_y * sizeof(int *));

   /* for each pointer, allocate storage for an array of ints */
   for (i = 0; i < size_y; i++)
   {
      a[i] = malloc(size_x * sizeof(int));
   }

   /* initialize each element to 0 */
   for (i = 0; i < size_y; i++)
   {
      for (j = 0; j < size_x; j++)
      {
         a[i][j] = 0;
      }
   }

   /* prints matrix to output window */
   for (i = 0; i < size_y; i++)
   {
      for (j = 0; j < size_x; j++)
      {
         printf("%d\t",a[i][j]);
      }
      printf("\n");
   }
}


Thanks,

~I'm Clueless
  #10  
Old 16-Jun-2009, 12:41
fakepoo fakepoo is offline
Regular Member
 
Join Date: Oct 2007
Posts: 696
fakepoo is a jewel in the roughfakepoo is a jewel in the roughfakepoo is a jewel in the rough

Re: Filling 2D array with .txt file values


Here is how you would use the code that I posted before:

CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>

int **alloc(int size_y, int size_x)
{
	int i;
	int **a;
	
	a = (int**)malloc(size_y * sizeof(int *));
	for (i=0; i<size_y; i++)
		a[i] = (int*)malloc(size_x * sizeof(int));
	return a;
}

void FillArray(int **a, int size_y, int size_x)
{
  int i,j;

  for(i=0;i<size_y;++i)
  {
    for(j=0;j<size_x;++j)
    {
      a[i][j] = i + j;
	}
  }  
}
  
void PrintArray(int **a, int size_y, int size_x)
{
  int i,j;

  for(i=0;i<size_y;++i)
  {
    for(j=0;j<size_x;++j)
    {
      printf("%d\t", a[i][j]);
	}
	printf("\n");
  }  
}

void FreeArray(int **a, int size_y)
{
  int i;

  for(i=0;i<size_y;++i)
  {
	  free(a[i]);
  }

  free(a);
}


int main() 
{
	// Allocate memory for the first array
	int **array1 = alloc(5,5);

	// Fill the array with values
	FillArray(array1, 5, 5);

	// Print the array
	printf("array1:\n");
	PrintArray(array1, 5, 5);

	// Allocate memory for the second array
	int **array2 = alloc(10,10);

	// Fill the array with values
	FillArray(array2, 10, 10);

	// Print the array
	printf("\narray2:\n");
	PrintArray(array2, 10, 10);
	
	// Free both arrays
	FreeArray(array1, 5);
	FreeArray(array2, 10);
	
	getchar();
	return 0;
}

Does it make sense now?
 
 

Recent GIDBlogReview: Gel laptop cooling pad by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Power Calibration Error In Nero Fix (hopefully) matt3678 Computer Hardware Forum 60 20-Aug-2009 06:04
Airport Log program using 3D linked List : problem reading from file batrsau C Programming Language 11 29-Feb-2008 08:44
Need help deleting the last element in the array headphone69 C++ Forum 2 15-Mar-2006 20:31
After execution - Error cannot locate /Skin File? WSCH C++ Forum 1 05-Mar-2005 21:03
CD Buring Failed skanth2000 Computer Hardware Forum 1 15-Nov-2003 04:52

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 22:19.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.