我需要从文本文件中读取未知数量的整数(每行一个)并将它们存储在全局数组中,以便我可以在不同的线程上对它们进行排序。
我的想法是声明(全局)int numberOfValuesToSort;
,然后通过快速传递文件并计算行数来设置它(我让这部分工作得很好)。
我还将全局声明int * unsortedValues;
和int * sortedValues;
(我不确定这是否是正确的格式,或许我需要两颗星?)
然后,我希望在两个数组的每一个中分配适当数量的整数槽(numberOfValuesToSort
),这样我就可以填充unsortedValues
数组,然后将其排序为{{1 }}
我尝试了下面的方法,但在打印时得到了乱码,所以我知道我做错了什么:
sortedValues
修改
在一些打印之后,我注意到/* Allocate the appropriate amount of space in our arrays */
unsortedValues = malloc(numberOfValuesToSort * sizeof(int));
sortedValues = malloc(numberOfValuesToSort * sizeof(int));
for(int i = 0; i < numberOfValuesToSort; i++){
fscanf(myfile, "%d", &unsortedValues[i]);
}
for (int i = 0; i < numberOfValuesToSort; i++) {
printf("Number is: %d\n\n", unsortedValues[i]);
}
的大小是8,而(对于我正在使用的测试用例),unsortedValues
只有6.包括以下代码似乎成功在将数组中的每个点设置为零时,我的输出现在总是= 0(而不是之前看到的乱码)。但是,大小的差异是一个红旗,以及我仍然看到所有零而不是输入文件中的数字的事实。
numberOfValuesToSort
这是输出:
printf("Size of unsortedValues = %lu\nnumberOfValuesToSort = %d\n",
sizeof(unsortedValues), numberOfValuesToSort);
for(int i = 0; i < sizeof(unsortedValues); i++){
unsortedValues[i] = 0;
printf("unsortedValues[%d] = %d\n", i, unsortedValues[i]);
}
答案 0 :(得分:1)
对于这种事情,使用实际的数据结构通常会更好,因为您需要将长度与数据一起存储在某处。此外,如果您在不同的线程上进行排序,则需要同步访问权限,如果您使用实际的数据结构,则可以在此处放置互斥锁。
以下是一个可动态调整大小的数组的示例:
main.c
:
#include <stdio.h>
#include <stdlib.h>
#include "darray.h"
#define BUFSIZE 1024
int main(void)
{
darray arr = darray_create();
FILE * fp = fopen("numbers.dat", "r");
if ( !fp ) {
perror("couldn't open data file");
return EXIT_FAILURE;
}
while ( 1 ) {
char buffer[BUFSIZE];
int value;
if ( !fgets(buffer, BUFSIZE, fp) ) {
break;
}
if ( sscanf(buffer, "%d", &value) != 1 ) {
break;
}
darray_append(arr, value);
}
fclose(fp);
const size_t len = darray_length(arr);
printf("Length of array: %zu\n", len);
for ( size_t i = 0; i < len; ++i ) {
printf("%3zu: %d\n", i, darray_get(arr, i));
}
darray_destroy(arr);
return 0;
}
darray.h
:
#ifndef DARRAY_H
#define DARRAY_H
#include <stddef.h>
typedef struct darray * darray;
darray darray_create(void);
void darray_destroy(darray arr);
size_t darray_length(darray arr);
void darray_append(darray arr, const int data);
void darray_set(darray arr, const size_t index, const int data);
int darray_get(darray arr, const size_t index);
void darray_shrink(darray arr);
#endif /* DARRAY_H */
darray.c
:
#include <stdio.h>
#include <stdlib.h>
#include "darray.h"
#define INIT_ELEMS 16
struct darray {
int * data;
size_t length;
size_t capacity;
};
darray darray_create(void)
{
struct darray * new_arr = malloc(sizeof *new_arr);
if ( !new_arr ) {
perror("couldn't allocate memory for darray");
exit(EXIT_FAILURE);
}
new_arr->data = malloc(INIT_ELEMS * sizeof *new_arr->data);
if ( !new_arr->data ) {
perror("couldn't allocate memory for darray elements");
exit(EXIT_FAILURE);
}
new_arr->length = 0;
new_arr->capacity = INIT_ELEMS;
return new_arr;
}
void darray_destroy(darray arr)
{
free(arr->data);
free(arr);
}
size_t darray_length(darray arr)
{
return arr->length;
}
static void darray_reallocate(darray arr, const size_t new_size)
{
arr->capacity = new_size;
if ( arr->length > arr->capacity ) {
arr->length = arr->capacity;
}
int * new_data = realloc(arr->data, arr->capacity);
if ( !new_data ) {
perror("couldn't reallocate memory for darray data");
exit(EXIT_FAILURE);
}
arr->data = new_data;
}
void darray_append(darray arr, const int data)
{
if ( arr->length == arr->capacity ) {
darray_reallocate(arr, arr->capacity * 2);
}
arr->data[arr->length++] = data;
}
void darray_set(darray arr, const size_t index, const int data)
{
if ( index >= arr->length ) {
fprintf(stderr, "Couldn't set - index of %zu exceeds length of %zu\n",
index, arr->length);
exit(EXIT_FAILURE);
}
arr->data[index] = data;
}
int darray_get(darray arr, const size_t index)
{
if ( index >= arr->length ) {
fprintf(stderr, "Couldn't get - index of %zu exceeds length of %zu\n",
index, arr->length);
exit(EXIT_FAILURE);
}
return arr->data[index];
}
void darray_shrink(darray arr)
{
if ( arr->length != arr->capacity ) {
darray_reallocate(arr, arr->length);
}
}
带输出:
paul@horus:~/Documents/src/sandbox/nsort$ cat numbers.dat
1432
9382
4211
482
55819
11
777
2881
33
6224
paul@horus:~/Documents/src/sandbox/nsort$ ./nsort
Length of array: 10
0: 1432
1: 9382
2: 4211
3: 482
4: 55819
5: 11
6: 777
7: 2881
8: 33
9: 6224
paul@horus:~/Documents/src/sandbox/nsort$
请注意,您只需以这种方式通过输入文件进行一次传递。
答案 1 :(得分:0)
我想出了我的问题。通过初始传递文件来计算行数,我导致连续调用fscanf从文件末尾开始并返回-1
。
我需要做的是:
这是我的工作代码:
/* Determine how many integers (one per line) the file holds */
/* From http://stackoverflow.com/questions/1910724/retrieving-total-line-numbers-in-a-file */
FILE * myfile = fopen(filename, "r");
int ch = 0;
do{
ch = fgetc(myfile);
if(ch == '\n'){ numberOfValuesToSort++; }
} while(ch != EOF);
/* Seek to the beginning of the file */
rewind(myfile);
/* Allocate the appropriate amount of space in our arrays */
unsortedValues = malloc(numberOfValuesToSort * sizeof(int));
sortedValues = malloc(numberOfValuesToSort * sizeof(int));
/* Read through the file again, this time grabbing integers from it as we scan */
int i = 0;
while (!feof (myfile)) {
/* Read an integer and insert it in the array unsortedValues */
fscanf (myfile, "%d", &unsortedValues[i]);
i++;
}
/* Close the file */
fclose(myfile);
/* Ensure we have filled the array with the correct values */
for(int i = 0; i < numberOfValuesToSort; i++){
printf("unsortedValues[%d] = %d\n", i, unsortedValues[i]);
}