在C中使用随机整数对MMMAPAPE进行排序
我正在尝试创建一个C程序,该程序使用随机整数创建TXT文件,然后MMAP
上述文件和QSort
IT。创建TXT和映射顺利进行,但是我无法弄清楚为什么QSort
只是将其摧毁。我的猜测,这与数据类型有关,但是即使与数据类型一起玩,我也会获得相同的结果。
比较:
int cmp(const void *p1, const void *p2)
{
return (*(const int *)p1 - *(const int *)p2);
}
MMAP和QSORT:
char *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, myFile, 0);
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
qsort(addr, 20, sizeof(char), cmp);
printf("\n-------------\n");
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
输出示例:
10
19
9
8
18
2
9
6
3
7
15
12
12
14
6
2
4
3
15
13
-------------
296
1
9
93818
1
0
7
15
12
12
14
6
2
4
3
15
13
因此,在TXT中创建了20个随机整数,并没有问题。但是我猜Qsort
不喜欢给出的内容。 我尝试使用mmap
作为int
,但这创造了其他问题,例如数组中的数字不正确,数量不正确和一些0(也许我错误地处理了输出)。我不确定我在做什么错。如果需要,这是完整的代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <time.h>
#include <stdlib.h>
int cmp(const void *p1, const void *p2);
void rand_txt(int size);
int main() {
rand_txt(20);
int myFile = open("rand.txt", O_RDWR);
struct stat myStat = {};
fstat(myFile, &myStat);
off_t size = myStat.st_size;
char *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, myFile, 0);
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
qsort(addr, 20, sizeof(char), cmp);
printf("\n-------------\n");
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
return 0;
}
int cmp(const void *p1, const void *p2) {
return (*(const int*)p1 - *(const int*)p2);
}
//Function to create a txt with random integers in given size
void rand_txt(int size) {
FILE *fp = fopen("rand.txt", "w");
srand(time(0));
for (int i = 0; i < size; i++)
fprintf(fp, "%d\n", (rand() % size) + 1);
fclose(fp);
}
Quickie: 阵列和指针在实践中的行为是否相同(如字符串)?说我们声明: int *x = {10,20,30,40};
我们可以fprint(“%d \ t”,x [i]);
还是必须将这种类型的数组声明为int [] = {10,20 ...};
而不是指针? (如果没有答案,我可以并且将自己测试并编辑“ Quickie”,直到我能够进行测试和研究之后)
I'm trying to create a C program that creates a txt file with random integers, and then mmap
the said file and qsort
it. Creating the txt and mapping goes smoothly, but I can't figure out why qsort
just destroys it. My guess, it's something to do with data types, but even after playing around with them, I get more or less the same result.
compar:
int cmp(const void *p1, const void *p2)
{
return (*(const int *)p1 - *(const int *)p2);
}
mmap and qsort:
char *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, myFile, 0);
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
qsort(addr, 20, sizeof(char), cmp);
printf("\n-------------\n");
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
output example:
10
19
9
8
18
2
9
6
3
7
15
12
12
14
6
2
4
3
15
13
-------------
296
1
9
93818
1
0
7
15
12
12
14
6
2
4
3
15
13
So 20 random integers are created in txt and mapped with no problems. But I guess qsort
doesn't like what's given to it.
I tried having mmap
as int
, but that created other problems like incorrect numbers in the array and incorrect amount of numbers and some 0s (perhaps I handled the output incorrectly). I'm not exactly sure what I'm doing wrong. here is the full code in case if it's needed:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <time.h>
#include <stdlib.h>
int cmp(const void *p1, const void *p2);
void rand_txt(int size);
int main() {
rand_txt(20);
int myFile = open("rand.txt", O_RDWR);
struct stat myStat = {};
fstat(myFile, &myStat);
off_t size = myStat.st_size;
char *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, myFile, 0);
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
qsort(addr, 20, sizeof(char), cmp);
printf("\n-------------\n");
for (int i = 0; i < size; i++)
printf("%c", addr[i]);
return 0;
}
int cmp(const void *p1, const void *p2) {
return (*(const int*)p1 - *(const int*)p2);
}
//Function to create a txt with random integers in given size
void rand_txt(int size) {
FILE *fp = fopen("rand.txt", "w");
srand(time(0));
for (int i = 0; i < size; i++)
fprintf(fp, "%d\n", (rand() % size) + 1);
fclose(fp);
}
Also a quickie:
Do the arrays and pointers behave in the same way in practice(like strings)? say we declare:int *x = { 10, 20, 30, 40 };
can we just fprint("%d\t", x[i]);
or such type of arrays must be declared as int[] = { 10, 20... };
and not with pointers?
(I can and will test it myself and edit the "quickie" out if there is no answer until after I am able to test and study it)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您无法通过在内存中映射文件并使用比较函数来对具有不同尺寸的数字进行分类,但出于多种原因:
QSort
需要一个数组条目具有相同的大小,这不是文本表示的情况。int
的数组,即使对于int
的数组,也不是一系列文本表示要对文本文件进行排序,经典方法是分配
int
的数组并从文件中加载值QSORT
具有适当的比较功能,然后写入排序的数组,将转换回字符串表示。这是您可以使用的比较功能:
You cannot sort a text file with numbers of different sizes by mapping the file in memory and calling
qsort()
with the comparison function for multiple reasons:qsort
needs an array where all entries have the same size, which is not the case of textual representations.int
, not an array of textual representationsint
, the comparison function would be inappropriate for large absolute values as the subtraction might overflow.To sort the text file, the classic approach is to allocate an array of
int
and load the values from the file, converting from text representation toint
values, sort the array withqsort
with an appropriate comparison function, and write the sorted array converting back to string representations.Here is a comparison function you can use:
您的代码所做的是您写的。没有
QSORT
“喜欢”或功能“思考”。您按行编写文本,如下所示。请注意,线字符的结尾:
以下功能
需要两个指针,将它们解释为
int*
,然后比较两个int
s。类型int
通常具有32位长度。我将在一行中写下您的文本,看看
cmp
函数会做什么。比较器将获得字节
10 \ n1
,将其解释为int
。然后,它将获得字节
9 \ n9 \ n
,将它们解释为int
。并比较这些int
s。正如其他人在评论部分中指出的那样,
QSort
可能会访问您写入文件的数据。这种情况,比较器将比较它在mmap
ed内存中找到的字节值。* int x = {10,20,30,40};
打开编译器警告,看看它会告诉您什么。也许尝试打印
x [0],x [1]
。您为什么要问 Quickey ?您是否会进入虚构c
语言?What your code does is what you wrote. There is no
qsort
"likes", or function "thinks".You write text line by line, like below. Do notice the end of line characters:
The below function
Takes two pointers, interprets them as
int*
and compares twoint
s being pointed to. Typeint
has typically 32-bit length.I will write your text in one line and see what will
cmp
function do.The comparator will get bytes
10\n1
, interpret them as anint
.Then it will get bytes
9\n9\n
, interpret them as anint
. And compare thoseint
s.As others have pointed out in comments section,
qsort
may access past the data that you wrote to the file. That case, comparator will compare bytes values, that it finds in ammap
ed memory.*int x = {10, 20, 30, 40};
Turn on compiler warnings and see what will it tell you. Maybe try to print
x[0], x[1]
. Why are you asking that quickey? Do you trip into imaginaryC
language?您应该为字符串设置格式(持续的长度且左填充零):
然后在
qsort
函数中使用相同的长度+1在size参数时使用。您还应将
cmp
函数如下更改,以便将字符串转换为atoi
的数字:我的建议代码是:
You should set format for your strings(with constant length and zero left padding):
and then use same length+1 at size argument in
qsort
function.You should also change the
cmp
function as follows so that it converts the string into a number byatoi
:My suggested code is: