Thread: An array of strings problem

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    40

    An array of strings problem

    Ok so basically I'm having a problem creating an array of strings, I've attempted to define it as a pointer to character arrays of size twenty. But i dont know if scanf will read in a string to a character array or just the first character. I have a feeling i'm not going about it the right way, I can get it to read in, but when it moves on to printing out the data i've read in, it fails.

    Code:
    int n,m;
    char (*x)[20];
    
    
    int main()
    {
        printf("Please say how many names you will enter:");
        scanf("%d", &n);
    
        for(m=0; m<n; m++)
        {
            printf("\nName %d: ",(m+1));
            scanf("%s", &x);
        }
        for(m=0; m<n; m++)
        {
            printf("\nName %d: %", (m+1), (x+m));
        }
    
        return 0;
    }
    Any suggestions or direction would be greatly appreciated

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    This is another variation on the common "forgot to allocate memory" theme. x is a pointer, but you've pointed it nowhere (it's NULL, in fact). You can allocate memory for it the same as you would any old pointer:
    Code:
    char (*x)[20];
    x = malloc(10 * sizeof *x);
    Now you have access to x[0], x[1], ... x[9], each of which is an array of 20 char. You can do things like:
    Code:
    scanf("%s", x[0]);
    puts(x[0]);
    The normal caveats to scanf() apply, of course: this code is not safe. But it gets the idea across. Remember that with scanf(), you should not use & when reading strings. Why? It's mildly complex if you're new to C, but the quick answer is that an array is automatically converted to a pointer, so you don't need to use & to do that (and in fact, it's wrong to simply stick an & in front of an array/pointer name when passing it to scanf("%s")).

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That's a pointer to an array of characters. Not an array of pointer characters. Lose the parentheses.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    Ok, so i've lost the ampersand, that was a silly mistake I should of known that because I had just read about it 15 minutes before hand!

    I then tried this code at the start
    Code:
    int n,m;
    char (*x)[20];
    x = malloc(20*sizeof*x));
    But this conflicted with the type of x. So i'm not sure what's wrong?

    To be honest I don't quite understand this, I have been reading about it, but I'm not exactly sure about it.
    Is it basically pointing x to a space in memory of the defined size?

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    You want x to be an array of 20 characters, correct? Do it like this:


    Code:
    char *x;
    x = malloc(20*sizeof(char));
    Saying
    Code:
    sizeof*x
    is meaningless (I think) - sizeof() is a function, you have to give it an argument.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by ineedmunchies View Post
    Ok, so i've lost the ampersand,
    I didn't say get rid of the ampersand. I said get rid of the parenthesis:
    Code:
    int n,m;
    char (*x)[20];
    x = malloc(20*sizeof*x));
    As I've said, that is a pointer to an array of 20 characters. Not an array of twenty pointers to characters:
    Code:
    char *x[20];

    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    I want x to be a pointer, to a series of character arrays. So basically a 2-D array. And thank you yes I was thinking that code looked a little funny.

    Ok, so I've tried again.

    Code:
    int n,m;
    char (*x)[20];
    
    int main()
    {
        printf("Please say how many names you will enter:");
        scanf("%d", &n);
    
        x = malloc(20*n*sizeof(char));
    
        for(m=0; m<n; m++)
        {
            printf("\nName %d: ",(m+1));
            scanf("%s", x+m);
    
        }
        for(m=0; m<n; m++)
        {
            printf("\nName %d: %", (m+1), x+m);
        }
    
        return 0;
    }
    This runs, and appears to scan something in, but only prints out the statements, it does not print any of the data there.

    I tried with scanf() and puts(), but this then printed out random file path names, so i deleted that.

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Look closely:
    Code:
    printf("\nName %d: %", (m+1), x+m);
    What's missing???

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    Quote Originally Posted by rags_to_riches View Post
    Look closely:
    Code:
    printf("\nName %d: %", (m+1), x+m);
    What's missing???
    Thank you! lol silly mistake again!

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Why do you keep putting parenthesis there? Stop. I've told you three times now.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    int main( void )
    {
        char *arrayofptoc[ 20 ];
        size_t x = 0;
    
        for( x = 0; x < 20; x++ )
        {
            arrayofptoc[ x ] = malloc( SOMETHING );
        }
    
        ...do stuff...
    
        for( x = 0; x < 20; x++ )
        {
            free( arrayofptoc[ x ] );
        }
    
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    For 2D arrays, you can do it like this:
    Code:
    char **x;
    x = malloc(20*sizeof(char *));
    for (int i = 0; i < n; i++)
    {
          x[i] = malloc(n * sizeof(char));
    }
    This will give you an array of 20 character arrays, each of length n characters. Don't forget to free the memory at the end.

    This is equivlenet to the above post, but it gives a bit of a better look at exactly what it is you are assigning.

  12. #12
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Code:
    x = malloc(20*n*sizeof(char));
    The way I showed is easier and less error-prone. Why hardcode the 20 when you don't have to? Also, for future reference, sizeof(char) is 1.
    Code:
    x = malloc(n * sizeof *x);

  13. #13
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    Quzah, the first time I misread it, the second time you posted as I was replying.

    I put the parenthesis there, as that is how the example in my book showed me. The code now seems to be working as intended, so thank you for your help Apologies for the misunderstanding

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by ineedmunchies View Post
    I put the parenthesis there, as that is how the example in my book showed me.
    Then you are misunderstand your book, or you have a lousy book.
    Code:
    type *foo[X];
    type (*bar)[X];
    These are not the same thing. You shouldn't attempt to use them as if they were, because it's entirely wrong. The latter is a pointer to an array. The former is an array of pointers. They are not even remotely the same thing.

    Question 6.13

    "seems to be working" doesn't mean "is correct".


    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    Quzah,
    From what I understand of that example, the second part is what I want.

    Here is the entirety of the program so far.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int n,m;
    char (*x)[20];
    
    int main()
    {
        printf("Please say how many names you will enter:");
        scanf("%d", &n);
    
        x = malloc(20*n*sizeof(char));
    
        for(m=0; m<n; m++)
        {
            printf("\nName %d: ",(m+1));
            scanf("%s", x+m);
    
        }
        for(m=0; m<n; m++)
        {
            printf("\nName %d: %s", (n-(m+1)+1), (x+(n-m-1)));
        }
    free(x);
    
        return 0;
    }
    It does what it was intended to do, in reading in a given amount of names, and returning them in the reverse order.
    Although from reading that example you gave, I think I may have mixed up the number for the array and the value n.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie Question: sizeof() problem in function
    By Xeyide in forum C Programming
    Replies: 3
    Last Post: 09-04-2009, 12:05 AM
  2. Array of strings problems...
    By chubigans in forum C Programming
    Replies: 4
    Last Post: 08-27-2009, 03:13 PM
  3. Problem with strings in Linked List
    By hellogamesmaste in forum C Programming
    Replies: 10
    Last Post: 08-23-2009, 10:06 AM
  4. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  5. array of strings problem
    By dayknight in forum C Programming
    Replies: 3
    Last Post: 11-08-2005, 10:41 AM