【问题标题】:Look up word meaning programmatically and print it to file以编程方式查找词义并将其打印到文件中
【发布时间】:2016-03-17 12:32:36
【问题描述】:

我想出了一个提高词汇量的想法。这个想法是在一个文件中包含大量最常见的英语单词。 然后我会编写一个程序,一次在屏幕上显示一个单词。如果我识别出这个单词,我按向下键 移动到下一个单词,否则我按“S”将这个单词保存到一个名为 Unknown.txt 的文本文件中。

当我完成时,我将收集所有我不知道其含义的单词。如果我停在这里,并手动浏览每个单词 并用我的字典搜索它的含义,这将需要很多时间来学习它们。

但是,如果我有一种方法可以以编程方式保存单词的含义, 我可以轻松打开文件并立即了解单词的含义。这就是我想要实现的目标。

“10kword.txt”文件如下所示:

购买
客户
活跃
回应
练习
硬件。

这是我目前的代码:

#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);
}

【问题讨论】:

  • 与您的问题无关,但不要使用前导下划线后跟大写字母的符号名称(例如您的变量_Buf)。这些名称是为“实现”(即编译器和标准库)保留的。也不要像-32767 一样使用magic numbers。如果要检查特定位或位,请使用位运算符。
  • 我在第 22 行收到此警告; main.cpp(22): warning C4473: 'fscanf_s' : not enough arguments passed for format string.
  • 不要忽略警告,它们是编译器表示你做错事或危险的方式。您收到警告是因为您没有为函数提供足够的参数,这将导致未定义的行为。你应该read a fscanf_s reference
  • 我不明白你在问什么。我可以在您的代码中看到一些错误。
  • 我不明白你想从我们这里得到什么。问题不清楚。文本中唯一的问题是,“有人可以帮我解决这个问题吗?”你到底想要什么?并且代码中有错误。它编译的事实并不意味着它是正确的。例如,您对GetAsyncKeyState 的使用是非常错误的。

标签: c windows winapi


【解决方案1】:

您正在寻找的似乎是一个字典 API,您可以向服务器发送请求并获得响应。快速google search 显示有很多。除此之外,您还需要一些额外的 C 库来发出 HTTP 请求,例如 libcurl,以及解析 JSON 或 XML 的方法 从 this other stack overflow question 你有一个如何使用它的示例,从在那里您可以使用它向 Merriam 的 API 发送请求。

Here's another good API.

这绝对是一个开放式问题,但希望我已经为您指明了正确的方向。

这里有一些示例代码from the curl website 展示了如何使用Curl 来做一个get http 请求:

#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;
}

然后,此示例会将溢出的定义作为 XML 文件打印到内存中。

祝你好运!

【讨论】:

  • 你不认为这是 C++ 吗??
  • 哎呀,我弄错了标签。给我几分钟,我会更新我对 C 的答案
  • 你去。抱歉,我忘了评论它已更新。祝你好运
【解决方案2】:

您的程序中有一个错误:您错误地使用了fscanf_s。您应该将目标缓冲区的大小作为rsize_tsize_t 传递,而不是intintsize_t 在您的系统上很有可能没有相同的大小,因此您正在调用未定义的行为。以这种方式修复代码:

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

您还应该检查fscanf_s 的返回值,以验证它是否解析了输入文件中的单词。您可能还想指定要扫描单词的最大字符数,以避免fscanf_s 默认行为,如果键入的单词太长,则会终止程序。这样做:

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

【讨论】:

  • 感谢 chqrlie 提供宝贵的编程建议。但是 fhat 如何回答我的问题?
  • @machine_1:实际上,我并没有在你的帖子中看到任何问题......我指出了代码中的一些错误,可以解释一些问题......你到底在问什么?跨度>
  • 如何以编程方式获取单词的含义。这是我的问题。
猜你喜欢
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 2011-07-24
相关资源
最近更新 更多