为什么这行不通?动态记忆入门课程
Why won't this work ? Dynamic memory beginner program
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,所以如果有人能告诉我该怎么做,我们将不胜感激。
提前致谢。
有几个问题:
char *strcat(text, buffer);
这不是调用函数的方式。这是一个函数声明,并且是一个不正确的声明,因为它没有定义参数的类型。
要调用 strcat
,只需这样做:
strcat(text, buffer);
接下来,您没有为缓冲区分配足够的space:
text =calloc(bufflen,sizeof(char));
您需要为终止字符串的空字节添加 space:
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);
这为您提供了足够的 space 当前长度、附加缓冲区和空字节。
最后,确保你在最后fclose(in)
和free(text)
清理你的资源,并且一定要检查fopen
的return值以确保文件打开成功,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);
}
这是一种可能的解决方案:
#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;
}
与原始文件一样,输入文件名是 hard-coded 其中 sub-optimal...
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,所以如果有人能告诉我该怎么做,我们将不胜感激。
提前致谢。
有几个问题:
char *strcat(text, buffer);
这不是调用函数的方式。这是一个函数声明,并且是一个不正确的声明,因为它没有定义参数的类型。
要调用 strcat
,只需这样做:
strcat(text, buffer);
接下来,您没有为缓冲区分配足够的space:
text =calloc(bufflen,sizeof(char));
您需要为终止字符串的空字节添加 space:
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);
这为您提供了足够的 space 当前长度、附加缓冲区和空字节。
最后,确保你在最后fclose(in)
和free(text)
清理你的资源,并且一定要检查fopen
的return值以确保文件打开成功,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);
}
这是一种可能的解决方案:
#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;
}
与原始文件一样,输入文件名是 hard-coded 其中 sub-optimal...