Thread: Could anyone help me on my Comp Sci homework? pointer functions and strings

  1. #1
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59

    Could anyone help me on my Comp Sci homework? pointer functions and strings

    I am having difficulty understanding the concept behind the question I am given for my homework. Im not looking to have someone do this for me, but rather help me understand this better so I can write my own code correctly. The homework is on base conversion of numbers.

    The question is about the first function I need to create:

    A function which reads the n answers from the input file into an array of strings, maintaining the ascending order in which they appeared in the file. Your function should return a pointer to the array of answers

    The input file looks like this:
    3
    B
    20
    1101
    13 10 2
    12 8 5
    1011 2 16


    To be honest, I am having a hard time understanding what the question is even asking. I think I should start out with something like:

    Code:
    char** buildAnsArray(*ifp){    char answer[10];    fscanf("%d", &answer[n]);
        return answer;}
    I know Im not right but I am trying to make n places in my array and return the pointer to the array. Where should I go from here?

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The question is poorly worded. Try breaking it into parts

    "read n values from the input file into an array of strings" can be broken down to steps of "open input file" and then "repeatedly read from the file and store the result in a string" and "place each of those strings into an array of strings".

    "maintaining the ascending order in which they appeared in the file" is a bit ambiguous. At the simplest, it can mean "place the strings read from the file into the array so they're in the same order" - which is fine if the file has the strings sorted in ascending order. If the files in the string are not sorted, the simple solution is to sort the array after reading it.


    The tricky bit is "return a pointer to the array of answers" since, strictly speaking, it is not possible to return an array from any function in C. It probably means that the function needs to use malloc() to allocate enough memory to hold the strings before reading them. Store the result of malloc() in a pointer, use that pointer to treat the allocated memory as if it is an array, and return that pointer.

    There are various ways malloc() might be used, depending on whether you know the maximum size of the possible strings or not. Bear in mind that every call of malloc() must be followed by exactly one corresponding call of free(). If your function is returning a pointer returned by malloc(), the caller will need to call free() with that pointer when done with it.


    Bear in mind that a pointer is not an array, even though it can be used as if it is. From the wording of the question, I suspect your instructor/lecturer/whoever does not understand that fundamental concept.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59
    Quote Originally Posted by grumpy View Post

    The tricky bit is "return a pointer to the array of answers" since, strictly speaking, it is not possible to return an array from any function in C. It probably means that the function needs to use malloc() to allocate enough memory to hold the strings before reading them. Store the result of malloc() in a pointer, use that pointer to treat the allocated memory as if it is an array, and return that pointer.
    I was looking a few things up and since this is dealing with allocating space for an array, then would calloc be best? and you said maybe the memory should be a space big enough for the strings inside a pointer. That makes sense. So do you mean something like:

    Code:
    char* buildAnsArray(*ifp){
        int n=0;
        char answer[MAX_LEN];
    
        fscanf("%d", n);
        answer[] = (char*)calloc(sizeof(n));
        
    
    
        return answer;
    }

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Mike Garber View Post
    you said maybe the memory should be a space big enough for the strings inside a pointer.
    I said no such thing. That statement does not even make sense. Memory is not placed inside pointers, ever. A pointer holds an address in memory - it does not contain that memory.

    Quote Originally Posted by Mike Garber View Post
    So do you mean something like:

    Code:
    char* buildAnsArray(*ifp){
        int n=0;
        char answer[MAX_LEN];
    
        fscanf("%d", n);
        answer[] = (char*)calloc(sizeof(n));
        return answer;
    }
    If you try to actually compile that code, you will find that any compiler will unceremoneously reject it with a bunch of compilation errors. And, if configured to issue diagnostics about suspicious constructs (compilers are not configured that way by default) there will be plenty of warnings too.


    Sorry, but you are relying on pure guesswork, and not even bothering to check if the code makes sense to a compiler. That effectively places anyone who tries to help you in the position of the blind man in "Blind Man's Bluff". Catch you around.
    Last edited by grumpy; 10-18-2014 at 05:26 AM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by Mike Garber View Post
    I was looking a few things up and since this is dealing with allocating space for an array, then would calloc be best?
    Code:
        answer[] = (char*)calloc(sizeof(n));
    Looking things up is fine but you also have to try compiling it. Does your compiler accept this line?

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Well that's not how you call calloc(); there's another argument, for one, and for two, sizeof(n) is the size in bytes of your integer.

    char *answer = calloc(n, sizeof(char));

  7. #7
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59
    Quote Originally Posted by whiteflags View Post
    Well that's not how you call calloc(); there's another argument, for one, and for two, sizeof(n) is the size in bytes of your integer.

    char *answer = calloc(n, sizeof(char));
    Thank you for this, but, I am not understanding what she wants us to do for the first number scanned in the file, (n). so in this call, calloc, that you made, if Im understanding correctly, you made room for n spots to point to in memory that are all the size of a character. In this way I can create memory for a pointer in an array? Am I following correctly?

  8. #8
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59
    After trying a while to get it to compile, I can only compile it when I comment out the calloc call:
    Code:
    char* buildAnsArray(ifp){
        int n=0;
        char answer[MAX_LEN];
        fscanf(ifp,"%d", &n);
        //answer* = calloc(n, sizeof(char));
    
    
        return answer;
    }
    I went here to try to get this call to compile but it doesnt work when I do it that way: calloc(3): allocate/free dynamic memory - Linux man page

  9. #9
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    You need to choose one of the following two ways (they each do different things):

    Code:
    char answer[MAX_LEN];
    This allocates an array of char called answer that has MAX_LEN elements. Since you are declaring it in a function, the memory owned by this array will only be valid for the duration of the function in which you declare it. If you attempt to use this memory after the function already exits, we say that your program produces undefined behaviour. This means that the program is incorrect and may even appear to work, but it is incorrect and it may do strange things.

    Code:
    char *answer = calloc(n, 1);
    This allocates a pointer to char called answer that points to the region given by calloc. Calloc allocates a region of n elements of 1 byte each. The region remains valid until you free it. If you never free it, we say that your program is causing a memory leak.

  10. #10
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59
    Quote Originally Posted by c99tutorial View Post
    You need to choose one of the following two ways (they each do different things):

    Code:
    char answer[MAX_LEN];
    This allocates an array of char called answer that has MAX_LEN elements. Since you are declaring it in a function, the memory owned by this array will only be valid for the duration of the function in which you declare it. If you attempt to use this memory after the function already exits, we say that your program produces undefined behaviour. This means that the program is incorrect and may even appear to work, but it is incorrect and it may do strange things.
    You explain this so clear here. This really helps me understand what is happening upon compilation. Thank you for this, C99

    This allocates a pointer to char called answer that points to the region given by calloc. Calloc allocates a region of n elements of 1 byte each. The region remains valid until you free it. If you never free it, we say that your program is causing a memory leak.
    The only question I have here is if the region is one byte each, how do I use *answer to point to an "array of strings" if it can only point to one char at a time? How many bytes should I calloc for an array of strings?

    hw prob:
    Create function which reads the n answers from the input file into an array of strings, maintaining the ascending order in which they appeared in the file. Your function should return a pointer to the array of answers.
    Last edited by Mike Garber; 10-19-2014 at 07:52 AM.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    The only question I have here is if the region is one byte each, how do I use *answer to point to an "array of strings" if it can only point to one char at a time?
    An array of strings is just an array of char pointers, or an array of arrays.

    To explain, lets think of a different kind of array.
    Code:
    long array[ARRAY_MAX] = {0};
    Reading the declaration, we can see the token ARRAY_MAX in square brackets, meaning it is an array, then to the immediate left we have the array name, and to the left of that we have the element type, long. So you might say you declared array to be an array of long ARRAY_MAX in size.
    Code:
    char *array2[ARRAY_MAX] = {NULL};
    Okay so what about this? If you read it the exact same way as before, the only difference that matters is the element type, char *. You might want to place the * next to the type, if that is clearer for you, but it doesn't matter.

    Incidentally, you can call calloc(n, 1); on every element in array2 and it should give you an empty string n characters in capacity.

    You may as well get that working with a hard limit of how many strings you can put into the array before you make the code more complicated. After you get the code working, you can always replace the declaration with another call to calloc to determine the array size. When you are ready to make that change, read Question 6.16 for some help.

    How many bytes should I calloc for an array of strings?
    Well okay, there is the string itself:

    array2[i] = calloc(n, 1);

    that is one dimension in the data structure. If you later choose to change the other dimension (how many strings there are in the array), you have to allocate a certain number of char pointers. Each char pointer is sizeof(char*) in size. Note: not likely to be 1!

    The call will yield a pointer to a char pointer.

  12. #12
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59
    So is this like a dynamically allocated multidimensional array that I can access elements in the array with a pointer? If I make two pointers, are those two pointers the positions in my multidimensional array? All these pointers are confusing to me. I can read about it a million times but when I try to implement them on an actual program, I get lost.

    Code:
    char **answerArray(FILE *ifp,int n){
    
    
        char **strings = calloc(n, sizeof(char));
        int i;
        for(i=0; i<n; i++)
        {
            strings[i] = calloc(10, sizeof(char)); // Does this restrict my string to 10?
            fscanf(ifp,"%s",strings[i]);
        }
        return strings;
    }
    So I would have to allocate mem for each position in my array? Im trying to do that here with the for loop. My max string length is ten.. When I call calloc to allocate memory for each column position in the array, if I want the max length of my string to be 10 characters, is this how I would write it?

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Honestly the code is mostly correct. The only immediate problem is the first call at the top of the function.
    Code:
    char **strings = calloc(n, sizeof(char *));
    You really need to pay attention to what you are allocating.

    When I first learned pointers, it helped me to think about it like this... if x is a pointer, then *x is the thing to which the pointer points.
    Hence the declaration:

    int *x;

    tells you exactly what *x is, and that is why I write it like that today. It doesn't matter if the declaration is char ***cp; you can apply similar logic.

    If I make two pointers, are those two pointers the positions in my multidimensional array?
    Well, one pointer to pointer simulates an array that holds all of the string pointers (basically where the strings are located). Then you have another pointer important to the data structure, although there may be more than one of them, the actual string. You want to put the string in the pointer to pointer someplace, so it can be part of the data structure. That is part of what you do in the function, when you store the return value of calloc(10, sizeof(char)); in the for loop.

  14. #14
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by Mike Garber View Post
    Code:
            strings[i] = calloc(10, sizeof(char)); // Does this restrict my string to 10?
            fscanf(ifp,"%s",strings[i]);
    My max string length is ten..
    Be careful of your limit. The 10 bytes are only enough to hold a string with a strlen of 9. There must be room to store the null terminator (which most functions like fscanf will automatically write to that buffer). That means if someone puts any string of length 10+ in that file, they will cause your program to buffer overflow. A safer way is to write a limit in the format string

    Code:
    fscanf(ifp, "%9s", strings[i]);
    This limits the string read to 9 characters, which is the most you could hope to store in a 10-byte null-terminated buffer.

  15. #15
    Registered User Mike Garber's Avatar
    Join Date
    Sep 2013
    Posts
    59
    Quote Originally Posted by c99tutorial View Post
    Code:
    fscanf(ifp, "%9s", strings[i]);
    This is cool. I wouldn't have thought I could do something like this. I have a question about these pointers. Is this statement:
    Code:
    char array[] == char *array//?
    true? (since array[] is a char pointer to the first element in the array)

    And similarly, is this:
    Code:
    char array[][];
    the same thing as
    Code:
    char **array;
    How are they different? Im having a hard time picturing everything and how calloc comes int play.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Homework help C with functions
    By packy283 in forum C Programming
    Replies: 5
    Last Post: 10-05-2014, 07:10 PM
  2. C++ homework; using strings and math
    By UWP student in forum C++ Programming
    Replies: 24
    Last Post: 09-28-2010, 04:27 PM
  3. Help! Homework using Strings
    By wco5002 in forum C++ Programming
    Replies: 16
    Last Post: 09-27-2007, 03:53 AM
  4. Homework Help Using Functions
    By Trekkie in forum C++ Programming
    Replies: 10
    Last Post: 11-21-2005, 02:42 AM
  5. Posting on comp.lang.c++ and comp.lang.c++.moderated
    By SilentStrike in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 05-24-2002, 08:27 PM

Tags for this Thread