如何正确处理一个巨大的字符串?

时间:2011-10-04 19:42:30

标签: c windows

这可能是一个新手问题,但我想避免缓冲区溢出。我从注册表中读取了很多数据,这些数据将被上传到SQL数据库。我在循环中读取数据,并在每次循环后插入数据。我的问题是,这样,如果我读了20个键,并且下面的值是(每台计算机上的键数不同),那么我必须连接到SQL数据库20次。

但是我发现,有一种方法,创建存储过程,并传递整个数据,因此,SQL服务器将处理数据,我只需连接一次到SQL服务器。

不幸的是我不知道如何处理这么大的字符串以避免任何意外错误,比如缓冲器功率流。所以我的问题是如何声明这个字符串?

我应该只创建一个像char string[ 15000 ];这样的字符串并连接值吗?或者有一种更简单的方法吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

STL字符串应该比你描述的方法做得好得多。

您还需要构建一些阈值。例如,如果你的字符串增长超过一百万字节,那么因为你的交易太长,所以考虑建立不同的SQL连接是值得的。

答案 1 :(得分:0)

要在C中正确执行此操作,您需要使用malloc或其中一个操作系统等效项动态分配内存。这里的想法是弄清楚你实际需要多少内存,然后分配正确的数量。注册表函数提供了各种方法来确定每次读取所需的内存量。

如果您正在读取多个值并将它们连接起来,那会有点棘手。一种方法是将每个值读入一个单独分配的内存块,然后将它们连接到一个新的内存块。

然而,可能没有必要去解决这个问题。如果你可以说“如果数据超过X字节,程序将失败”,那么你可以按照你的建议创建一个静态缓冲区。只需确保为缓冲区的剩余部分提供正确大小的注册表和/或字符串连接函数,并检查错误,以便在失败时正常失败而不是崩溃。

还有一点需要注意:如果声明在程序范围内,char buf[15000];是正常的,但如果它出现在函数中,则应添加static说明符。默认情况下,函数中隐式分配的内存是从堆栈中获取的,因此大量分配可能会失败并导致程序崩溃。 (15,000个字节应该没问题,但这不是一个好习惯。)

此外,最好为缓冲区的大小定义一个宏,并始终如一地使用它:

#define BUFFER_SIZE 15000
char buf[BUFFER_SIZE];

以便稍后通过修改单行来轻松增加缓冲区的大小。

答案 2 :(得分:0)

您可以从注册表中读取(键,值)对,并将其存储到预分配的缓冲区中,同时有足够的空间。 在缓冲区内保持“写入”位置。您可以使用它来检查缓冲区中是否有足够的空间用于新的键值对。 当没有剩余空间用于新(键,值)对时 - 执行存储过程并重置缓冲区内的“写入”位置。 在“读取键,值对”循环结束时 - 检查缓冲区的“写入”位置,如果大于0,则执行存储过程。 这样,您可以最大限度地减少在服务器上执行存储过程的次数。

const int MAX_BUFFER_SIZE = 15000;
char buffer[MAX_BUFFER_SIZE];
char buffer_pos = 0; // "write" position within the buffer.

...

// Retrieve key, value pairs and push them into the buffer.
while(get_next_key_value(key, value)) {
  post(key, value);
}

// Execute stored procedure if buffer is not empty.
if(buffer_pos > 0) {
  exec_stored_procedure(buffer);
}
...

bool post(const char* key, const char* value)
{
  int len = strlen(key) + strlen(value) + <length of separators>;

  // Execute stored procedure if there is no space for new key/value pair.
  if(len + buffer_pos >= MAX_BUFFER_SIZE) {
    exec_stored_procedure(buffer);
    buffer_pos = 0;  // Reset "write" position.
  }

  // Copy key, value pair to the buffer if there is sufficient space.
  if(len + buffer_pos < MAX_BUFFER_SIZE) {  
    <copy key, value to the buffer, starting from "write" position>
    buffer_pos += len; // Adjust "write" position.
    return true;
  }
  else {
    return false;
  }
}

bool exec_stored_procedure(const char* buf)
{
  <connect to SQL database and execute stored procedure.>
}