-6

I came up with an idea to improve my vocabulary.The idea is to have large number of the most common english words in a file. I would then write a program that displays the words on the screen one at a time.If i recognize the word,I press the DOWN key to move to the next word,otherwise I press 'S' to save this word to a text file called Unknown.txt .

When i get finished,i will have collected all the words that i don't know their meaning.If i stop here,and go through each word manually and seach for it's meaning with my dictionary,it will take alot of time to learn them all this way.

However,if i have a method to save the meaning of the word programatically, i can easily open the file and learn the meaning of the words immediatly.That is what i want to acheive.

The "10kword.txt" file looks like the following:

purchase
customers
active
response
practice
hardware.

Here is the code i have so far:

#include <stdio.h>
#include <Windows.h>

void cls(void *hConsole);

int main(void)
{
    FILE *inp, *out;
    if (fopen_s(&inp, "10kWords.txt", "r")) {
        fprintf(stderr, "Unable to open input file\n");
        return 1;
    }
    else if (fopen_s(&out, "Unknown.txt", "a")) {
        fprintf(stderr, "Error opening file Unknown.txt\n");
        fclose(inp);
        return 1;
    }
    char buf[100];
    void *hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    while (1) {
        //Press the down key to move to the next word
        if (GetAsyncKeyState(VK_DOWN) == -32767) {
            cls(hConsole);
            fscanf_s(inp, "%s", buf, 100);
            printf("%s", buf);
        }
        //Press S to save the word to output file
        else if (GetAsyncKeyState('S') == -32767) {
            fprintf(out, "%s\n", buf);
            //Obtain word meaning from dictionary Programatically HERE and print it to 'out'
        }
        else if (GetAsyncKeyState(VK_ESCAPE)) {
            break;
        }
    }
    fclose(inp);
    fclose(out);
    return 0;
}

void cls(void *hConsole)
{
    COORD coordScreen = { 0, 0 };    // home for the cursor 
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD dwConSize;
    // Get the number of character cells in the current buffer. 
    if (!GetConsoleScreenBufferInfo(hConsole, &csbi))
    {
        return;
    }
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
    // Fill the entire screen with blanks.
    if (!FillConsoleOutputCharacter(hConsole,        // Handle to console screen buffer 
        (TCHAR) ' ',     // Character to write to the buffer
        dwConSize,       // Number of cells to write 
        coordScreen,     // Coordinates of first cell 
        &cCharsWritten))// Receive number of characters written
    {
        return;
    }
    // Get the current text attribute.
    if (!GetConsoleScreenBufferInfo(hConsole, &csbi))
    {
        return;
    }
    // Set the buffer's attributes accordingly.
    if (!FillConsoleOutputAttribute(hConsole,         // Handle to console screen buffer 
        csbi.wAttributes, // Character attributes to use
        dwConSize,        // Number of cells to set attribute 
        coordScreen,      // Coordinates of first cell 
        &cCharsWritten)) // Receive number of characters written
    {
        return;
    }
    // Put the cursor at its home coordinates.
    SetConsoleCursorPosition(hConsole, coordScreen);
}
machine_1
  • 4,266
  • 2
  • 21
  • 42
  • 2
    Unrelated to your problem, but don't use symbol names with leading underscore followed by an upper-case letter (like your variable `_Buf`). Such names are reserved for "the implementation" (i.e. the compiler and the standard library). Also don't use [magic numbers](https://en.wikipedia.org/wiki/Magic_number_%28programming%29) like `-32767`. If you want to check for a specific bit or bits use bitwise operators. – Some programmer dude Mar 17 '16 at 12:35
  • I get this warning at line 22; `main.cpp(22): warning C4473: 'fscanf_s' : not enough arguments passed for format string`. – Jabberwocky Mar 17 '16 at 12:38
  • @MichaelWalz ,Actually i used fscanf,but the compiler refused to compile the code and proposed `fscan_s` so i used it,and it compiled with warnings which i ignored. – machine_1 Mar 17 '16 at 12:40
  • 2
    Don't ignore warnings, they are the compilers way of saying you do something wrong or dangerous. You get the warning because you don't provide enough arguments to the function, and that will lead to *undefined behavior*. You should [read a `fscanf_s` reference](https://msdn.microsoft.com/en-us/library/6ybhk9kc.aspx). – Some programmer dude Mar 17 '16 at 12:41
  • 1
    I can't understand what you are asking. I can see a number of errors in your code. – David Heffernan Mar 21 '16 at 11:30
  • @DavidHeffernan What is it you don't understand? The question is clear enough.As for the code,it compiles fine without warnings. – machine_1 Mar 21 '16 at 11:32
  • 3
    I don't understand what you want from us. The question is not clear. The only question in the text is, "Can someone help me out with this one?" What exactly do you want? And there are errors in the code. The fact that it compiles does not mean that it is correct. Your use of `GetAsyncKeyState` is badly wrong, for instance. – David Heffernan Mar 21 '16 at 11:37
  • @DavidHeffernan then I will edit the question later today. – machine_1 Mar 21 '16 at 11:42
  • Why go through the trouble of writing a program to make a Web API call when you can just download a dictionary with definitions and store it on your hard drive? See http://stackoverflow.com/questions/6441975/where-can-i-download-english-dictionary-database-in-a-text-fomat, for example. – Jim Mischel Mar 22 '16 at 20:38
  • @JimMischel I already have a dictionary installed,but i don't want to search the words my self.I want the meanings to be stored along-side the words that i don't know their meanings when i press 'S'.That way,i open the file called Unknown.txt and start learning immediately. – machine_1 Mar 22 '16 at 20:47
  • I don't see where having the file on disk precludes you from doing what you want. Just have your program look up the meaning in the dictionary on disk rather than calling the Web API. – Jim Mischel Mar 22 '16 at 20:49
  • @JimMischel That's part of my question.How do i have my program look up the meaning in the dictionary on disk? – machine_1 Mar 22 '16 at 20:53
  • That rather depends on the format of the dictionary. You can sequentially search a text file. Or you can store it in a database, or you can load the whole thing into an in-memory data structure and search that, whether it's an array of words with definitions or a hash map or whatever. – Jim Mischel Mar 22 '16 at 21:25
  • The file `"10kword.txt"` seems to be a list of English words. It's not a dictionary, but it can be used for spell check. For example you type in "blu", and the program suggests "blue". If you want an actual dictionary I think @Tmayto has a solution to look up words online. You could do an offline version of it, but it would need a large dictionary database. – Barmak Shemirani Mar 24 '16 at 20:43
  • What's up with all the downvotes? – machine_1 Mar 25 '16 at 11:17

2 Answers2

1

It seems as though what you are looking for is a dictionary API that you can send a request to a server and get a response. A quick google search shows there are quite a lot. In addition to this you will also need a couple extra libraries for C to make the HTTP requests, such as libcurl, and a way to parse JSON or XML From this other stack overflow question you have an example of how to use it, and from there you can use it to send requests to Merriam's API.

Here's another good API.

This one's definitely an open ended question but hopefully I've pointed you in the right direction.

Here's some sample code from the curl website showing how to use Curl to do a get http request:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <curl/curl.h>

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  mem->memory = realloc(mem->memory, mem->size + realsize + 1);
  if(mem->memory == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}

int main(void)
{
  CURL *curl_handle;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */ 
  chunk.size = 0;    /* no data at this point */ 

  curl_global_init(CURL_GLOBAL_ALL);

  /* init the curl session */ 
  curl_handle = curl_easy_init();

  /* specify URL to get */ 
  curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/overflow?key=<YOUR KEY GOES HERE>");

  /* send all data to this function  */ 
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

  /* we pass our 'chunk' struct to the callback function */ 
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);

  /* some servers don't like requests that are made without a user-agent
     field, so we provide one */ 
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  /* get it! */ 
  res = curl_easy_perform(curl_handle);

  /* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
  }
  else {
    /*
     * Now, our chunk.memory points to a memory block that is chunk.size
     * bytes big and contains the remote file.
     *
     * Do something nice with it!
     */ 

    printf("%lu bytes retrieved\n", (long)chunk.size);
  }

  /* cleanup curl stuff */ 
  curl_easy_cleanup(curl_handle);

  free(chunk.memory);

  /* we're done with libcurl, so clean it up */ 
  curl_global_cleanup();

  return 0;
}

This example would then print the definition of overflow as an XML file to memory.

Good luck!

Community
  • 1
  • 1
Tmayto
  • 135
  • 6
0

There is a bug in your program: you use fscanf_s incorrectly. You should pass the size of the destination buffer as an rsize_t or a size_t, not an int. There is a good chance int and size_t do not have the same size on your system, so you are invoking undefined behavior. Fix the code this way:

fscanf_s(inp, "%s", buf, (size_t)100);

You should also check the return value of fscanf_s to verify if it did parse a word from the input file. You might also want to specify a maximum number of characters to scan for a word to avoid fscanf_s default behavior that will terminate the program if the word typed is too long. Do this with:

fscanf_s(inp, "%99s", buf, (size_t)100);
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Thank you chqrlie for your valuable programming advices.But how does fhat answer my question? – machine_1 Mar 23 '16 at 05:27
  • 2
    @machine_1: Actually, I did not really see a question in your post... I pointed to some errors in the code that could explain some problems... What are you asking exactly? – chqrlie Mar 23 '16 at 16:14
  • How do i get meanings of the words programatically.That is my question. – machine_1 Mar 23 '16 at 16:24