动态地将文件复制到char数组中

时间:2018-02-28 13:26:05

标签: c

我有将文本文件(非二进制文件)复制到字符数组中的代码。

我正在尝试将.txt文件的内容复制到char*数组中。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

bool is_not_binary(const void *data, size_t len)
{
    return memchr(data, '\0', len) != NULL;
}

int main(void)
{
    char* file_name="./bash_example.sh";
    FILE *file = fopen (file_name, "r");

    size_t size = 64;
    const size_t line_size = 300;
    char *mem = malloc(size);

    if (mem == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
    }
    *mem = 0;        

    if (file != NULL && is_not_binary(file_name,line_size)) {

        char* line = malloc(line_size);

        while (fgets(line, line_size, file) != NULL)  {

            size_t total = strlen(mem) + strlen(line) + 1;
            if (size < total) {
                    size_t newsize = (total & ~1U) << 1;
                    char *tmp = realloc(mem, newsize);
                    if (tmp == NULL) {
                            perror("realloc");
                            exit(EXIT_FAILURE);
                    }

                    mem = tmp;
                    size = newsize;
            }
            strcat(mem, line);

        }
    }

    printf("%s",mem);

    return 0;
}

但在我的代码中,我必须指定一个静态大小:

size_t size = 64;
const size_t line_size = 300;

我想删除它,我想要动态分配,是否可能? 实际上它是静态代码,64和300。

2 个答案:

答案 0 :(得分:1)

我编写了一个使用fopen,fread的示例,以及随着内容的增长将缓冲区大小加倍的经典示例。

int main()
{

    const size_t initial_size = 1024;
    char* contents = (char*)malloc(initial_size);
    size_t length = 0;
    size_t allocated = initial_size;

    FILE* file = fopen("./sbatch_example.sh", "r");
    if (file)
    {
        while (1)
        {
            size_t remaining = allocated - length;
            size_t result = 0;

            if (remaining == 0)
            {
                contents = (char*)realloc(contents, allocated*2);
                allocated = allocated*2;
                remaining = allocated-length;
            }

            result = fread(contents+length, 1, remaining, file);
            length += result;

            if (result==0) /* EOF */
            {
                break;
            }
        }
    }

    if (file)
    {
        fclose(file);
        file = NULL;
    }

    /* at this point, "contents" is your file data bytes
       and "length" is the number of bytes copied into that array*/

    /*optional: append a null char to the end of the buffer to make  it easier for debugging and print statements */
    contents = (char*)realloc(contents, length+1);
    contents[length] = '\0';


    free(contents);
    return 0;
}

答案 1 :(得分:1)

您可以使用ftell()提前获取总长度,使用fread()一次读取整数。

FILE *fp = fopen("./sbatch_example.sh", "r"); 
if (fp) {
  fseek(fp, 0, SEEK_END);
  size_t size = ftell(fp);
  rewind(fp);
  char *mem = malloc(size+1);
  size_t nr = fread(mem, size, 1, fp);
}