如何从数组中一次读取一个字节?

时间:2011-04-18 13:44:11

标签: c file fwrite

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

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

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

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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;
}

答案 2 :(得分: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 */

答案 3 :(得分: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条件退出循环
  • i点击缓冲区的末尾
  • 在缓冲区中找到特定字节
  • fputc()会返回错误。

答案 4 :(得分: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;
}