4

好吧,我已经花了三天时间尝试这个,这是场景:

我想从 Google 下载一个“.csv”文件,然后对文件中的数据进行处理。它适用于 Win32 控制台应用程序。我有后者,我一生都无法弄清楚如何下载文件。我听说过 libcurl、curlpp、ptypes,我自己滚动,只是使用 .NET api,并且被告知了很多次:

...这只是一个 GET 请求

好吧,这一切都很好,但我一定错过了一些东西,因为似乎每个人都生来就知道如何做到这一点。我一直在梳理书籍以解决这个问题,甚至在与“C++ 的艺术”一起旅行了一段时间后,LNKerrors 也出现了巨大的问题。

话虽如此,我从中学到了很多,但在这一点上,我只想知道如何去做。C++ 的 API 严重缺乏,找不到示例代码。在线教程几乎不存在。似乎没有一本书认为这很重要。

有人可以给我扔一个救生筏吗?我在这里是一个处于边缘的人。

编辑

“来自 Google”是指我想下载他们托管的 .csv 文件。一个例子可以在这里找到。

4

8 回答 8

2

你应该能够根据你的意愿来改变它。

既然我已经回答了你的问题。为什么选择 C++?没有反对语言,但选择最适合工作的语言。Perl、PHP 和 Python(我相信还有更多)都有很好的文档和对这种操作的支持。

在 perl(我熟悉的那个)中,它只有大约 3-5 行代码。


这是以前在(来自WayBackMachine )中可用的代码片段:

/*
 * This is a very simple example of how to use libcurl from within 
 * a C++  program. The basic idea is that you want to retrieve the 
 * contents of a web page as a string. Obviously, you can replace 
 * the buffer object with anything you want and adjust elsewhere 
 * accordingly.
 * 
 * Hope you find it useful..
 * 
 * Todd Papaioannou
 */

#include <string>
#include <iostream>
#include "curl/curl.h"

using namespace std;

// Write any errors in here
static char errorBuffer[CURL_ERROR_SIZE];

// Write all expected data in here
static string buffer;

// This is the writer call back function used by curl
static int writer(char *data, size_t size, size_t nmemb,
                  std::string *buffer)
{
  // What we will return
  int result = 0;

  // Is there anything in the buffer?
  if (buffer != NULL)
  {
    // Append the data to the buffer
    buffer->append(data, size * nmemb);

    // How much did we write?
    result = size * nmemb;
  }

  return result;
}

// You know what this does..
void usage()
{
  cout < < "curltest: \n" << endl;
  cout << "  Usage:  curltest url\n" << endl;
} 

/*
 * The old favorite
 */
int main(int argc, char* argv[])
{
  if (argc > 1) 
  {
    string url(argv[1]);

    cout < < "Retrieving " << url << endl;

    // Our curl objects
    CURL *curl;
    CURLcode result;

    // Create our curl handle
    curl = curl_easy_init();

    if (curl)
    {
      // Now set up all of the curl options
      curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
      curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
      curl_easy_setopt(curl, CURLOPT_HEADER, 0);
      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);

      // Attempt to retrieve the remote page
      result = curl_easy_perform(curl);

      // Always cleanup
      curl_easy_cleanup(curl);

      // Did we succeed?
      if (result == CURLE_OK)
      {
        cout << buffer << "\n";
        exit(0);
      }
      else
      {
        cout << "Error: [" << result << "] - " << errorBuffer;
        exit(-1);
      }
    }
  }
}
于 2009-01-07T06:20:12.090 回答
2

为什么不直接使用已经存在的东西?

UrlDownloadToFile()

于 2009-01-07T06:47:32.113 回答
1

由于您在 Win32 平台上,因此您可以使用一个内置库以相对简单的方式实现 GET 请求:WinInet,它是 Win32 SDK 的一部分。WinInet的基本参考可以在 MSDN 上找到。

请注意,如果您不熟悉 Win32 API,将会有一些困难。这里有一个相当有用的示例代码块

如果您未能将适当的库引用添加到您的项目,您将收到链接器错误。听起来你已经在那里学到了一些教训,所以我会保持简短,但请放心,你会在 Win32 文档中找到所需的库和头文件引用的引用(你只需要了解在哪里寻找它的页面)。

于 2009-01-07T06:25:26.603 回答
1

你不能用标准库做到这一点。既然是win32,你可以听从Paul Keister的建议。

但是看看libcurl,因为你在 C++ 中,我推荐POCO它也非常有用。它们是非常方便的工具!

于 2009-01-07T07:03:58.820 回答
1

另一个选择是WinHTTP,它也随 Windows 一起提供。

于 2009-01-07T07:10:07.403 回答
1

> 找不到示例代码

???

数十个示例已经发布了 15 年。请参阅 api ng news://comp.os.ms-windows.programmer.win32(C 中的示例)

(COM、INET 等)

于 2009-01-07T10:00:16.140 回答
1

我也一直在为 C++ 寻找一个好的 http 库,但还没有找到“完美”的库。 Boost.Asio非常棒,但对于一个简单的 http 库来说级别很低(尽管http 客户端示例是一个好的开始)。C++ 网络库* ( cpp-netlib) 看起来正在走上正轨,在 asio 之上构建更高级别的 api,但还不是很成熟。查看http_client 示例

除非我能找到更好的选择,否则我要么编写自己的 asio 包装器,要么扩展(并贡献)到 cpp-netlib。

(顺便说一句,libcurl对我来说不是一个更好的选择。它的 api 比我想要的要大得多,而且对于 http 客户端之类的东西非常笨拙,尤其是在 C++ 中。不要误会我的意思,它是一个很棒的库,但不适合简单的http 客户端。)

于 2009-01-08T00:18:54.333 回答
0

C++ 本身并没有真正的 API。要执行 GET 请求,您的程序需要打开到相关站点的 TCP 套接字连接,并将信息发送到套接字以符合 HTTP 规范,请参见此处。您可能可以找到许多库来帮助解决此问题,例如,您可以查看开源程序 wget 使用什么。如果您自己编写代码,那么使用数据包嗅探工具会很有帮助。您可以准确地看到您的浏览器发送到 Web 服务器以取回文件的内容,并准确地发送该消息。这不是太难,但它是相当难的。TCP 最初是一个相当大的学习曲线。

顺便问一下,“来自谷歌”是什么意思?

于 2009-01-07T06:10:08.553 回答