为什么不赢这项工作?动态内存初学者程序

时间:2016-01-13 20:15:24

标签: c file dynamic malloc realloc

int main()
{   
    //FILE *out = fopen("keimeno.txt", "w+");

    FILE *in = fopen("keimeno.txt", "r");
    int fullbufflen=0 , i;

    char buffer[100];
    fgets(buffer, 100, in);

    int bufflen = strlen(buffer);
    char *text;
    text =calloc(bufflen,sizeof(char));
    char *strcat(text, buffer); 
    //  printf("line of \"keimeno.txt\": %s", buffer);
    //  printf("size of line \"keimeno.txt\": %i\n\n", bufflen);

    fullbufflen = bufflen;  

    while(fgets(buffer, 100, in)!=NULL)
    {         
        //  printf("line of \"keimeno.txt\": %s", buffer);
        //  printf("size of line \"keimeno.txt\": %i\n\n", bufflen);
        text =realloc(text,bufflen*sizeof(char));
        char *strcat(text, buffer);

        fullbufflen = bufflen + fullbufflen ;
    }
    for (i = 0;i<fullbufflen;i++)
    {
        printf("%c\n",text[i]);
    }
}

我正在尝试将全文文件(keimeno.txt)复制到动态内存数组中,每次最多使用100个字符的缓冲区。为了在最后测试它我试图打印结果。我只是不能让它工作。不知道最后printf上是否有问题,或整个程序是错误的。

此外,动态数组在开始时应该有0个大小,所以如果有人能告诉我如何做到这一点,那将是受欢迎的。

提前致谢。

2 个答案:

答案 0 :(得分:0)

有一些问题:

char *strcat(text, buffer);

这不是你如何调用函数。这是一个函数声明,由于它没有定义参数的类型,因此它是一个不正确的声明。

要致电strcat,请执行以下操作:

strcat(text, buffer);

接下来,您没有为缓冲区分配足够的空间:

text =calloc(bufflen,sizeof(char));

您需要为终止字符串的空字节添加空间:

text =calloc(bufflen + 1,sizeof(char));

同样在这里:

text =realloc(text,bufflen*sizeof(char));

这仅重新分配bufflen个字节。它不会将bufflen个字节添加到已分配的内容中,并且bufflen与首次在while循环之外设置时保持不变。这样做:

bufflen = strlen(buffer);
text =realloc(text,bufflen+fullbufflen+1);

这为您提供了足够的空间用于当前长度,附加缓冲区和空字节。

最后,请确保最后fclose(in)free(text)清理资源,并确保检查fopen的返回值以确保文件成功打开,和realloc / calloc以确保您的分配有效。

完成上述更改后,您的代码应如下所示:

int main(void)
{
    //FILE *out = fopen("keimeno.txt", "w+");

    FILE *in = fopen("keimeno.txt", "r");
    if (in == NULL) {
        perror("open failed");
        exit(1);
    }
    int fullbufflen=0 , i;

    char buffer[100];
    fgets(buffer, 100, in);

    int bufflen = strlen(buffer);
    char *text;
    text =calloc(bufflen+1,sizeof(char));
    if (text == NULL) {
        perror("calloc failed");
        exit(1);
    }
    strcat(text, buffer);
//  printf("line of \"keimeno.txt\": %s", buffer);
//  printf("size of line \"keimeno.txt\": %i\n\n", bufflen);

    fullbufflen = bufflen;

    while(fgets(buffer, 100, in)!=NULL)
    {
    //  printf("line of \"keimeno.txt\": %s", buffer);
    //  printf("size of line \"keimeno.txt\": %i\n\n", bufflen);
        bufflen = strlen(buffer);
        text =realloc(text,bufflen+fullbufflen+1);
        if (text == NULL) {
            perror("realloc failed");
            exit(1);
        }
        strcat(text, buffer);

        fullbufflen = bufflen + fullbufflen ;
    }
    fclose(in);
    for (i = 0;i<fullbufflen;i++)
    {
        printf("%c\n",text[i]);
    }
    free(text);
}

答案 1 :(得分:0)

以下是一种可能的解决方案:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>


#define ERR     (-1) 
#define GROW    100


static void die ( const char * msg ) { perror(msg); exit(1); }


int main ( void ) {

        char *  filename        = "in.txt";
        size_t  buffSize        = 0;
        size_t  buffUsed        = 0;
        ssize_t bytesRead       = 0;
        char *  buffer          = NULL;
        char *  tmp;
        int     fd;

        fd = open(filename, O_RDONLY, 0);
        if (fd == ERR) die("open");

        do {
                buffUsed += (size_t)bytesRead;
                if (buffUsed == buffSize) {
                        tmp = realloc(buffer, buffSize += GROW);
                        if (tmp == NULL) die("realloc");
                        buffer = tmp;
                }
                bytesRead = read(fd, buffer + buffUsed, buffSize - buffUsed);
                if (bytesRead == ERR) die("read");
        } while (bytesRead > 0);

        if (write(STDOUT_FILENO, buffer, buffUsed) == ERR) die("write");
        free(buffer);
        if (close(fd) == ERR) die("close");

        return 0;
}

与原版一样,输入文件名是硬编码的,这是次优的......