0

在 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(?,?,?,?); 
}

这不是我使用的确切代码,但我只是想放一些东西来显示我遇到问题的地方。

直接从文件中读取而不是将字节放入数组中会更好吗?

4

5 回答 5

2

如果我可以提出建议,在找到停止字节之前通读数组可能会更有效,然后在单个 I/O 中从头开始写入数组直到该停止字节。

于 2011-04-18T13:52:20.790 回答
2

这是 fread / fwrite 的一个完整示例。

但是我不确定将整个文件读入内存然后再次将其写入文件是否有任何意义,而您可以在读取输入文件的同时写入输出文件,就像前面的一些示例所展示的那样.

我什至不确定这是否比使用 fgetc 和 fputc 更有效,但至少文件是在一个函数调用中读取和写入的

#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;
}
于 2011-04-18T14:07:35.877 回答
1

一个简单但有效的方法是完全避免读入内存,只需执行以下操作:

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 */
于 2011-04-18T13:52:53.913 回答
0

如果您不必一次读取整个文件,只需分配一个固定大小的缓冲区并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;
}
于 2011-04-18T15:08:39.570 回答
0

这是一种方法:

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 条件退出循环 if

  • i到达缓冲区的末尾
  • 在缓冲区中找到特定字节
  • fputc()返回错误。
于 2011-04-18T14:09:10.480 回答