Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Multidimensional arrays in C

  1. Mar 29, 2009 #1

    djeitnstine

    User Avatar
    Gold Member

    Hi guys I just learned M-D arrays and was trying to execute this piece of code:

    Code (Text):
    //initial value of y
        printf("\nTime of initial displacement - y(t): t=");
        fflush(stdin);
        scanf("%lf", &IVP[1][1]);
        printf("\nInitial displacement - y(%.4lf)=",&IVP[1][1]);
        fflush(stdin);
        scanf("%lf", &IVP[1][2]);
       
        //initial value of y_prime
        printf("\nTime of initial velocity - y'(t): t=");
        fflush(stdin);
        scanf("%lf", &IVP[2][1]);
        printf("\nInitial velocity - y'(%.4lf)=", &IVP[2][1]);
        fflush(stdin);
        scanf("%lf", &IVP[2][2])
    And for some reason the output keeps screwing up. I placed '1' for the first scanf and ever since then it kept printing '1'. I can post a screen shot if necessary...

    thanks
     
  2. jcsd
  3. Mar 29, 2009 #2

    sylas

    User Avatar
    Science Advisor

    You've got address operators "&" in your printf statements. Get rid of them.

    If you are reading and writing a single variable, you do it like this.
    Code (Text):

    {
        int x;

        printf("Enter a value for x: ");
        scanf("%d", &x);
        printf("You entered the value %d\n", x);
    }
     
    You include or omit the "&" operator the same way for an array element.
    Code (Text):

    {
        int x[5][5];

        printf("Enter a value for x[2][3]: ");
        scanf("%d", &x[2][3]);
        printf("You entered the value %d\n", x[2][3]);
    }
     
    It's a good idea to have all possible compiler warnings enabled when you compile your program. If you are using the gnu compiler, the compiler argument is "-Wall". There should be something similar for any other compiler you use.

    Cheers -- Sylas
     
  4. Mar 29, 2009 #3

    djeitnstine

    User Avatar
    Gold Member

    Thanks a mil
     
  5. Mar 29, 2009 #4

    djeitnstine

    User Avatar
    Gold Member

    Ok so now I encountered a 3rd problem. I'm truly puzzled this time. I guess its only because I'm really not used to C.

    Please bare with the slightly lengthy printf's

    Code (Text):
     
    [COLOR="Red"][B]#define FUNY  1[/B][/COLOR]
    #define Y_T   0
    [B][COLOR="Orange"]#define FUNYP 1
    #define YP_T  0[/COLOR][/B]

    .
    .
    .
    [COLOR="Red"][B]double[/B] IVP[1][1]={0}[/COLOR]
    .
    .
    .
       //initial value of y
        printf("\nTime of initial displacement - y(t): t=");
        fflush(stdin);
        scanf("%lf", &IVP[0][Y_T]);
        printf("\nInitial displacement - y(%.4lf)=",IVP[0][Y_T]);
        fflush(stdin);
        [COLOR="Red"][B]scanf("%lf", &IVP[0][FUNY]);[/B][/COLOR]
       
        //initial value of y_prime
        printf("\nTime of initial velocity - y'(t): t=");
        fflush(stdin);
        [COLOR="Orange"]scanf("%lf", &IVP[1][YP_T]);[/COLOR]
        printf("\nInitial velocity - y'(%.4lf)=", IVP[1][YP_T]);
        fflush(stdin);
        scanf("%lf", &IVP[1][FUNYP]);
       
        printf("\n\nt=%.4lf, [B][COLOR="Red"]Y=%.4lf[/COLOR][/B], t'=%.4lf, Y'=%.4lf\n\n",[COLOR="Orange"][B]IVP[0][Y_T][/B][/COLOR],[COLOR="Red"][B]IVP[0][FUNY][/B][/COLOR],[B][COLOR="Orange"]IVP[1][YP_T][/COLOR][/B],IVP[1][FUNYP]);
    .
    .
    .
    coeff[0]=(coeff_solv*IVP[0][FUNY]+IVP[1][FUNYP])/(coeff_solv*sine+solution[IMAG]*cosine_yp);  //step 1 solve for C1
        printf("\n\nC1:%.4lf= x:%.4lf* [COLOR="Red"]Y:%.4lf[/COLOR] + Y':%.4lf / x:%.4lf * sin:%.4lf + r:%.4lf * cosy':%.4lf\n\n",coeff[0],coeff_solv,[COLOR="Red"][B]IVP[0][FUNY][/B][/COLOR],IVP[1][FUNYP],coeff_solv,sine+solution[IMAG],cosine_yp);
    So this is what showed up. Please note Y:
    28jh1n8.jpg
     
    Last edited: Mar 29, 2009
  6. Mar 29, 2009 #5

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    The most obvious problem is that you've overflown your array.

    double IVP[1][1]={0};

    This declares a two-dimensional array whose first index set has length 1, consisting of the interval [0,1). I.E. the only legal first index is 0. Similarly, the only legal second index is 0.


    A more subtle problem -- I'm pretty sure %lf is supposed to be for long double arguments, not double arguments. Though, I bet on your computer, those turn out to be the same type.
     
  7. Mar 29, 2009 #6

    djeitnstine

    User Avatar
    Gold Member

    Maybe I'm totally wrong but aren't 2d arrays
    Code (Text):
    2D_Array[row][column]
     
  8. Mar 29, 2009 #7

    djeitnstine

    User Avatar
    Gold Member

    Ahh ok, so I should make it 2D_Array[2][2]
     
  9. Mar 29, 2009 #8

    djeitnstine

    User Avatar
    Gold Member

    Yea this is how our professor asks us to do it.
     
  10. Mar 29, 2009 #9

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Or... maybe the l just does nothing. (Now that I read again, I think %Lf is for long doubles)
     
  11. Mar 29, 2009 #10

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    You should do things correctly. I bet your professor doesn't have any deep reason for asking you to use %lf -- it was simply how he was taught. You should ask him about it. And if he insists you use %lf, then humor him for his class, and but only for his class.
     
  12. Mar 29, 2009 #11

    djeitnstine

    User Avatar
    Gold Member

    Thanks a mil, got it.
     
  13. Mar 29, 2009 #12

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Aha, I checked the Microsoft visual studio documentation (that is what you're using, right?). Whether or not this is what the C standard dictates, Microsoft's C implementation does interpret %lf as specifying a long double. So, your program would fail to work if long double and double were differently sized types.
     
  14. Mar 29, 2009 #13

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Ack, I just noticed I never explicitly said what you're supposed to use for doubles! In case it wasn't clear, %f is the correct specifier.
     
  15. Mar 29, 2009 #14

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    BTW, I was looking up the codes for printf -- I think scanf might have slightly different behavior; I generally try to avoid using if whenever possible, so I'm not familiar with the differences between scanf and printf. (maybe %lf is right for scanf even if it's wrong for printf?)
     
  16. Mar 29, 2009 #15

    djeitnstine

    User Avatar
    Gold Member

    Hmm well I'm using Dev C++, and it sees it all the same. %lf seems to work for both scanf and printf. Just to let you know the program works okay now, thanks again.

    Also I have another question, can I make an array of strings? or would that have to be a structure or something. Perhaps a 2D string array? char 2D_String[][]=" ";
     
  17. Mar 29, 2009 #16

    djeitnstine

    User Avatar
    Gold Member

    Hmm now I'm having trouble with this simple function. I just want it to loop to grab strings and skip the terminator.

    Code (Text):

    //declare variables
       char final_unit[12]=" ";
       int i=0, row=0, length=0;
       char skip='-', units[4][10]={" "};
           
        //welcome user
        printf("Enter units plz (N-m-s) \n");
               
        //ask/get
        fflush(stdin);
        scanf("%s", final_unit);
       
       length=strlen(final_unit);
       
       //grab each unit
       for(i=0; i<=length; i++)
       {
          if(final_unit[i]==skip)
          {
          i++;
          row++;
          }
         
          //grab each word
          units[row][i]=final_unit[i];
          printf("%s\n",units[i]);
       }
       
        //print to screen
        row=0;
        for(row=0;row<=2;row++)
        {
           printf("\n\n%s\n",units[row]);

        }
     
  18. Mar 29, 2009 #17

    djeitnstine

    User Avatar
    Gold Member

    For some reason that only prints garbage, then the first word before the terminator. Note that I need each one to be a string not necessarily a char.
     
  19. Apr 1, 2009 #18

    sylas

    User Avatar
    Science Advisor

    Your problem, I think, is that C doesn't really have strings in tthe same sense as more high level languages. I love C, but it is pretty close to being block structured assembly language. It doesn't actually treat "strings" as a data type like numbers, but rather it deals with buffers and addresses.

    When you declare a string in C, you are really declaring a buffer... an array of characters. If you pass the string (or any other array) to a function, you are actually passing the address of the memory where the characters are stored. You are not passing a thing called a string, but an address where you have stored some characters.

    Here are my comments on your code:

    Code (Text):

    //declare variables
       char final_unit[12]=" ";
    /*
     * SYLAS: The declaration above is an array of 12 chars.
     * The initialization uses a compiler array (a string) of
     * of two characters (a space, and a null) to initialize
     * the first two places in final_unit, and then leftover
     * 10 places are just set to null as well by extending the
     * initializer.
     */
       int i=0, row=0, length=0;
       char skip='-', units[4][10]={" "};
    /*
     * The 2D array here has an unfortunate initializer. You
     * might be better just to omit it.
    char units[4][10];
     * means that units is a 2D array.
     * It also means that units[i] is a valid expression, that
     * denotes an 1D array, each element of which behaves as if
     * declared as
    char xxx[10];
     * That is, units[0] up to units [3] are all arrays of
     * 10 characters each.
     *
     * To initialized units, you are initializing 4 arrays of
     * characters. You could say, for example:
    char units[4][10] = { "zero", "one", "two", "three" };
     * In this case, units[1] would be an array, which has
     * contents 'o', 'n', 'e', and then a lot of nulls.
     * Your initialization only initialized units[0], leaving
     * units[1] to units[3] all to have the default, which is
     * an array of 10 nulls.
     */
           
        //welcome user
        printf("Enter units plz (N-m-s) \n");
               
        //ask/get
        fflush(stdin);
        scanf("%s", final_unit);
    /*
     * This scanf here is fine, but it's a good idea to know
     * what it does. final_unit is an array of 12 characters.
     * You pass to the function the address, as a pointer to
     * the first character position. The function can then
     * read and store characters into this part of the memory.
     * If you enter more than 11 characters, then you'll be in
     * trouble, because it will keep storing past the size you
     * have allocated in the declaration. C is dangerous like
     * that. There are ways to code more safely, but this is
     * ok to explore how it works.
     */  
       length=strlen(final_unit);
       
       //grab each unit
       for(i=0; i<=length; i++)
       {
          if(final_unit[i]==skip)
          {
          i++;
          row++;
          }
         
          //grab each word
          units[row][i]=final_unit[i];
          printf("%s\n",units[i]);
       }
    /*
     * Alas, this loop makes no sense.
     * You should count up to i<length, because there are only
     * length charactes, in places 0 to length-1. There is a
     * null character stored at final_unit[length], but you
     * don't need to look at it.
     * The assignment units[row][i] only sets one character
     * in the row i. The assignment refers to units[i],
     * which is not the same as units[row] wherein you stored
     * the character. And in any case, you need to store more
     * than one character in row, don't you?
     */  
        //print to screen
        row=0;
        for(row=0;row<=2;row++)
        {
           printf("\n\n%s\n",units[row]);

        }
    I might put up a bit of sample code for you in a tick...

    Cheers -- Sylas
     
    Last edited: Apr 1, 2009
  20. Apr 1, 2009 #19

    sylas

    User Avatar
    Science Advisor

    Try this program. It writes out the each line
    of input, but with words reversed. The code
    assumes proper line terminated input with a
    newline just before end of file. It's naive
    about words, just counting anything with spaces
    between them as words. It's careful not to
    overflow any arrays. It handles a maximum of
    12 words per line, and 15 characters per word,
    simply ignoring anything extra without crashing.
    If I use this paragraph as input to the program,
    then I get the following as output:
    Code (Text):

    Words reversal. Stops at end of file. Go...
    line each the out writes It program. this Try
    code The reversed. words with but input, of
    a with input terminated line proper assumes
    naive It's file. of end before just newline
    spaces with anything counting just words, about
    to not careful It's words. as them between
    of maximum a handles It arrays. any overflow
    word, per characters 15 and line, per words 12
    crashing. without extra anything ignoring simply
    program, the to input as paragraph this use I If
    output: as following the get I then
     
    Here's the program.
    Code (Text):

    #include <stdio.h>

    #define NWORDS 12  // Store up to 12 words, no more
    #define MAXLEN 16  // Store up to 16 chars, including null, for each word

    // A program to collect words (separated by spaces) and print each line
    // out with words in reverse order.

    int main()
    {
        char word[NWORDS][MAXLEN]; // Stores the words. Note subscript order
        char c;   // The input character
        int w;    // A counter of the number of words
        int len;  // A counter for the length of a word

        printf("Words reversal. Stops at end of file. Go...\n");

        c = getchar();
        while ( c != EOF ) {
            // Each time around the loop does one line of input.
            // Skip initial spaces
            while ( c == ' ' ) {
                c = getchar();
            }
            // Read until end of line
            // Loop invariant. At end of line, or at the start of a new word
            w = 0;
            while ( c != '\n' && w < NWORDS ) {
                len = 0;
                do {
                    if ( len < MAXLEN-1 ) {
                        // Only store if there is space. Leave room for a null
                        word[w][len] = c;
                        len++;
                    }
                    c = getchar();
                } while ( c != ' ' && c != '\n' );
                word[w][len] = 0; // Add a null to terminate the word
                w++;
                // Skip over any spaces
                while ( c == ' ' ) {
                    c = getchar();
                }
            }
            // We might not have finished reading the line, if there were
            // too many words. Finish it off now.
            while ( c != '\n' ) {
               c = getchar();
            }
            // Now output the words
            // w is the number of stored words; we can use to count back
            // This loop uses word[w] as an array of chars to pass to
            // printf. All words are null terminated, so printf can work.

            while ( w > 0 ) {
                w--;
                printf("%s ", word[w]);
            }
            printf("\n");

            // This loop needs the first char of next line to be read
            c = getchar();
        }

        return 0; // Finished
    }
     
    Observe that I use words[w][len] to refer to a place where I store one single character, and words[w] as an expression for an array of len characters, passed to printf. Note how I leave space to store the final null character in each word. It's needed for printf.

    Cheers -- Sylas
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Multidimensional arrays in C
  1. Arrays c++ (Replies: 14)

  2. C++ Array (Replies: 10)

  3. C# arrays (Replies: 1)

Loading...