我正在编写两个文本文件,每行写一个整数。 我从驱动器中读取它们,我想对它们进行排序合并。 两个输入文件“1piece0”和“1piece1”具有排序整数列表。 输出文件的大小与两个文件组合在一起,但不是那么多整数。 问题:两个输入文件有25430000行,而输出文件应该有50860000行,但它只有17259463行。 这是我目前的代码。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <algorithm>
#define FILESIZE 25430000 * sizeof(int)
#define FILE0 279288034
#define FILE1 279287226
int main()
{
int i;
int fd;
int fd2;
int fd3;
int result;
int *map;
int *map2;
int *map3;
fd3 = open( "file.out", O_RDWR | O_CREAT | O_TRUNC, (mode_t)0755);
if ( fd3 == -1 ) {
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
result = lseek(fd3, FILE0 + FILE1 - 1, SEEK_SET );
if(result == -1) {
close(fd);
perror("Error calling lseek\n");
exit(EXIT_FAILURE);
}
result = write(fd3,"",1);
if( result != 1 ) {
close(fd3);
perror("error writing last byte");
exit(EXIT_FAILURE);
}
map3 =(int *) mmap(0, FILE0 + FILE1, PROT_READ | PROT_WRITE, MAP_SHARED, fd3, 0);
if( map == MAP_FAILED ) {
close(fd);
perror("Error mmapinG fd3");
exit(EXIT_FAILURE);
}
fd = open( "1piece0", O_RDONLY );
if( fd == -1 ) {
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
map = (int *)mmap(0, FILE0, PROT_READ, MAP_SHARED, fd, 0 );
if( map == MAP_FAILED ) {
close(fd);
perror("error mapping file");
exit(EXIT_FAILURE);
}
fd2 = open( "1piece1", O_RDONLY );
if( fd2 == -1 ) {
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
map2 = (int *)mmap(0, FILE1, PROT_READ, MAP_SHARED, fd2, 0 );
if( map == MAP_FAILED ) {
close(fd2);
perror("error mapping file");
exit(EXIT_FAILURE);
}
// while(1);
std::merge( map, map + 25430000, map2, map2 + 25430000, map3 );
if(munmap(map, FILE0 ) == -1 ) {
perror("error unmapping map");
}
close(fd);
if(munmap(map3, FILE0 + FILE1 ) == -1 ) {
perror("error unmapping map3");
}
close(fd3);
if(munmap(map2, FILE1 ) == -1 ) {
perror("error unmapping map2");
}
close(fd2);
return 0;
}
你能告诉我我做错了吗?
更新:按行我的意思是整数,然后是换行符。
答案 0 :(得分:2)
“line”是什么意思?
当你记忆地图时,它将数据视为内存,在这里你就像一个整数数组一样读它。因此,输入必须是本机二进制格式(即以相同的方式存储字节,相同的大小和相同的字节顺序),25430000是您从每个集合中读取的整数。
你的输入是如何存储的?
这里有很多“神奇数字”。
答案 1 :(得分:2)
您不能将文本行视为二进制blob作为int指针进行操作。
您可以将文本文件视为文本extracted and used:
void merge_ints(std::istream &a_in, std::istream &b_in, std::ostream &out) {
int a, b;
std::istream *remaining = 0;
if (!(a_in >> a)) {
remaining = &b_in;
}
else if (!(b_in >> b)) {
out << a << '\n';
remaining = &a_in;
}
else while (a_in && b_in) {
if (a < b) {
out << a << '\n';
if (!(a_in >> a)) {
out << b << '\n';
remaining = &b_in;
}
}
else {
out << b << '\n';
if (!(b_in >> b)) {
out << a << '\n';
remaining = &a_in;
}
}
}
for (int x; *remaining >> x;) {
out << x << '\n';
}
}
Taking advantage of std::merge:
void merge_ints(std::istream &a, std::istream &b, std::ostream &out) {
typedef std::istream_iterator<int> In;
std::merge(In(a), In(), In(b), In(), std::ostream_iterator<int>(out, "\n"));
}
int main() {
stringstream a ("1\n3\n5\n"), b ("2\n4\n6\n7\n"), out;
merge_ints(a, b, out);
cout << out.str();
}