在C中,我如何从字节数组中读取一个字节,将其放入文件中,然后一遍又一遍地循环,直到找到我想要停止读取的特定字节?
的例子:
while (x = fgetc(file) != EOF )
{
count++;//Counts the number of bytes
}
chars = (unsigned char*) malloc (sizeof(unsigned char)*count+1);
rewind(file);
FILE* output_file = fopen("Filename.jpg", "rb");
while(chars[i] != specificByte)
{
fwrite(?,?,?,?);
}
这不是我使用的确切代码,但我只是想在那里放一些东西来显示我遇到问题的地方。
直接从文件中读取而不是将字节放入数组中可能会更好吗?
如果我可以提出一个建议,它可能会更有效地读取数组,直到你找到你的停止字节,然后从开始写数组,直到在一个单一的I/o中停止字节
下面是一个使用read/fwrite的完整示例。
但是我不确定是否有任何意义将整个文件读取到内存中,然后再将其写入文件,而您可以在读取输入文件的同时写入输出文件,就像前面的一些示例所演示的那样。
我甚至不确定这是否比使用fgetc &但是至少文件是在一个函数调用中读写的。
#include <stdio.h>
#include <stdlib.h>
/* this function retrieves the size of the input file */
long get_filesize(FILE *fp)
{
long filesize;
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
rewind(fp);
return filesize;
}
int main(void)
{
FILE *fp;
unsigned char *data;
long filesize;
unsigned char specificByte = 10; /* line feed for example */
/* open the input file */
fp = fopen("input_file", "rb");
if(fp == NULL) exit(EXIT_FAILURE);
/* get the filesize */
filesize = get_filesize(fp);
/* allocate space for the file */
data = malloc(filesize * sizeof(unsigned char));
if(data == NULL) exit(EXIT_FAILURE);
/* read the file into memory */
fread(data, filesize, sizeof(unsigned int), fp);
fclose(fp);
/* open output file */
fp = fopen("output_file", "wb");
if(fp == NULL) {
free(data);
exit(EXIT_FAILURE);
}
/* check how many bytes should be written into output file */
int i;
for(i = 0; i < filesize && data[i] != specificByte; ++i);
/* write the bytes */
fwrite(data, i, sizeof(unsigned char), fp);
/* close the file and free the memory */
fclose(fp);
free(data);
return EXIT_SUCCESS;
}
一种简单但有效的方法是完全避免读入内存,只需执行以下操作:
while ((input_char = fgetc(input_fp)) != EOF)
{
if (input_char != specificByte)
{
fputc(input_char, output_fp);
}
else
{
/* do something with input_char */
}
}
这在理论上是低效的,因为您每次从缓冲区读取一个字符,这可能会很昂贵。然而,对于许多应用程序来说,这将运行得很好,特别是因为文件读取是由C标准库缓冲的。
如果你确实关心效率,并且希望尽量减少对文件函数的调用,可以使用如下代码:
/* Don't loop through the chars just to find out the file size. Instead, use
* stat() to find out the file size and allocate that many bytes into array.
*/
char* array = (char*) malloc(file_size);
fread(array, sizeof(char), file_size, input_fp);
/* iterate through the file buffer until you find the byte you're looking for */
for (char* ptr = array; ptr < array + file_size; ptr++);
{
if (*ptr == specificByte)
{
break;
}
}
/* Write everything up to ptr into the output file */
fwrite(array, sizeof(char), ptr - array, output_fp);
/* ptr now points to the byte you're looking for. Manipulate as desired */
有一种方法:
int putResult = 0;
for(int i = 0 ; i < BUFFER_SIZE && buffer[i] != specificByte && putResult != EOF ; ++i)
{
putResult = fputc(buffer[i]);
}
if (putResult == EOF)
{
// Deal with the error (in errno)
}
for条件退出循环,如果
-
i
到达缓冲区的末端 - 在缓冲区 中找到特定的字节
-
fputc()
返回错误。
如果你不需要一次读取整个文件,只需分配一个固定大小的缓冲区,并完全避免malloc
;如果你不有来打乱动态内存管理,就不要打乱动态内存管理。
#define PAGE_SIZE ... // however big a chunk you process at a time
...
unsigned char inbuf[PAGE_SIZE];
unsigned char outbuf[PAGE_SIZE];
FILE *input_stream = fopen(...);
FILE *output_stream = fopen(...);
while (fread(inbuf, sizeof inbuf, 1, input_stream))
{
unsigned char *r = inbuf, *w = outbuf;
while (r != inbuf + sizeof inbuf && *r != specificByte)
*w++ = *r++;
fwrite(outbuf, (size_t) (w - outbuf), 1, output_stream);
if (*r == specific_byte)
break;
}