Thread: converting from a const char to a char.

  1. #1
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73

    Exclamation converting from a const char to a char.

    Hi,

    I need help with converting a const char to a char. That is part of a larger function that is a part of a spell checker, this function is supposed to compare "word" with every word in the dictionary "result" If a match is found, then the word is spelt correctly, and the program returns true... otherwise, it returns false.

    Here is my code:

    Code:
    bool check(const char* word)
    {
        int r = 0;  // might have to be 1 instead of 0
        char temp[51];
        strncpy(temp,word,51);
        char new_word = malloc(strlen(word)+1);
        
        if (new_word) {
            strcpy(new_word,word);
        printf("%s\n", new_word);
        
        while(r != count);
        {
            if(strcmp (new_word,result[r]) != 0)
            {
                r++;
            }
            else if(strcmp (new_word,result[r]) = 0)
            {
                return true;
            }
        }
        
        return false;
    }
    There are also 2 global variables... here they are:

    Code:
    int count = 0;
    
    
    char *result = NULL;
    There are 10 errors generated when I try to compile the code. Here is the first one (I believe that fixing this should fix all/most of the other errors):

    Code:
    dictionary.c:30:10: error: incompatible pointer to integer conversion initializing 'char' with an expression of type
          'void *'; [-Werror]
        char new_word = malloc(strlen(word)+1);
             ^          ~~~~~~~~~~~~~~~~~~~~~~


    Any help/hints would be GREATLY appreciated!

    Thanks,
    Josh
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    You can't assign a pointer to a char. You may want to study some documentation for malloc(). Plus you probably don't even need malloc() in this case. And if you do use malloc() make sure you free the memory before you exit the function. Fixing the malloc() problem will not solve most of the other problems with this function. I really suggest you rethink your solution.



    Jim

  3. #3
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    It needs to be done tonight! Do you have any recommendations for a different way to do it???
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    this function is supposed to compare "word" with every word in the dictionary
    I don't see anywhere where you are reading anything from a file. So you probably should start by opening your file and reading values from the file so you can compare your string to something.

    Jim

  5. #5
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    sorry, that isn't all of my code, here it is, although I don't know how it will help:

    Code:
    include <stdio.h>
    #include "dictionary.h"
    #include <string.h>
    #include <stdlib.h>
    
    
    #define MAXWORDS 26
    #define DLENGTH 46
    
    
    int count = 0;
    
    
    char *result = NULL;
    
    
    /**
     * Returns true if word is in dictionary else false.
     */
    bool check(const char* word)
    {
        int r = 0;  // might have to be 1 instead of 0
        char temp[51];
        strncpy(temp,word,51);
        char new_word = malloc(strlen(word)+1);
        
        if (new_word) {
            strcpy(new_word,word);
        printf("%s\n", new_word);
        
        while(r != count);
        {
            if(strcmp (new_word,result[r]) != 0)
            {
                r++;
            }
            else if(strcmp (new_word,result[r]) = 0)
            {
                return true;
            }
        }
        
        return false;
    }
    
    
    /**
     * Loads dictionary into memory.  Returns true if successful else false.
     */
    bool load(const char* dictionary)
    {
    
    
    int ch = 0;
    
    
    
    
    FILE *f = fopen("test.txt", "r");
    
    
    while ((ch = fgetc(f)) != EOF)
    	{
    		if (ch == '\n')
    			count++;
    	}
    
    
    
    
    size_t total_size = 0;
    size_t num_bytes = 0;
    
    
    char buf[0x1000];
    
    
    
    
    while ((num_bytes = fread(buf, 1, sizeof(buf), f)) > 0) {
        char *p = realloc(result, total_size + num_bytes);
        if (p == NULL) {
            fclose(f);
            free(result);
            abort(); // whatever, out of memory
        }
    
    
        result = p;
        memcpy(result + total_size, buf, num_bytes);
        total_size += num_bytes;
    }
    
    
        //printf("%s\n",result);
    
    
    //fclose(f);
    
    
    
    
    return true;
      
    }
    
    
    
    
    
    
    /**
     * Returns number of words in dictionary if loaded else 0 if not yet loaded.
     */
    unsigned int size(void)
    {
    if (count != 0)
    {
        return count;
    }
    else
    {
       return 0;
    }
    }
    
    
    /**
     * Unloads dictionary from memory.  Returns true if successful else false.
     */
    bool unload(void)
    {
    return true;
    }
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  6. #6
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Also, there is another program that goes with this, they are compiled together with a makefile, here that program is:

    Code:
    #include <ctype.h>
    #include <stdio.h>
    #include <sys/resource.h>
    #include <sys/time.h>
    
    
    #include "dictionary.h"
    
    
    
    
    // default dictionary
    #define DICTIONARY "/home/cs50/pset6/dictionaries/large"
    
    
    // prototype
    double calculate(const struct rusage *b, const struct rusage *a);
    
    
    
    
    int
    main(int argc, char *argv[])
    {
        // check for correct number of args
        if (argc != 2 && argc != 3)
        {
            printf("Usage: speller [dictionary] text\n");
            return 1;
        }
    
    
        // structs for timing data
        struct rusage before, after;
    
    
        // benchmarks
        double ti_load = 0.0, ti_check = 0.0, ti_size = 0.0, ti_unload = 0.0;
    
    
        // determine dictionary to use
        char *dictionary = (argc == 3) ? argv[1] : DICTIONARY;
    
    
        // load dictionary
        getrusage(RUSAGE_SELF, &before);
        bool loaded = load(dictionary);
        getrusage(RUSAGE_SELF, &after);
    
    
        // abort if dictionary not loaded
        if (!loaded)
        {
            printf("Could not load %s.\n", dictionary);
            return 2;
        }
    
    
        // calculate time to load dictionary
        ti_load = calculate(&before, &after);
    
    
        // try to open text
        char *text = (argc == 3) ? argv[2] : argv[1];
        FILE *fp = fopen(text, "r");
        if (fp == NULL)
        {
            printf("Could not open %s.\n", text);
            unload();
            return 3;
        }
    
    
        // prepare to report misspellings
        printf("\nMISSPELLED WORDS\n\n");
    
    
        // prepare to spell-check
        int index = 0, misspellings = 0, words = 0;
        char word[LENGTH+1];
    
    
        // spell-check each word in text
        for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
        {
            // allow only alphabetical characters and apostrophes
            if (isalpha(c) || (c == '\'' && index > 0))
            {
                // append character to word
                word[index] = c;
                index++;
    
    
                // ignore alphabetical strings too long to be words
                if (index > LENGTH)
                {
                    // consume remainder of alphabetical string
                    while ((c = fgetc(fp)) != EOF && isalpha(c));
    
    
                    // prepare for new word
                    index = 0;
                }
            }
    
    
            // ignore words with numbers (like MS Word can)
            else if (isdigit(c))
            {
                // consume remainder of alphanumeric string
                while ((c = fgetc(fp)) != EOF && isalnum(c));
    
    
                // prepare for new word
                index = 0;
            }
    
    
            // we must have found a whole word
            else if (index > 0)
            {
                // terminate current word
                word[index] = '\0';
    
    
                // update counter
                words++;
    
    
                // check word's spelling
                getrusage(RUSAGE_SELF, &before);
                bool misspelled = !check(word);
                getrusage(RUSAGE_SELF, &after);
    
    
                // update benchmark
                ti_check += calculate(&before, &after);
    
    
                // print word if misspelled
                if (misspelled)
                {
                    printf("%s\n", word);
                    misspellings++;
                }
    
    
                // prepare for next word
                index = 0;
            }
        }
    
    
        // check whether there was an error
        if (ferror(fp))
        {
            fclose(fp);
            printf("Error reading %s.\n", text);
            unload();
            return 4;
        }
    
    
        // close text
        fclose(fp);
    
    
        // determine dictionary's size
        getrusage(RUSAGE_SELF, &before);
        unsigned int n = size();
        getrusage(RUSAGE_SELF, &after);
    
    
        // calculate time to determine dictionary's size
        ti_size = calculate(&before, &after);
    
    
        // unload dictionary
        getrusage(RUSAGE_SELF, &before);
        bool unloaded = unload();
        getrusage(RUSAGE_SELF, &after);
    
    
        // abort if dictionary not unloaded
        if (!unloaded)
        {
            printf("Could not unload %s.\n", dictionary);
            return 5;
        }
    
    
        // calculate time to unload dictionary
        ti_unload = calculate(&before, &after);
    
    
        // report benchmarks
        printf("\nWORDS MISSPELLED:     %d\n", misspellings);
        printf("WORDS IN DICTIONARY:  %d\n", n);
        printf("WORDS IN TEXT:        %d\n", words);
        printf("TIME IN load:         %.2f\n", ti_load);
        printf("TIME IN check:        %.2f\n", ti_check);
        printf("TIME IN size:         %.2f\n", ti_size);
        printf("TIME IN unload:       %.2f\n", ti_unload);
        printf("TIME IN TOTAL:        %.2f\n\n", 
         ti_load + ti_check + ti_size + ti_unload);
    
    
        // that's all folks
        return 0;
    }
    
    
    
    
    /*
     * Returns number of seconds between b and a.
     */
    
    
    double
    calculate(const struct rusage *b, const struct rusage *a)
    {
        if (b == NULL || a == NULL)
            return 0;
        else
            return ((((a->ru_utime.tv_sec * 1000000 + a->ru_utime.tv_usec) -
                     (b->ru_utime.tv_sec * 1000000 + b->ru_utime.tv_usec)) +
                    ((a->ru_stime.tv_sec * 1000000 + a->ru_stime.tv_usec) -
                     (b->ru_stime.tv_sec * 1000000 + b->ru_stime.tv_usec)))
                    / 1000000.0);
    }
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Likely this
    Code:
    char new_word = malloc(strlen(word)+1);
    Should be changed to below
    Code:
    char* new_word = malloc(strlen(word)+1);
    Edit: Not knowing the above likely means you are not safe using malloc in a program.
    Edit2: The function check has more problems than I can help you with to-nite.
    Hint1: "==" and "=" are not the same in C.
    Hint2: A extra semicolon in the wrong place is very hard to find.

    Tim S.
    Last edited by stahta01; 04-13-2013 at 07:38 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  8. #8
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    ok, that fixed half my errors, but I still have these:

    Code:
    dictionary.c:38:29: error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *';
          take the address with & [-Werror]
            if(strcmp (new_word,result[r]) != 0)
                                ^~~~~~~~~
                                &
    /usr/include/string.h:143:54: note: passing argument to parameter '__s2' here
    extern int strcmp (__const char *__s1, __const char *__s2)
                                                         ^
    dictionary.c:42:34: error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *';
          take the address with & [-Werror]
            else if(strcmp (new_word,result[r]) = 0)
                                     ^~~~~~~~~
                                     &
    /usr/include/string.h:143:54: note: passing argument to parameter '__s2' here
    extern int strcmp (__const char *__s1, __const char *__s2)
                                                         ^
    dictionary.c:42:45: error: expression is not assignable
            else if(strcmp (new_word,result[r]) = 0)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    dictionary.c:54:34: error: expected ';' at end of declaration
    bool load(const char* dictionary)
                                     ^
                                     ;
    dictionary.c:120:2: error: expected '}'
    }
     ^
    dictionary.c:26:1: note: to match this '{'
    {
    ^
    5 errors generated.
    make: *** [dictionary.o] Error 1
    I think they are mostly all caused by the first error, any idea how to fix the error???

    Thanks,
    Josh
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  9. #9
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Help PLEASE!! the deadline is fast approaching, and I can't figure this out!
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    DO NOT PM ME.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > dictionary.c:38:29: error: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *';
    This is telling you that result[r] is NOT a char pointer.

    result is char*
    so result[r] is a char

    The bigger problem can be tracked back to your load() function, where you load the entire file into memory as just one very large text string.
    Where do you break this up into distinct words you can compare with?

    > Help PLEASE!! the deadline is fast approaching, and I can't figure this out!
    How To Ask Questions The Smart Way
    Next time, show up with at least a day to spare, not a couple of hours hoping that yelling at us will make us fix all the issues in your code.

    There's more things wrong with your code than a couple of compilation errors, more than can be fixed in a couple of hours before a deadline.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73

    Red face I thought all hope was lost..

    Hi everyone,

    I would like to start by apologising, I should not have expected you to drop everything you were doing to help me.

    I have also learnt a valuable lesson in scheduling... I left to much till the last minute, and am now paying for that in sleep loss.

    With that out of the way, there is actually still hope of me completing this course! I had said that last night was my deadline, but the actual deadline is monday at midnight! The reason I had said that it needed to be done earlier, was because I also have a final project to do, and I though that would need all of the last 2 days. However, I kicked ash this morning, and the final project is just about complete! So, that leaves the rest of today, and all day tomorrow for me to complete the spell checker! If you could take a look at my current problem (below) and give me some help, that would be GREAT!

    The problem I am having now is that it gets stuck on the first word it is spell checking... Here is the code for the whole program, the function that the problem seems to be coming from, however, is the very first one, check, so unless you feel like it, I don't think you need to read all the code!


    Code:
    #include <stdio.h>
    #include "dictionary.h"
    #include <string.h>
    #include <stdlib.h>
    
    
    #define MAXWORDS 26
    #define DLENGTH 46
    
    
    int count = 0;
    
    
    char **result = NULL;
    
    
    /**
     * Returns true if word is in dictionary else false.
     */
    bool check(const char* word)
    {
        int r = 1;  // might have to be 1 instead of 0
        char temp[51];
        strncpy(temp,word,51);
        char *new_word = malloc(strlen(word)+1);
        
        if (new_word) 
        {
        strcpy(new_word,word);
        printf("%s\n", new_word);
        }
        
        while(r < count);
        {
            if(strcmp(new_word, result[r]) != 0)
            {
                r++;
            }
            else if(strcmp(new_word, result[r]) == 0)
            {
                return true;
            }
        }
        
        return false;
    }
    
    
    
    
    /**
     * Loads dictionary into memory.  Returns true if successful else false.
     */
    bool load(const char* dictionary)
    {
    
    
    int ch = 0;
    
    
    
    
    FILE *f = fopen("test.txt", "r");
    
    
    while ((ch = fgetc(f)) != EOF)
        {
            if (ch == '\n')
                count++;
        }
    
    
    
    
    size_t total_size = 0;
    size_t num_bytes = 0;
    
    
    char buf[0x1000];
    
    
    
    
    while ((num_bytes = fread(buf, 1, sizeof(buf), f)) > 0) {
        char *p = realloc(result, total_size + num_bytes);
        if (p == NULL) {
            fclose(f);
            free(result);
            abort(); // whatever, out of memory
        }
    
    
        result = &p;
        memcpy(result + total_size, buf, num_bytes);
        total_size += num_bytes;
    }
    
    
        //printf("%s\n",result);
    
    
    //fclose(f);
    
    
    
    
    return true;
      
    }
    
    
    
    
    
    
    /**
     * Returns number of words in dictionary if loaded else 0 if not yet loaded.
     */
    unsigned int size(void)
    {
    if (count != 0)
    {
        return count;
    }
    else
    {
       return 0;
    }
    }
    
    
    /**
     * Unloads dictionary from memory.  Returns true if successful else false.
     */
    bool unload(void)
    {
    return true;
    }


    When I run the program, it seems to get stuck on this line of code:

    Code:
    if(strcmp(new_word, result[r]) != 0)
    Any Idea what is wrong???

    Thanks,
    Josh
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You're still not reading words properly, though at least you've moved in the right direction as far as declaring your result pointer.

    You start with while ((ch = fgetc(f)) != EOF) to count the number of lines, which I take it will also be the number of words.

    Having counted the lines, don't forget to
    rewind(f);
    so you can read the file again.

    You should then do
    result = malloc( count * sizeof(*result) );
    This is your array of pointers to char, where each result[i] will point to a single word.


    > while ((num_bytes = fread(buf, 1, sizeof(buf), f)) > 0)
    You should replace this with
    while ( fgets( buf, sizeof(buff), f) != NULL )
    This will read one line at a time, including a newline. Read the FAQ to find out how to dispose of the newline.

    You then do something like this to allocate space for a single word, and copy it.
    result[i] = malloc( strlen(buf) + 1 );
    strcpy( result[i], buf );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    ok, here is my code now... I was not able to remove the newline, could you link to the manual that you were referring to, as the only fgets manual I could find, shown nothing about removing the newline character.


    Code:
    #include <stdio.h>
    #include "dictionary.h"
    #include <string.h>
    #include <stdlib.h>
    
    
    #define MAXWORDS 26
    #define DLENGTH 46
    
    
    int count = 0;
    
    
    char **result = NULL;
    
    
    /**
     * Returns true if word is in dictionary else false.
     */
    bool check(const char* word)
    {
        int r = 1;  // might have to be 1 instead of 0
        char temp[51];
        strncpy(temp,word,51);
        char *new_word = malloc(strlen(word)+1);
        
        if (new_word) 
        {
        strcpy(new_word,word);
        printf("%s\n", new_word);
        }
        
        while(r < count);
        {
            if(strcmp(new_word, result[r]) != 0)
            {
                r++;
            }
            else if(strcmp(new_word, result[r]) == 0)
            {
                return true;
            }
        }
        
        return false;
    }
    
    
    
    
    /**
     * Loads dictionary into memory.  Returns true if successful else false.
     */
    bool load(const char* dictionary)
    {
    
    
    int ch = 0;
    
    
    
    
    FILE *f = fopen("test.txt", "r");
    
    
    while ((ch = fgetc(f)) != EOF)
        {
            if (ch == '\n')
                count++;
        }
    
    
    rewind(f);
    
    
    result = malloc( count * sizeof(*result) );
    
    
    //size_t total_size = 0;
    //size_t num_bytes = 0;
    
    
    char buf[0x1000];
    
    
    int i = 0;
    
    
    while ( fgets( buf, sizeof(buf), f) != NULL ) {
    
    
        result[i] = malloc( strlen(buf) + 1 );
        strcpy( result[i], buf );
        
        i++;
    
    
        //result = &p;
        //memcpy(result + total_size, buf, num_bytes);
        //total_size += num_bytes;
    }
    
    
        //printf("%s\n",result);
    
    
    //fclose(f);
    
    
    
    
    return true;
      
    }
    
    
    
    
    
    
    /**
     * Returns number of words in dictionary if loaded else 0 if not yet loaded.
     */
    unsigned int size(void)
    {
    if (count != 0)
    {
        return count;
    }
    else
    {
       return 0;
    }
    }
    
    
    /**
     * Unloads dictionary from memory.  Returns true if successful else false.
     */
    bool unload(void)
    {
    return true;
    }

    Right now it is still doing what It was doing before, that is, getting stuck on this line:

    Code:
     if(strcmp(new_word, result[r]) != 0)
    If you could take a look at what I did, and let me know what you think is wrong, that would be GREAT.

    Thanks,
    Josh
    There is always one more bug...

    Remember, don't name you php arrays "hit"

  15. #15
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by Dude22 View Post
    ok, here is my code now... I was not able to remove the newline, could you link to the manual that you were referring to, as the only fgets manual I could find, shown nothing about removing the newline character.
    FAQ > Get a line of text from the user/keyboard (C) - Cprogramming.com

    I prefer to use sscanf with fgets.
    fgets && sscanf

    Second sscanf link http://faq.cprogramming.com/cgi-bin/...&id=1043284392

    But, it might be better in this case to just place zero on the newline.

    Tim S.
    Last edited by stahta01; 04-14-2013 at 05:29 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting int to const char* ?
    By Wiretron in forum C++ Programming
    Replies: 7
    Last Post: 11-12-2007, 02:49 PM
  2. Converting an std::string to a const char *
    By Shamino in forum C++ Programming
    Replies: 21
    Last Post: 01-24-2006, 04:03 PM
  3. Converting from type char to const char*
    By Leeman_s in forum C++ Programming
    Replies: 1
    Last Post: 05-21-2003, 09:51 PM
  4. Assigning Const Char*s, Char*s, and Char[]s to wach other
    By Inquirer in forum Linux Programming
    Replies: 1
    Last Post: 04-29-2003, 10:52 PM
  5. Converting const char to char array
    By HomerJ in forum C++ Programming
    Replies: 4
    Last Post: 04-30-2002, 03:21 PM

Tags for this Thread