[英]fread string of dynamic size from a binary file
我需要知道如何使用fread()从二进制文件读取字符串。
据我了解,如果我想将某个字符串的值复制到这样声明的新字符串中:
char *string;
我需要首先使用strlen()计算另一个字符串的长度,使用该值通过malloc为我的新字符串保留内存,然后使用strcpy()将另一个字符串的值复制到我的新字符串中
有点像这样:
newLength = strlen ( otherString ) + 1;
string = malloc ( sizeof ( char ) * newLength );
if ( string == NULL ) {
return ( FALSE )
}
但是,如果我正在从二进制文件中读取数据,并且试图从所述文件中读取字符串,但是我事先不知道其长度,那么会发生什么情况,因此我无法使用malloc为所述字符串保留内存?
即使我还没有为该字符串保留内存(我不太确信),该方法也可以吗?:
fread ( string, sizeof ( char ), strlen ( string ), currentFile );
我有点卡住了。 希望你们能给我一些启发并引导我一点。
您的问题内容复杂。 您说的是“二进制”文件,但您想从中读取字符串数据。 从文件中解析字符串通常意味着该文件本质上是文本的。 不过,不知道是先验的 ,你正在阅读的字符串的长度,就可以读取该文件逐字节,字节计数,直到你达到一个字符串结束,之后就分配一致的缓冲器,快退的文件,读入缓冲区。
另外,您可以预分配任意大的缓冲区,而不必担心未使用的数量。 如果您需要读取许多不同的量,则可以通过节余分配内存来节省更多,这是通过预先分配内存来优化地读取每个字符串,如果耗尽缓冲区则可以使用realloc() 。
fread()不会进行面向字符串的读取,例如说fscanf() ,它将以%s格式说明符对以字符串结尾的字符串进行空终止。 fread()与数据无关,仅填充指定的缓冲区,如果文件末尾则不填充。 如果“二进制”数据包含空终止符,也许这就是您要使用的终止符,但我认为值得重新考虑。
仅当您打算将字符串指针用于动态内存分配时,声明才是适当的。 如果要使用定义为字符串分配存储,则必须将其定义为数组类型。
char string[1000];
只要您跟踪实际使用了多少内存,分配的内存就不会比使用的内存多(在合理的限制内–您不会为8字节的字符串分配64 kB)。
fread
返回读取的元素数(可能少于请求的项目数),如果您正在读取字符串,则应在分配的字符串中的这么多字节之后添加一个0
字节:
// we'll read at most 255 bytes
// C strings always need one extra '\0' byte at the end, though
char *string = malloc(256);
// open file "test.txt"
FILE *fp = fopen("test.txt", "r");
// read text from file, and store the number of characters read in len
size_t len = fread(string, sizeof(char), 255, fp);
// note that you can't use strlen(string) here because string doesn't have any data
// so we just tell it to read "as many bytes it can, up to a maximum of 255"
// add '\0' byte to the end because all C strings require this,
// and fread() doesn't add this for us
string[len] = '\0'; // note that string[len] is the (len+1)th character
从文件中读取字符串是棘手的,因为许多用户将“文本行”(各种char
后跟'\\n
')称为“字符串”。 但是在C中,“字符串”是各种char
后跟'\\0'
。
fgets()
, scanf()
和fread()
无法从文件中读取C字符串。 没有人容易读取直到'\\0'
的能力。
假设您想读取任意长的“ C字符串”:建议使用fgetc()
。
char *ReadString(FILE *inf) {
if (inf == NULL)
return NULL;
size_t size = 1;
char *buf = malloc(size);
if (buf == NULL) {
return Handle_AllocFailure();
}
size_t i = 0;
int ch;
while ((ch = fgetc(inf)) != EOF && ch != '\0') {
if (i + 1 >= size) {
size_t newsize = (size + 1) * 4 - 1;
char *newbuf = realloc(buf, newsize);
if (newbuf == NULL) {
return Handle_AllocFailure();
}
buf = newbuf;
size = newsize;
}
buf[i++] = ch;
}
buf[i++] = '\0';
// If a final re-size is desired...
char *newbuf = realloc(buf, i);
if (newbuf == NULL) {
return Handle_AllocFailure();
}
buf = newbuf;
return buf;
}
FILE *inf;
...
char *buf = ReadString(inf);
...
free(buf);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.