如何在 C++ 中将文件内容读入字符串

发布于 2024-12-10 06:17:52 字数 722 浏览 0 评论 0原文

我想将文件的所有内容读入字符串或其他允许我比较两个文件的方法。我正在寻找完全匹配的文件。

只是我如何打开文件并读取它有多少个字符的一小段片段。我用它来与其他文件进行比较,以检查是否有必要比较整个内容。

有没有办法可以比较两个缓冲区?

 char buf[1000];
 string str;
 ssize_t numread; 

    cout<<"Enter in the full file path: ";

    getline(cin,str);

    int f1= open(str.c_str(), O_RDONLY);

        if(f1 ==-1){
            cout<<"file did not open"<<'\t'<<errno<<str<<endl;
        }

    int size= tell(f1);
    lseek(f1,0,SEEK_SET);
    numread= read(f1,buf,size);

        if(numread==-1){
            cout<<errno<<endl;
        }

    cout<<'\t'<<":"<<str<<" #Chars:"<<numread<<endl;

    close(f1);

I want to read the all the contents of a file into a string or some other method that would allow me to compare two files. I am looking for files that are exact matches.

Just a little snippet of how I am opening the file and read how many characters it has. which I use to compare to other files to check if it is necessary to compare the whole contents.

Is there a way I can just compare the two buffers?

 char buf[1000];
 string str;
 ssize_t numread; 

    cout<<"Enter in the full file path: ";

    getline(cin,str);

    int f1= open(str.c_str(), O_RDONLY);

        if(f1 ==-1){
            cout<<"file did not open"<<'\t'<<errno<<str<<endl;
        }

    int size= tell(f1);
    lseek(f1,0,SEEK_SET);
    numread= read(f1,buf,size);

        if(numread==-1){
            cout<<errno<<endl;
        }

    cout<<'\t'<<":"<<str<<" #Chars:"<<numread<<endl;

    close(f1);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如果没有 2024-12-17 06:17:52

为此,请使用内存映射文件。
对于 UNIX mmap() 与 Windows MapViewOfFile()。
这将为您提供内存中映射到文件内容的指针。
为什么这是个好主意?
您不需要使用 malloc() 或 new() 为文件分配空间。
文件可以是任意大小,可以限制 32 位,但应该有 64 位版本。
比较文件

您可以使用memcmp(file1, file2, sizeofile1)

享受...

编辑 - 在 C 中添加了一些代码

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int
cmpfile(char *file1, char *file2)
{
  int result = -1;
  int fd1, fd2;
  off_t size1, size2;
  char *ptr1, *ptr2;

  fd1 = open(file1, O_RDONLY);
  if (fd1 == -1) {
    fprintf(stderr, "Failed to open file '%s' - %s\n", file1, strerror(errno));
    goto error1;
  }

  fd2 = open(file2, O_RDONLY);
  if (fd2 == -1) {
    fprintf(stderr, "Failed to open file '%s' - %s\n", file2, strerror(errno));
    goto error2;
  }

  size1 = lseek(fd1, 0, SEEK_END);
  if (size1 == (off_t)-1) {
    fprintf(stderr, "Failed to seek to end of file '%s' - %s\n", file1, strerror(errno));
    goto error3;
  }

  size2 = lseek(fd2, 0, SEEK_END);
  if (size2 == (off_t)-1) {
    fprintf(stderr, "Failed to seek to end of file '%s' - %s\n", file2, strerror(errno));
    goto error4;
  }

  if (size1 != size2) {
    fprintf(stderr, "File sizes mimatched\n");
    goto error5;
  }

  ptr1 = mmap((void *)0, size1, PROT_READ, MAP_SHARED, fd1, 0);
  if (ptr1 == MAP_FAILED) {
    fprintf(stderr, "Failed to map file '%s' - %s\n", file1, strerror(errno));
    goto error6;
  }

  ptr2 = mmap((void *)0, size2, PROT_READ, MAP_SHARED, fd2, 0);
  if (ptr2 == MAP_FAILED) {
    fprintf(stderr, "Failed to map file '%s' - %s\n", file2, strerror(errno));
    goto error7;
  }

  if (memcmp(ptr1, ptr2, size1) == 0) {
    result = 0;
  }

  munmap(ptr2, size2);
error7:
  munmap(ptr1, size1);
error6:
error5:
error4:
error3:
  close(fd2);
error2:
  close(fd1);
error1:

  return result;
}

int main(int argc, char **argv)
{
  int result = -1;

  if (argc == 3) {
    result = cmpfile(argv[1], argv[2]);
    if ( result == 0 ) {
      printf("Files match\n");
    } else {
      printf("Files don't match\n");
    }

  } else {
    fprintf(stderr, "Usage: %s <file1> <file2>\n", argv[0]);
  }

  return result;
}

Use a memory mapped file for this.
With UNIX mmap() With Windows MapViewOfFile().
This will give you a pointer in memory that maps to the contents of the file.
Why is this a good idea?
You don't need to allocate space for the file using malloc() or new().
The files can be any size, ok 32bit limit, but there should be a 64bit version.
You can compare the files using

memcmp(file1, file2, sizeoffile1)

Enjoy...

edit - added some code in C

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int
cmpfile(char *file1, char *file2)
{
  int result = -1;
  int fd1, fd2;
  off_t size1, size2;
  char *ptr1, *ptr2;

  fd1 = open(file1, O_RDONLY);
  if (fd1 == -1) {
    fprintf(stderr, "Failed to open file '%s' - %s\n", file1, strerror(errno));
    goto error1;
  }

  fd2 = open(file2, O_RDONLY);
  if (fd2 == -1) {
    fprintf(stderr, "Failed to open file '%s' - %s\n", file2, strerror(errno));
    goto error2;
  }

  size1 = lseek(fd1, 0, SEEK_END);
  if (size1 == (off_t)-1) {
    fprintf(stderr, "Failed to seek to end of file '%s' - %s\n", file1, strerror(errno));
    goto error3;
  }

  size2 = lseek(fd2, 0, SEEK_END);
  if (size2 == (off_t)-1) {
    fprintf(stderr, "Failed to seek to end of file '%s' - %s\n", file2, strerror(errno));
    goto error4;
  }

  if (size1 != size2) {
    fprintf(stderr, "File sizes mimatched\n");
    goto error5;
  }

  ptr1 = mmap((void *)0, size1, PROT_READ, MAP_SHARED, fd1, 0);
  if (ptr1 == MAP_FAILED) {
    fprintf(stderr, "Failed to map file '%s' - %s\n", file1, strerror(errno));
    goto error6;
  }

  ptr2 = mmap((void *)0, size2, PROT_READ, MAP_SHARED, fd2, 0);
  if (ptr2 == MAP_FAILED) {
    fprintf(stderr, "Failed to map file '%s' - %s\n", file2, strerror(errno));
    goto error7;
  }

  if (memcmp(ptr1, ptr2, size1) == 0) {
    result = 0;
  }

  munmap(ptr2, size2);
error7:
  munmap(ptr1, size1);
error6:
error5:
error4:
error3:
  close(fd2);
error2:
  close(fd1);
error1:

  return result;
}

int main(int argc, char **argv)
{
  int result = -1;

  if (argc == 3) {
    result = cmpfile(argv[1], argv[2]);
    if ( result == 0 ) {
      printf("Files match\n");
    } else {
      printf("Files don't match\n");
    }

  } else {
    fprintf(stderr, "Usage: %s <file1> <file2>\n", argv[0]);
  }

  return result;
}
木格 2024-12-17 06:17:52

您可以使用istreambuf_iterator,如此示例在 cplusplus.com 上。

#include <iostream>
#include <iterator>
#include <string>
#include <stdexcept>
#include <fstream>

int main (int ac, char **av) {
  if(ac != 3)
    throw(std::runtime_error("Usage: progname file1 file2"));

  if(std::equal(
      std::istreambuf_iterator<char>(
        std::ifstream(av[1], std::ios::binary).rdbuf()),
      std::istreambuf_iterator<char>(),
      std::istreambuf_iterator<char>(
        std::ifstream(av[2], std::ios::binary).rdbuf()))) {
    std::cout << "same\n";
    return 0;
  } else {
    std::cout << "different\n";
    return 1;
  }
}

You could use an istreambuf_iterator, as this example on cplusplus.com.

#include <iostream>
#include <iterator>
#include <string>
#include <stdexcept>
#include <fstream>

int main (int ac, char **av) {
  if(ac != 3)
    throw(std::runtime_error("Usage: progname file1 file2"));

  if(std::equal(
      std::istreambuf_iterator<char>(
        std::ifstream(av[1], std::ios::binary).rdbuf()),
      std::istreambuf_iterator<char>(),
      std::istreambuf_iterator<char>(
        std::ifstream(av[2], std::ios::binary).rdbuf()))) {
    std::cout << "same\n";
    return 0;
  } else {
    std::cout << "different\n";
    return 1;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文