我为qsort
编写的比较器函数每次运行时都会引发分段错误。具体来说,qsort()
命令本身会导致错误,将其注释掉会使代码运行正常。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "sort.h"
#include <sys/stat.h>
int compare(const void *r1, const void *r2) {
return (strcmp(r1, r2));
}
//Function to compare strings in an array of strings for qsort
int main(int argc, char *argv[]) {
FILE *file;
file = fopen(argv[1], "r");
struct stat fs;
//exists only to get file size
stat(argv[1], &fs);
int file_size = fs.st_size;
int number_of_records = file_size / 100;
char AllRecords[file_size][100];
fread(AllRecords, 100, file_size, file);
fclose(file);
int i = sizeof(AllRecords);
// int l = compare(AllRecords[0],AllRecords[1]);
// Test, current bug, calling qsort causes errors
qsort(AllRecords, i, 100, compare);
FILE *file2 = fopen(argv[2], "w");
fwrite(AllRecords, 100, i, file2);
fclose(file2);
return (0);
}
答案 0 :(得分:1)
您需要非常小心使用的尺寸。该代码有效,解决了数组大小的各种问题。请注意,在堆栈上可以创建多大数组有一个限制。在Unix系统上,1 MiB具有足够的错误余量(限制通常为8 MiB);在Windows上,该限制通常为1 MiB,因此此处施加的限制可能有点大-也许(1000 * 1000)
是安全的;也许较小的值会更好,例如(1024 * 1024 * 15 / 16)
。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define MAX_FILE_SIZE (1024 * 1024)
static int compare(const void *r1, const void *r2)
{
return(strcmp(r1, r2));
}
int main(int argc, char *argv[])
{
assert(argc == 3);
FILE *file = fopen(argv[1], "r");
struct stat fs;
stat(argv[1], &fs);
int file_size = fs.st_size;
if (file_size > MAX_FILE_SIZE)
{
fprintf(stderr, "file %s is too big to be sorted by this program\n", argv[1]);
exit(EXIT_FAILURE);
}
int number_of_records = file_size / 100;
char AllRecords[number_of_records][100];
fread(AllRecords, 100, file_size, file);
fclose(file);
qsort(AllRecords, number_of_records, 100, compare);
FILE *file2 = fopen(argv[2], "w");
fwrite(AllRecords, 100, number_of_records, file2);
fclose(file2);
return(0);
}
问题之一就是生成样本数据。我使用随机数据生成器生成以空字节结尾的99个字符“行”(这样,字符串比较将具有以空结尾的字符串。
输入:
LLWNMGWMIQECKYLWFFIHWSZVYBQLLYTDAXNQNCQRBJZMZNFMMNCBAFYIIXUKXEBGSQHIYVCDVWCUHLXLOCOETLRPZRSGWDERQAZ
YNWEULRIMNODDAKABCKVAXTWLMPFOFIGRIJLKPVTWCFJGXAZEWKZFWCIZVQZYPADMBQOOHITVPEVWOIUSZISJOQTHQHCXEADIHW
YSHUYAQTPVTBKKHXQQXZMJIQVJRFJSNZSXKMHNJRAPNYWVSJRIHVHUBJJJAMRVBJZWWEACTUXLDXEFIDALHJBOKXJBAQJFABKLR
UWXIJELISTPAFXSKEGQHHJYPKWGLBXJSQWFHCAPRJTLQHRZEEEJAELOMKDAQIDIBZKZMCYNCMVLTXDUKLYGEIBVXTXNKPOUGMQE
NFUVXYBDQYMIEVWEQUYPTEASNSOQHZRLLLKXSBSQJFJBNRLSPUELCYTWDLLMTQKKHWFVFCQXNEBBMAPASRZSIOELSZGGFDDWJSK
OXQGGDODECBRVSXUAMZSLIHUJRAUFGMMORRBBGHECQLRWSVZGZWTSSBJVPTTRUIDJVGKTFGJFMSOHHTBIAEFIMUSYXMJAIRIZTU
XRRQOOBLDYLQQMKVFSOIZNTXAARKUZRBFCAEJDGCZGXHUTWHHOHERWPKOLDBCEHCUXPHVJMEUEJVTUDCQFXWAEWMPZPROKSOKAE
LURFJLTYKIIWTMWJLXZGOGCPMMRWZEOCSODVRSQDFTMJJILCIZNQWITWFJSCSAZTTJBYEGAWXBAYGQVQOMQTKTEHGUTOOMOCFAZ
NGBPRHOEICRLXPVTMHULNYJNNRJYVZDDGHDFHJFKELHUGGYWHSMBPCRTAAVHOKAITDPTPGWOOMSHHGLRNVQBMTHCFCPQGDRTCAV
ZJRHMYEPSWTRPGNFZMGPHOSFAFADGTDMISIWGSOCLSYGBURDJEKYYYLZXHHXIYYUVTYNXYBKJLSPNVXIKDZNSIZDITIOWGODJNL
使用tr '\0' '\n'
进行了转换(反之亦然,将换行符转换为空字节)。
输出:
LLWNMGWMIQECKYLWFFIHWSZVYBQLLYTDAXNQNCQRBJZMZNFMMNCBAFYIIXUKXEBGSQHIYVCDVWCUHLXLOCOETLRPZRSGWDERQAZ
LURFJLTYKIIWTMWJLXZGOGCPMMRWZEOCSODVRSQDFTMJJILCIZNQWITWFJSCSAZTTJBYEGAWXBAYGQVQOMQTKTEHGUTOOMOCFAZ
NFUVXYBDQYMIEVWEQUYPTEASNSOQHZRLLLKXSBSQJFJBNRLSPUELCYTWDLLMTQKKHWFVFCQXNEBBMAPASRZSIOELSZGGFDDWJSK
NGBPRHOEICRLXPVTMHULNYJNNRJYVZDDGHDFHJFKELHUGGYWHSMBPCRTAAVHOKAITDPTPGWOOMSHHGLRNVQBMTHCFCPQGDRTCAV
OXQGGDODECBRVSXUAMZSLIHUJRAUFGMMORRBBGHECQLRWSVZGZWTSSBJVPTTRUIDJVGKTFGJFMSOHHTBIAEFIMUSYXMJAIRIZTU
UWXIJELISTPAFXSKEGQHHJYPKWGLBXJSQWFHCAPRJTLQHRZEEEJAELOMKDAQIDIBZKZMCYNCMVLTXDUKLYGEIBVXTXNKPOUGMQE
XRRQOOBLDYLQQMKVFSOIZNTXAARKUZRBFCAEJDGCZGXHUTWHHOHERWPKOLDBCEHCUXPHVJMEUEJVTUDCQFXWAEWMPZPROKSOKAE
YNWEULRIMNODDAKABCKVAXTWLMPFOFIGRIJLKPVTWCFJGXAZEWKZFWCIZVQZYPADMBQOOHITVPEVWOIUSZISJOQTHQHCXEADIHW
YSHUYAQTPVTBKKHXQQXZMJIQVJRFJSNZSXKMHNJRAPNYWVSJRIHVHUBJJJAMRVBJZWWEACTUXLDXEFIDALHJBOKXJBAQJFABKLR
ZJRHMYEPSWTRPGNFZMGPHOSFAFADGTDMISIWGSOCLSYGBURDJEKYYYLZXHHXIYYUVTYNXYBKJLSPNVXIKDZNSIZDITIOWGODJNL
当然,有了这些数据,字符串比较将不需要查找空字节,但是如果文件中有重复的行,那将是至关重要的。
答案 1 :(得分:0)
qsort
函数需要两个数字参数:nitems
和size
。第一个是项目数。我认为您已将此存储在number_of_records
中。第二个是单个记录的大小,您正在使用文字100
。
与其传递i
(整个数组的总字节数),不如传递number_of_records
:
qsort(AllRecords, number_of_records, 100, compare);
答案 2 :(得分:0)
立即解决各种问题。
<?php
$a = isset( $_GET['A'] ) ? $_GET['A'] : '';
echo $a;
$point = isset( $_GET['POIN'] ) ? $_GET['POIN'] : '';
echo $point;
?>
<form enctype="multipart/form-data" method="post" style="width:auto;">
<div class="box">
<span class='odometer' id="timespan" name="timespan">232</span>
</div>
<input
class="process"
name="submit"
type="submit"
id="submit"
value="winners"
onclick="window.location='reward-pollingx.php?A=1&POIN='+document.getElementById('timespan').innerHTML;return false;"
>
</form>
不是file_size
中期望的记录数,file
是期望的记录数。
number_of_records
不应是i
的字节大小,也不应该是AllRecords
中的元素数,而不能是从AllRecords[]
成功读取的项数。
fread()
希望//char AllRecords[file_size][100];
//fread(AllRecords, 100, file_size, file);
//int i = sizeof(AllRecords);
char AllRecords[number_of_records][100];
int i = fread(AllRecords, 100, number_of_records, file);`
qsort(AllRecords, i, 100, compare); // This is OK
,但是在读取文件时会发生废话。 number_of_records == i
的返回值是最好的指示。