从C中的文件获取str时的奇怪字符

时间:2018-05-08 17:14:00

标签: c file debugging printing char

我试图获取文件的内容并将其放入字符串中。当我运行我的程序并打印字符串时,我会在文件的内容中找到一些奇怪的字符。

我的代码:

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 ²²²²ר─

4 个答案:

答案 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映射到文件大小,然后memcpymalloc内存。 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字符。

这是输出垃圾字符的根本原因。