在C中获取文件内容最简单的方法

什么是最简单的方法(最less错误,最less的代码行,但是你想解释它)打开一个文件在C中,并将其内容读取到一个string(char *,char [],无论)?

我倾向于将整个缓冲区作为原始内存块加载到内存中,并自行进行parsing。 这样我就可以最好地控制标准库在多个平台上的工作。

这是我用于此的一个存根。 您可能还想检查fseek,ftell和fread的错误代码。 (为了清楚起见省略)。

 char * buffer = 0; long length; FILE * f = fopen (filename, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = malloc (length); if (buffer) { fread (buffer, 1, length, f); } fclose (f); } if (buffer) { // start to process your data / extract strings here... } 

另一个不幸的是高度依赖操作系统的解决scheme是内存映射文件。 好处通常包括读取的性能和减less的内存使用量,因为应用程序视图和操作系统文件caching实际上可以共享物理内存。

POSIX代码看起来像:

  int fd = open("filename", O_RDONLY); int len = lseek(fd, 0, SEEK_END); void *data = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0); 

另一方面,Windows有点棘手,不幸的是我没有一个编译器在我面前testing,但function是由CreateFileMapping()和MapViewOfFile()提供的。

如果文件是文本,并且想要逐行获取文本,最简单的方法是使用fgets()。

 char buffer[100]; FILE *fp = fopen("filename", "r"); // do not use "rb" while (fgets(buffer, sizeof(buffer), fp)) { ... do something } fclose(fp); 

如果“将其内容读入string”意味着该文件不包含带有代码0的字符,则还可以使用getdelim()函数,该函数接受一块内存并在必要时重新分配内存,或者只分配整个缓冲区你,并将文件读入它,直到遇到一个指定的分隔符或文件结尾。 只要传递'\ 0'作为分隔符来读取整个文件。

这个函数可以在GNU C库中find, http://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getdelim-994

示例代码可能看起来很简单

 char* buffer = NULL; size_t len; ssize_t bytes_read = getdelim( &buffer, &len, '\0', fp); if ( bytes_read != -1) { /* Success, now the entire file is in the buffer */ 

如果您正在阅读特殊文件(如标准input或pipe道),则无法事先使用fstat来获取文件大小。 另外,如果你正在读取一个二进制文件,由于embedded的'\ 0'字符,fgets将丢失string大小信息。 读取文件的最佳方法是使用read和realloc:

 #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> int main () { char buf[4096]; ssize_t n; char *str = NULL; size_t len = 0; while (n = read(STDIN_FILENO, buf, sizeof buf)) { if (n < 0) { if (errno == EAGAIN) continue; perror("read"); break; } str = realloc(str, len + n + 1); memcpy(str + len, buf, n); len += n; str[len] = '\0'; } printf("%.*s\n", len, str); return 0; } 

如果你使用的是glib ,那么你可以使用g_file_get_contents ;

 gchar *contents; GError *err = NULL; g_file_get_contents ("foo.txt", &contents, NULL, &err); g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL)); if (err != NULL) { // Report error to user, and free error g_assert (contents == NULL); fprintf (stderr, "Unable to read file: %s\n", err->message); g_error_free (err); } else { // Use file contents g_assert (contents != NULL); } } 
 // Assumes the file exists and will seg. fault otherwise. const GLchar *load_shader_source(char *filename) { FILE *file = fopen(filename, "r"); // open fseek(file, 0L, SEEK_END); // find the end size_t size = ftell(file); // get the size in bytes GLchar *shaderSource = calloc(1, size); // allocate enough bytes rewind(file); // go back to file beginning fread(shaderSource, size, sizeof(char), file); // read each char into ourblock fclose(file); // close the stream return shaderSource; } 

这是一个非常粗略的解决scheme,因为没有检查null。

刚刚从上面接受的答案修改。

 #include <stdio.h> #include <stdlib.h> #include <assert.h> char *readFile(char *filename) { FILE *f = fopen(filename, "rt"); assert(f); fseek(f, 0, SEEK_END); long length = ftell(f); fseek(f, 0, SEEK_SET); char *buffer = (char *) malloc(length + 1); buffer[length] = '\0'; fread(buffer, 1, length, f); fclose(f); return buffer; } int main() { char *content = readFile("../hello.txt"); printf("%s", content); }