Thread: Came from Java to C and i'm having a hard time, please help

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    8

    Came from Java to C and i'm having a hard time, please help

    Hello everybody!

    I previously programmed with Java and now I need to learn C. I'm preety confused with C language and so i would really appreciate your help.

    I need to write a program, which read words from input until it reads the word "end". I need to save words into array and size of array is not fixed, so i need to enlarge this array everytime. And particular word cannot be bigger than 80 characters.

    After this, from all the words in array, I need to find 3 words which are first in alphabetical order and i need to print them out.

    So would you guys at least give me some clues at how to start and which functions to use. Because I'm really not yet familiar with pointers and i'm confused because i'm used to Java. And i watch a couple of tutorials and i still do not know how to start.

    So for array enlargement I know i need to use malloc() and realloc() functions.
    But i do not know how to declare a array. If i'am right it can not be declared as array of Strings so i need to do all the things with characters?

    Thanks, i would really appreciate any help.

  2. #2
    Registered User
    Join Date
    Mar 2012
    Posts
    8
    Code:
    #include <stdio.h>
     
    
     
    int main() {
    char *array = malloc(2 * sizeof(char)); 
     
           char ch= getchar();
           int count = 0; 
     
           while (ch != EOF) {       
                  
            array[count]=c;
                   count++;
                   array = (char *)realloc(array,(count +1)*sizeof(char));
    array[count]=0;
                   ch = getchar();
           }
    so what i did so far is this piece of code in which i save characters in char array. Here i use EOF to stop the inputting. Which condition i need to use, so that when the word "end" is entered input is stoped. while(cg != "end") does not work in my case.
    Last edited by amazineous; 03-08-2012 at 04:49 AM.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You need two dimensions. The outer dimension holds pointers to the char *s that contain the individual words.

    Code:
    char **words = malloc(word_count * sizeof(*words));
    You read each word into a fixed buffer.

    Code:
    char buffer[256];
    You allocate memory for the word.

    Code:
    char *word = malloc(strlen(word) + 1);
    You copy the content of the buffer into the memory for word.

    When you need to reallocate, you operate on the outer dimension, using a temporary variable so if there's a failure you do not lose the memory previously associated with words, allowing you to clean up after.

    Code:
    char **temp = realloc(words, (word_count + 1) * sizeof(*temp));
    if (!temp)
    {
        /* Cleanup existing memory here due to memory failure */
    }
    else
    {
        words = temp;
    }
    Don't forget the memory cleanup after.

    Code:
    /* Free individual word memory */
    for(int i = 0; i < word_count; ++i)
    {
        char *word = words[i];
        free(word);
    }
    
    /* Free container memory */
    free(words);
    You should not need to cast the return value of malloc or calloc in C, nor should you. If you need to to shut the compiler up, it means that you're either compiling as C++ code or you've forgotten the stdlib.h header (which you seem to be).

    For string functions such as comparison and copying, C Strings - Cprogramming.com

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Firstly, malloc() and realloc() manage memory, not arrays. There is a difference. However, if you treat a pointer by returned by malloc() as if it was an array, then the compiler treats it that way as well. Array indices, like Java start at zero. So
    Code:
        char *array = malloc(2);    /*  sizeof(char) is defined by the C standard to be 1  */
        array[0] = 'A';
        array[1] = 'B';
        array[2] = 'C';    /*  invalid, but will not usually yield a compilation error.   Result is undefined behaviour, which often manifests as a runtime error */
    If you want to compare strings, you do not use the comparison operators directly. You either compare one character at a time (in a loop) or use functions like strcmp() (declared in standard header <string.h>). This is because, by convention in C, a string is represented as an array of char, with a terminating char of value zero. So the string "end" is represented as four characters with values 'e', 'n', 'd', and '\0'. So, if array is an array of 4 char, and we want to stop if it contains the string "end". One way is
    Code:
        while (!(array[0] == 'e' && array[1] == 'n' && array[2] == 'd' && array[3] == '\0')) ....
    This is functionally equivalent to
    Code:
         while (strcmp(array, "end") != 0) ....
    strcmp() is shorthand for "string comparison". It effectively implements a loop, comparing one character at a time.

    Also, when you malloc() or realloc(), YOU have to clean up the memory allocated. There is no garbage collection in C.

    Another thing is that getchar() returns an int, and EOF is a value of type int that cannot be represented in a char. That means the type of ch needs to be int, not char .... otherwise a loop of the form while (ch != EOF) will never end.

    At this stage, any basic textbook on C will get you started. However, I recommend VERY strongly that you try to put Java out of your mind while learning C. C does things very differently than Java, even if sometimes the code looks similar. You will waste a lot of time and effort, unnecessarily, if you keep thinking in terms of how you do things in Java first, and then map to C.
    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
    Mar 2012
    Posts
    8
    Thanks rags_to_riches and grumpy for your exhaustive answers and really useful advices. I really appreciate it and you two guys really gave me some confidence. But i still got hard time of putting it all together, these pointers and memory allocation is really bothering me, but in some time I believe I will figure it out.
    Could you just suggest me, is putchar() function the right function to use, or would it be better for me to use something else.
    Because in my current program I used
    Code:
    while(strcmp(array, "end")!=0)
    as grumpy suggested before and it gets out of the while loop only if "end " is the first word I type, otherwise it is not working.

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    8
    Hey, finally i figured it out, thanks for all your help
    My code for writing words until the word "end" now looks like this

    Code:
    int counter= 0,day;
    char **wordCollection;
    char* word;
    wordCollection  = (char**)malloc(1 * sizeof(char));
     
           while (1) {
            day = counter+1;
            word= malloc(80);
            printf("Type  %d.  word: ", day);
            scanf("%s",word);
            int comparision= strcmp(word, "end");
                    if (comparision== 0){
                        break;
                        }else{
                            wordCollection = (char **)realloc(wordCollection,(counter +1)*sizeof(word));
                            wordCollection[counter] = word;
                            }
                                counter++;

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Nope. Still wrong. You're still casting the return of realloc, and you're not using the temporary variable as I described.

    More importantly, compare what you wrote:

    Code:
    wordCollection  = (char**)malloc(1 * sizeof(char));
    with what I wrote:

    Code:
    char **words = malloc(word_count * sizeof(*words));
    Note how I did the sizeof(); that's the safe and best practice way to use sizeof in a malloc. It's telling the compiler get the sizeof the thing pointed to by words. In this case, that's a char *, which is the size of a pointer (size of which depends on your environment). sizeof(char) == 1, what you're using, is not enough room. You're corrupting memory and therefore engaging in undefined behaviour.

    There's also no need to use malloc for the temporary buffer into which you're reading the word. Just use

    Code:
    char word[80];

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Having a hard time with linked lists.
    By aw1742 in forum C Programming
    Replies: 5
    Last Post: 10-08-2011, 03:41 PM
  2. Replies: 12
    Last Post: 02-27-2010, 10:53 PM
  3. I'm having a hard time making a .exe from a .cpp
    By manugarciac in forum C++ Programming
    Replies: 10
    Last Post: 05-13-2009, 04:40 PM
  4. I am having a hard time understanding this...
    By EvilPickles in forum C++ Programming
    Replies: 2
    Last Post: 07-10-2006, 05:26 AM
  5. I'm having a really hard time understanding classes.
    By imortal in forum C++ Programming
    Replies: 4
    Last Post: 05-25-2003, 01:02 PM