對于看起來像這樣的大檔案,我需要使用 malloc 或 calloc 分配記憶體:
2357 VKLYKK
7947 1WTFWZ
3102 F2IXK3
2963 EXMW55
2865 50CJES
2510 8PC1AI
該 .txt 檔案中有大約 10K 行。如何分配所需的記憶體?
該程式應該做什么?該程式必須讀取整個 .txt 檔案,按第一個數字對其進行排序并將輸出發送到 out.txt 但由于檔案的輸入很大,它不會讓我這樣做。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable : 4996)
typedef struct {
int number;
char order[10];
} Data;
int sorting(const void *a, const void *b)
{
Data *dataA = (Data *)a;
Data *dataB = (Data *)b;
// return (dataA->number - dataB->number); // Ascending order
return (dataB->number - dataA->number); // Descending order
}
int main()
{
FILE *fp;
FILE *f = fopen("out.txt", "w");
Data data[20];
char *line[150]
int i = 0;
char file_name[10] = "";
printf("enter file name: ");
scanf("%s", &file_name);
fp = fopen(file_name, "r");
if (fp == NULL)
{
printf("\n%s\" File not found!", file_name);
exit(1);
}
while (1)
{
if (fgets(line, 150, fp) == NULL)
break;
char *pch;
pch = strtok(line, " ");
data[i].number = atoi(pch);
pch = strtok(NULL, " ");
strcpy(data[i].order, pch);
i ;
}
printf("#################\n");
printf("number\torder\n");
for (int k = 0; k < 10; k )
{
printf("%d\t%s", data[k].number, data[k].order);
}
qsort(data, 10, sizeof(Data), sorting);
printf("\n#################\n");
printf("number\torder\n");
for (int k = 0; k < 10; k )
{
printf("%d\t%s", data[k].number, data[k].order);
fprintf(f, "%d\t%s", data[k].number, data[k].order);
}
fclose(fp);
fclose(f);
return 0;
}
uj5u.com熱心網友回復:
如果您的檔案包含大約 10,000 行,您的while回圈將很快超出您的data陣列(您宣告的陣列只有 20 個元素)。如果事先不知道行數,最好的方法是使用不斷增長的陣列。首先初始化data(以及 newdataSize和dataCount變數),如下所示:
int dataSize = 0;
int dataCount = 0;
Data *data = NULL;
然后,當您用完陣列中的空間時,當它到達dataSize條目時,您將不得不增加您的陣列。像這樣的東西:
while (1) {
if (dataCount >= dataSize) {
Data *new;
dataSize = 1000;
new = realloc(data,dataSize * sizeof *data);
if (new == NULL) {
perror("realloc");
free(data);
return 2;
}
data = new;
}
int cnt = fscanf(fp,"%d %9s", &data[dataCount].number, data[dataCount].order);
if (cnt == EOF)
break;
if (cnt != 2) {
printf("Error reading data\n");
return 1;
}
dataCount ;
}
當 while 回圈完成時(如果沒有錯誤),data陣列將包含所有資料,并且dataCount將是找到的資料項的總數。
請注意,我使用fscanf了代替fgets,因為這消除了像呼叫atoi和呼叫這樣的中間步驟的需要strcpy。我還進行了一些簡單的錯誤檢查。我選擇了 1000 作為增長增量,盡管你可以改變它。但是太小會更快地對堆進行碎片化,而太大則太快需要大量記憶體。
uj5u.com熱心網友回復:
這條線
char* line[150];
創建一個包含 150 個字符指標的陣列,如果您正在閱讀這樣的一行,這不是您想要的
if (fgets(line, 150, fp) == NULL) break;
我懷疑你想要一行 150 個字符
也一樣
char line[150];
uj5u.com熱心網友回復:
您可以使用qsort對行陣列進行排序,但這可能不是最好的方法。將行插入到可以輕松按順序遍歷的資料結構中可能更有效。盡管這個簡單的解決方案遠不理想,但這里有一個簡單的插入樹的示例。這會按字典順序對行進行排序;修改它以根據行進行數字排序是一個很好的練習。
/* Build an (unbalanced) binary search tree of lines in input. */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void * xrealloc(void *buf, size_t num, size_t siz, void *end);
FILE * xfopen(const char *path, const char *mode);
struct entry {
const char *line;
struct entry *node[2];
};
static struct entry *
new_node(const char *line)
{
struct entry *e = calloc(1, sizeof *e);
if( e == NULL ){
perror("calloc");
exit(EXIT_FAILURE);
}
e->line = line;
return e;
}
/*
* Note that this tree needs to be rebalanced. In a real
* project, we would use existing libraries.
*/
static struct entry *
lookup(struct entry **lines, const char *line)
{
struct entry *t = *lines;
if( t ){
int cmp = strcmp(line, t->line);
return lookup(&t->node[cmp > 0], line);
} else {
return *lines = new_node(line);
}
}
/* In-order descent of the tree, printing one line per entry */
static void
print_table(const struct entry *t)
{
if( t ){
print_table(t->node[0]);
printf("%s", t->line);
print_table(t->node[1]);
}
}
static void *
xrealloc(void *buf, size_t num, size_t siz, void *endvp)
{
char **endp = endvp;
ptrdiff_t offset = endp && *endp ? *endp - (char *)buf : 0;
buf = realloc(buf, num * siz);
if( buf == NULL ){
perror("realloc");
exit(EXIT_FAILURE);
}
if( endp != NULL ){
*endp = buf offset;
}
return buf;
}
int
main(int argc, char **argv)
{
FILE *ifp = argc > 1 ? xfopen(argv[1], "r") : stdin;
struct entry *lines = NULL;
char *line = NULL;
size_t cap = 0;
while( getline(&line, &cap, ifp) > 0 ){
(void) lookup(&lines, line);
line = NULL;
}
print_table(lines);
}
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ){
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/448226.html
