Help with C Homework: Array from 1D to 2D for 9 Cell Average

  • Thread starter Thread starter Clint_Johnson
  • Start date Start date
  • Tags Tags
    Array
Click For Summary

Discussion Overview

The discussion revolves around a homework problem involving the conversion of a one-dimensional array into a two-dimensional array in C, specifically for calculating a 9-cell average. Participants are addressing issues related to array definitions, memory allocation, and file reading operations.

Discussion Character

  • Homework-related
  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant seeks assistance with converting a 1D array into a 2D array for averaging operations, expressing confusion about the necessary code structure.
  • Another participant clarifies that a 2D array must be created and values copied from the 1D array, highlighting a compiler error due to an incomplete 'if' statement.
  • Concerns are raised about the definition of the variable 'dataArray', which is incorrectly defined as a 1D array, leading to further confusion in the code.
  • Participants discuss the need for comments in the code to clarify the purpose of various variables, including 'imax', 'jmax', 'dimensions', 'r', and 'c'.
  • One participant explains that the size of a 2D array must be known at compile time, suggesting that dynamic memory allocation may be necessary for arrays of arbitrary size.
  • There is a discussion about the implications of using uninitialized variables, particularly 'i', which leads to undefined behavior in calculations for 'r' and 'c'.
  • Concerns are raised about the data types being used, questioning whether the data in the binary file is of type int or float, and whether the array sizes are appropriate for the data being processed.

Areas of Agreement / Disagreement

Participants generally agree on the need for a proper definition of the 2D array and the importance of understanding the binary file's structure. However, there is no consensus on the best approach to resolve the coding issues, with differing opinions on whether to start from scratch or to fix the existing code.

Contextual Notes

Limitations include the lack of clarity regarding the binary file's content, the need for proper initialization of variables, and the requirement for dynamic memory allocation for arrays whose sizes are determined at runtime.

Clint_Johnson
Messages
8
Reaction score
0

Homework Statement



Need to write a 1 dimensional array in 2D so I can do operations on a 9 cell average. Here's what I've got so far

Code:
#include <stdio.h>
#include <stdlib.h>

int main()
{

  int dataArray[2];
  int imax, jmax;

  FILE *fp;
  char buffer[4];
  int dimensions[2];
  int i, r, c;

  fp = fopen("input.bin", "rb");

  if(fp == NULL)

    {
    printf("Error: File cannot be opened.\n");
    return 1;
    }

  else

    {
    fread(buffer, sizeof(buffer), 1, fp);
    fread(dimensions, sizeof(dimensions), 1, fp);
    fread(buffer, sizeof(buffer), 1, fp);
    printf("dimensions ( row , col ) ( %d , %d)\n", dimensions[0],dimensions[1]);
    int elements = dimensions[0] * dimensions[1];
    float myArray[elements];
    fread(buffer, sizeof(buffer), 1, fp);
    fread(myArray, sizeof(myArray), 1, fp);
    fread(buffer, sizeof(buffer), 1, fp);
    imax = dimensions[0];
    jmax = dimensions[1];
    printf(" %d, %d\n", dimensions[0],dimensions[1] );
    r = i / dimensions[1];
    c = i % dimensions[1];
    dataArray[r][c] = myArray[i++];
    if
    fclose(fp);
    return 0;
    }

}

I know I need to do something simple with i, i++ to make the array into 2D because this doesn't compile.

Please help, I'm very ignorant when it comes to C

Thanks
 
Physics news on Phys.org
You don't "make" the array into 2D - you create a 2D array and copy the values into it from your 1D array. I can't tell enough about what you're trying to do to help you out here. Information about what's in you binary file would be helpful.

You have a line with just if in it. That alone would cause a compiler error.
 
Mark44 said:
You don't "make" the array into 2D - you create a 2D array and copy the values into it from your 1D array. I can't tell enough about what you're trying to do to help you out here. Information about what's in you binary file would be helpful.

You have a line with just if in it. That alone would cause a compiler error.

Whoops I accidentally forgot to edit the "if' out.

Well the first line of the binary file is two integers representing the number of rows and columns, the rest of the lines are data values, one per line.

It compiles fine up until I try to create the 2D array, which is were I hit my road block. I don't think I've defined i correctly because I receive the compiler error: "41: error: subscripted value is neither array nor pointer"

Line 41 is the

Code:
dataArray[r][c] = myArray[i++]

Any clues?

Thanks for the reply btw
 
You can't do this:
Code:
dataArray[r][c] = myArray[i++]

because you already have this definition earlier in your code:
Code:
int dataArray[2];

Before going any further, what are the purposes of these variables?
Code:
int dataArray[2];
  int imax, jmax;

  FILE *fp;
  char buffer[4];
  int dimensions[2];
  int i, r, c;
You have zero comments in your code, so I can't tell what you plan to store in each variable. I know what fp is for, so I don't need an explanation of that one.

You probably have way more variables than you need, so the extra ones do nothing but cause confusion.
 
Here's it with comments, took out a imax, jmax, they are for use later.

Code:
File Edit Options Buffers Tools C Help                                                                              
#include <stdio.h>
#include <stdlib.h>

int main()
{

  int dataArray[2]; /*trying to compile without this always gives errors so I put this in*/
  int imax, jmax;   /*for use later in the code*/

  FILE *fp; 
  char buffer[4];  /*Must first read the header of the file, this will hold 4 byte header*/
  int dimensions[2]; 
  int i, r, c;

  fp = fopen("heat.data.bin", "rb"); /*Open file*/

  if(fp == NULL)

    {
    printf("Error: File cannot be opened.\n");  /*Prints error message if file isn't found*/
    return 1;
    }

  else

    {
    fread(buffer, sizeof(buffer), 1, fp);  /*read the first header*/

    fread(dimensions, sizeof(dimensions), 1, fp); /*read the actual data*/
    
    fread(buffer, sizeof(buffer), 1, fp); /*read the footer*/
    
    printf("dimensions ( row , col ) ( %d , %d)\n", dimensions[0],dimensions[1]); /*read dimensions into dimensions array*/

    int elements = dimensions[0] * dimensions[1]; /*total number of elements*/

    float myArray[elements]; /*for memory allocation*/

    fread(buffer, sizeof(buffer), 1, fp); /*second header*/

    fread(myArray, sizeof(myArray), 1, fp);/*read array from file and put it in "myArray"*/

    fread(buffer, sizeof(buffer), 1, fp);/*secong footer*/

    r = i / dimensions[1];       /*My attempt at creating a 2D array and copying values*/
    c = i % dimensions[1];
    dataArray[r][c] = myArray[i++];
    fclose(fp);
    return 0;
    }
}
 
I didn't need to see any code. I just wanted to find out what is the purpose of
  • dataArray (the first one)
  • imax
  • jmax
  • dimensions
  • r
  • c
Please explain, in words, what each of these is to be used for.
 
dataArray was supposed to be the 2D array I was to create

imax is to be used later (this is a smaller part of a larger assignment)

same with jmax

r was to stand for row

c for column

I got r and c idea from

http://www.daniweb.com/forums/thread172619.html#

dimensions, I assume, was to be the variable for all the data in the file besides the header and footer, although my prof did the dimensions part and since it wasn't declared, I thought it was an intrinsic function in C or something.
 
What you're trying to do is to determine at run time how big you 2D array should be. The problem with that is that an array's size has to be known at compile time, which is always before run time.

If you have some a priori information about that maximum amount of data, then you can create a 2D array at compile time that will be big enough.

There is a way to create arrays of arbitrary size at run time, but you have to allocate memory for them from the heap and have a good working knowledge of pointers, which I suspect you don't have.

There are so many things wrong with your program, it would probably be better to start from scratch. That would entail coming up with an algorithm that you understand, and that you would implement in C.

Comments about your code
  • int dataArray[2]; -- creates a 1D array that can hold two ints.
  • int dimensions[2]; -- creates a 1D array that can hold two ints.
  • fread(dimensions, sizeof(dimensions), 1, fp); -- this reads two ints, probably not what you intended.
  • float myArray[elements]; -- Absolutely can't do this. The value of elements is not known at compile time, so the compiler has no way of knowing how much memory to allocate for the array. Also, this is an array of float, and dataArray is an array of int. Is the data in the binary file int or float?
  • fread(buffer, sizeof(buffer), 1, fp); -- The comment says second header. How many headers are there?
  • r = i / dimensions[1]; -- i has never been given a value, so r will be assigned a garbage value. Even if i had been initialized, why would you divide i by dimensions[1]?
  • c = i % dimensions[1]; -- As before, i has never been given a value, so c will be assigned a garbage value. Even if i had been initialized, why would you i modulo dimensions[1]? Whatever happened to dimensions[0]?
  • dataArray[r][c] = myArray[i++]; -- dataArray is a 1D array, so this generates a compiler error. Even if it had worked, what you would be doing is reading the value at a random place in myArray (since i is a garbage value) and attempting to store it at a random location in dataArray (since r and c are garbage values).

As I already said, I would advise you to scrap you current attempt and start from scratch. You need a good understanding of how the data is layed out in the binary file you program will read. From you code, I have a sense that you don't understand what's in the binary file, which means it will be impossible for you to write a program to process it. Your code mentions a header block, which I assume contains the number of rows and the number of columns. For example, if the header contained 3 and 4, I would expect 12 data values to follow. There would be no need for a footer, and certainly no need for a second header and second footer. You also need to know the type of the data in the binary file, and you seem to be confused about that, declaring an array of int in one place and an array of float in another, both supposedly for the same data.

After you have a good understanding of how the data is laid out in the input file, then you can start in on an algorithm - not code - a description in English of what you're going to do. Once you have a good understanding of what you want the computer to do, then you're ready to start writing code.
 
Mark44 said:
What you're trying to do is to determine at run time how big you 2D array should be. The problem with that is that an array's size has to be known at compile time, which is always before run time.

If you have some a priori information about that maximum amount of data, then you can create a 2D array at compile time that will be big enough.

There is a way to create arrays of arbitrary size at run time, but you have to allocate memory for them from the heap and have a good working knowledge of pointers, which I suspect you don't have.

There are so many things wrong with your program, it would probably be better to start from scratch. That would entail coming up with an algorithm that you understand, and that you would implement in C.

Comments about your code
  • int dataArray[2]; -- creates a 1D array that can hold two ints.
  • int dimensions[2]; -- creates a 1D array that can hold two ints.
  • fread(dimensions, sizeof(dimensions), 1, fp); -- this reads two ints, probably not what you intended.
  • float myArray[elements]; -- Absolutely can't do this. The value of elements is not known at compile time, so the compiler has no way of knowing how much memory to allocate for the array. Also, this is an array of float, and dataArray is an array of int. Is the data in the binary file int or float?
  • fread(buffer, sizeof(buffer), 1, fp); -- The comment says second header. How many headers are there?
  • r = i / dimensions[1]; -- i has never been given a value, so r will be assigned a garbage value. Even if i had been initialized, why would you divide i by dimensions[1]?
  • c = i % dimensions[1]; -- As before, i has never been given a value, so c will be assigned a garbage value. Even if i had been initialized, why would you i modulo dimensions[1]? Whatever happened to dimensions[0]?
  • dataArray[r][c] = myArray[i++]; -- dataArray is a 1D array, so this generates a compiler error. Even if it had worked, what you would be doing is reading the value at a random place in myArray (since i is a garbage value) and attempting to store it at a random location in dataArray (since r and c are garbage values).

As I already said, I would advise you to scrap you current attempt and start from scratch. You need a good understanding of how the data is layed out in the binary file you program will read. From you code, I have a sense that you don't understand what's in the binary file, which means it will be impossible for you to write a program to process it. Your code mentions a header block, which I assume contains the number of rows and the number of columns. For example, if the header contained 3 and 4, I would expect 12 data values to follow. There would be no need for a footer, and certainly no need for a second header and second footer. You also need to know the type of the data in the binary file, and you seem to be confused about that, declaring an array of int in one place and an array of float in another, both supposedly for the same data.

After you have a good understanding of how the data is laid out in the input file, then you can start in on an algorithm - not code - a description in English of what you're going to do. Once you have a good understanding of what you want the computer to do, then you're ready to start writing code.

Part of the purpose of the assignment was to allocate array memory arbitrarily so that you could potentially input any array into the final program. But yeah I will go ahead and restart. Everyone says C is the easiest programming language but honestly I find Fortran to be more understandable and easier to manage. Who knows. Thanks for you help.
 
  • #10
Clint_Johnson said:
Everyone says C is the easiest programming language but honestly I find Fortran to be more understandable and easier to manage.
:bugeye:

If you want easy, you use a good scripting language, like python.

AFAIK, Fortran was originally designed for manipulating arrays, so it shouldn't be surprising that it would be simpler for a program that just manipulates arrays, whether or not C is a better language overall.
 
  • #11
Hurkyl said:
:bugeye:

If you want easy, you use a good scripting language, like python.

AFAIK, Fortran was originally designed for manipulating arrays, so it shouldn't be surprising that it would be simpler for a program that just manipulates arrays, whether or not C is a better language overall.

Sorry, should have specified. Everyone, at least to my knowledge, says C is the easiest for scientific programming due to its small nature and the fact that you can do almost anything with it. But you are right about the Fortran bit and the python for that matter. I started toying around with python about a year ago and found it lovely. Cheers.
 
  • #12
Clint_Johnson said:
Part of the purpose of the assignment was to allocate array memory arbitrarily so that you could potentially input any array into the final program. But yeah I will go ahead and restart. Everyone says C is the easiest programming language but honestly I find Fortran to be more understandable and easier to manage. Who knows. Thanks for you help.
As I mentioned in my previous post, there is a way to allocate a block of memory at run time using one of the memory allocation functions (such as malloc) available in the C run-time library. Using this technique you could read the size data in your input file, calculate the number of bytes of memory to allocate, and then allocate the memory. The memory allocated in this way is accessed through the pointer returned by malloc, so accessing this memory requires understanding of how to use pointers.

"Everyone says C is the easiest programming language..." C is easier to use than C++ with its object oriented features that C doesn't have, but I wouldn't say that C is an easy language to use. Both languages have the concept of pointers, which Fortran doesn't have. This capability is very difficult for newcomers to understand, but makes these languages more useful for a broad range of applications, including computer operating systems, than narrow-focus languages such as Fortran that don't have pointers.
 
  • #13
Mark44 said:
C is easier to use than C++ with its object oriented features that C doesn't have,
Of course, people would say the exact same feature makes C++ easier to use than C. :wink:

I'll argue that writing a good C++ library is much harder than writing a good C library, but the corresponding library is going to make things much easier on the user. std::vector, for example...
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 1 ·
Replies
1
Views
11K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 12 ·
Replies
12
Views
10K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K