我希望从内存中原始字节的缓冲区中获取字符串,是否可以正常工作?

static int in = 0;

void *loadFile (FILE *fp)
{
    fseek (fp, 0L, SEEK_END);
    size_t size = ftell (fp);
    fseek (fp, 0L, SEEK_SET);


    char *buf = malloc (sizeof(char) * size);
    if (!buf)
        return NULL;

    if (fread (buf, sizeof(char), size, fp) != size) {
        free (buf);
        return NULL;
    }

    return buf;
}

char *getString (void *buf)
{
    char *l_buf = buf;

    int i, j, num;
    char *string = NULL;

    for (i = in; l_buf[i] == '\n' || l_buf[i] == '\r'; i++);

    for (j = i; l_buf[j] != '\n' && l_buf[j] != '\r'; j++);

    num = j - i;
    string = malloc (sizeof(char) * (num + 1));

    if (!string)
        return NULL;

    in = j;

    strncpy (string, &l_buf[i], num);
    string[num] = '\0';

    return string;
}

最佳答案

我认为所提出的解决方案至少存在一个问题,并且没有检查以确保您不会耗尽getString()中的内存缓冲区末尾。因此,在您的读取代码中避免这种情况的一种方法是像这样将一个显式NULL添加到缓冲区的末尾

char *buf = malloc (sizeof(char) * (size + 1));
if (!buf)
   return NULL;

if (fread (buf, sizeof(char), size, fp) != size) {
    free (buf);
    return NULL;
}
buf[size] = `\0`;


然后在您的字符串提取函数中,将NULL检查添加到行终止测试中,如下所示:

for (i = in; l_buf[i] != '\0' && (l_buf[i] == '\n' || l_buf[i] == '\r'); i++);
if (l_buf[i] == '\0') {
    /* Never saw the start of a line before the buffer ran out */
    return NULL;
}

for (j = i; l_buf[i] != '\0' && l_buf[j] != '\n' && l_buf[j] != '\r'; j++);
if (i == j) {
    return NULL;
}


还有另一个潜在的问题,但是由于您没有说是在UNIX或Windows上运行还是在乎可移植性,所以我不确定。提议的代码不处理同时包含“ \ r”和“ \ n”的行终止符。

我还建议通过使用如下参数替换全局起始位置索引来使函数可重入:

char *getString (void *buf, int *in) { ...


然后像这样更新getString()中的指针:

*in = j;

关于c - 从缓冲区获取字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3120863/

10-16 18:01