我试图创建一个C程序,它用随机整数创建一个txt文件,然后mmap
上述文件,qsort
它。创建txt和Map顺利进行,但我不明白为什么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个随机整数,并没有任何问题地Map。但我猜qsort
不喜欢给它的东西。我试着让mmap
作为int
,但这也带来了其他问题,比如数组中的数字不正确,数字数量不正确,(也许我错误地处理了输出).我不确定我做错了什么.这里是完整的代码,如果需要的话:
#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);
}
型
还有一个快速:数组和指针在实践中的行为是一样的吗(就像字符串一样)?比如我们声明:int *x = { 10, 20, 30, 40 };
,我们可以只声明fprint("%d\t", x[i]);
吗?或者这种类型的数组必须声明为int[] = { 10, 20... };
,而不是指针?(我可以也会自己测试它,如果没有答案,我会编辑“quickie”,直到我能够测试和研究它)
3条答案
按热度按时间qeeaahzv1#
由于多种原因,您无法通过在内存中Map文件并使用比较函数调用
qsort()
来对具有不同大小的数字的文本文件进行排序:qsort
需要一个数组,其中所有条目都具有相同的大小,这不是文本表示的情况。int
数组,而不是一个文本表示数组int
的阵列,由于减法可能溢出,所以比较函数对于大的绝对值也是不合适的。要对文本文件进行排序,经典的方法是分配一个
int
数组并从文件中加载值,将文本表示转换为int
值,使用qsort
和适当的比较函数对数组进行排序,并将排序后的数组转换回字符串表示。这里有一个比较函数,你可以用途:
字符串
kgsdhlau2#
你的代码做的就是你写的。没有
qsort
“喜欢”,或者函数“认为”。你一行一行地写文本,就像下面这样。注意行尾字符:
字符串
下面的函数
型
获取两个指针,将它们解释为
int*
并比较两个int
所指向的。类型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
吗?2uluyalo3#
你应该为你的字符串设置格式(使用常量长度和零左填充):
字符串
然后在
qsort
函数中使用相同的length+1 at size参数。您还应该按如下方式更改
cmp
函数,以便它将字符串转换为atoi
的数字:型
我的建议代码是:
型