gpt4 book ai didi

C: fscanf 和字符/字符串大小

转载 作者:太空宇宙 更新时间:2023-11-04 07:41:24 24 4
gpt4 key购买 nike

我正在使用 fscanf 解析文本 (css) 文件。基本目标很简单;我想提取任何符合此模式的内容:

@import "some/file/somewhere.css";

所以我正在使用 fscanf,告诉它读取并丢弃直到“@”字符的所有内容,然后存储所有内容直到它到达“;”特点。这是执行此操作的函数:

char* readDelimitedSectionAsChar(FILE *file)
{
char buffer[4096];

int charsRead;
do
{
fscanf(file, "%*[^@] %[^;]", buffer, &charsRead);

} while(charsRead == 4095);

char *ptr = buffer;
return ptr;
}

据我所知,我已经创建了一个能够容纳 4095 个字符的缓冲区。但是,我发现情况并非如此。如果我有一个包含长匹配字符串的文件,如下所示:

@import "some/really/really/really/long/file/path/to/a/file";

使用 char[4096] 缓冲区将其截断为 31 个字符。 (如果我用printf查看buffer的值,发现字符串被截短了。)

如果我增加缓冲区大小,则会包含更多字符串。我的印象是一个字符占用一个字节(尽管我知道这会受到编码的影响)。我想了解这里发生了什么。

理想情况下,我希望能够将缓冲区设置为“即时”所需的大小——也就是说,让 fscanf 只创建一个足够大的缓冲区来存储字符串。这可以做到吗? (我知道 GNU 的 %as 标志,但这是适用于 OS 10.5/10.6 的 Mac 应用程序,我不确定它是否适用于该平台。)

最佳答案

您遇到的主要问题是您要返回指向堆栈上本地缓冲区的指针,该缓冲区悬空(因此会被您进行的下一次调用覆盖)。您也有潜在的缓冲区溢出。您提到了“a”选项,这会有很大帮助,但不幸的是,它是一个 GNU 扩展,通常不可用。

其次,您有这个额外的 scanf 选项,&charsRead 永远不会被写入,因为格式字符串中没有 %。所以 charsRead 将永远是随机垃圾——这意味着你循环将(可能)只运行一次,或者(很少)永远循环。尝试类似的东西

char* readDelimitedSectionAsChar(FILE *file)
{
char buffer[4096], term[2] = "", *rv = 0;
int len = 0;

fscanf(file, "%*[^@]");
while (term[0] != ';' && !feof(file)) {
if (fscanf(file, "%4095[^;]%1[;]", buffer, term) > 0) {
int read = strlen(buffer);
rv = rv ? realloc(rv, len+read+1) : malloc(read+1);
strcpy(rv+len, buffer);
len += read;
}
}
return rv;
}

这仍然是错误的,因为如果您用完内存,它会出现异常(如果您向它提供一个开头带有 @ 而没有 ; 的巨大格式错误的文件,则很容易发生这种情况),

关于C: fscanf 和字符/字符串大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3791850/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com