我试图获取文件的内容并将其放入字符串中。当我运行我的程序并打印字符串时,我会在文件的内容中找到一些奇怪的字符。
我的代码:
int size = 0;
char ch = 0;
char* content = 0;
FILE* fs = fopen(file, "r");
//getting file's content and put it into a string
while (ch != EOF)
{
ch = (char)fgetc(fs);
size++;
content = myRealloc(content, size);
content[size - 1] = ch;
}
printf("%s", content);
myRealloc:
char* myRealloc(char* array, int size)
{
char* temp = 0;
temp = realloc(array, size * sizeof(char));
return temp;
}
文件的内容:
1,2,3,4
5,6,7,8
a,b,c,d
e,f,g,h
我打印时:
1,2,3,4
5,6,7,8
a,b,c,d
e,f,g,h ²²²²ר─
答案 0 :(得分:4)
在末尾添加空终止字符:
int size = 0;
int ch = 0;
char* content = 0;
FILE* fs = fopen(file, "r");
//getting file's content and put it into a string
while ((ch = fgetc(fs)) != EOF)
{
size++;
content = myRealloc(content, size);
content[size - 1] = (char)ch;
}
size++;
content = myRealloc(content, size);
content[size - 1] = '\0';
print("%s", content);
编辑:另外,正如@achal指出的那样,您正在尝试添加EOF字符,因为当您阅读它时,您已经处于while循环中。我相应地修改了我的代码。
答案 1 :(得分:1)
循环中的语句ch = (char)fgetc(fs);
也会尝试打印EOF
,您不应该这样做。
只需用
替换该代码块while ( (ch = fgetc(fs)) != EOF) { /* fetch the char & check the condition */
putchar(ch);
size++;
content = myRealloc(content, size);
content[size - 1] = ch;
}
size++;
content = myRealloc(content, size);
content[size - 1] = '\0';
print("%s", content);
同时查看fgetc()
的手册页,它会返回int
。因此,请ch
输入int
。
int fgetc(FILE *stream);
同样print("%s", content);
应为printf("%s", content);
,除非您没有定义print()
。
最后&最重要的是,一旦完成工作,不要忘记通过调用free()
函数释放动态分配的内存。
答案 2 :(得分:1)
您的字符串未终止。您需要分配足够的空间来容纳最后一个空字符,例如temp = realloc(array, (size + 1) * sizeof(char));
,最后执行content[size] = '\0'
之类的操作。但是,使用realloc
可能是执行您尝试做的最糟糕的方式。
我使用stat
查找文件的大小,然后使用mmap
将文件映射到内存,然后malloc
映射到文件大小,然后memcpy
到malloc
内存。 realloc
是邪恶的,表现明智。
这是一个非常优于原始代码的替代方案:
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char** argv){
if (argc != 2){
printf("Usage: %s {filename}\n",argv[0]);
return 1;
}
int fd = open(argv[1], O_RDONLY);
// @todo: check if fd is valid
struct stat st;
int ret = fstat(fd,&st);
// @todo: check ret
void* mapped_memory = mmap(NULL,st.st_size,PROT_READ,MAP_SHARED,fd,0);
// @todo: check mapped_memory that is not null
char* str = (char*)malloc(sizeof(char)*(st.st_size + 1));
// @todo: check that str is not null
memcpy(str,mapped_memory,st.st_size);
str[st.st_size] = '\0';
printf("%s",str);
free(str);
munmap(mapped_memory,st.st_size);
close(fd);
return 0;
}
答案 3 :(得分:0)
关于:
printf("%s", content);
填写content
内容的代码未能终止该字符数组。
(并且分配的内存没有足够的空间来附加NUL字符)
所以对printf()
的调用将继续输出字符,直到找到NUL字符。
这是输出垃圾字符的根本原因。