我只能在新的文本文件中存储有限数量的行

时间:2013-12-14 13:36:06

标签: c file shell storage lines

我有许多不同的伪随机数生成器,用C编写生成任意数量的随机数对(通过CLI)并将它们存储在(新)文本文件中:每列一对数字。我想在文本文件中存储400.000.000个数字,但是当我查看文件所包含的行数时,它只有82.595.525行。这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../Calculos/myfunctions.c"

void outputDevRandomOpenFile (FILE * from_file, FILE * to_file, unsigned long long how_many_pairs){

    unsigned long long i = 0LL;
    int seed;

    unsigned long long max_period = 2147483648LL;

    for (i = 0LL; i < how_many_pairs; i += 1LL){

        fread (&seed, sizeof(int), 1, from_file);
        fprintf (to_file, "%.10lf ", fabs (((double) seed) / ((double) max_period)));

        fread (&seed, sizeof(int), 1, from_file);
        fprintf (to_file, "%.10lf\n", fabs (((double) seed) / ((double) max_period)));
    }
}


int main (int argc, char *argv[]){

    char * endptr;
    unsigned long long how_many_pairs = (unsigned long long) strtoull (argv[1], &endptr, 10);

    FILE * urandom = fopen ("/dev/urandom", "r");
    FILE * to_file = fopen ("generated_numbers_devrandom.txt", "w");

    outputDevRandomOpenFile (urandom, to_file, how_many_pairs);

    fclose (urandom);

    return 0;
 }

起初我怀疑代码中存在某些问题(即我可能在某处选择了错误类型的变量),但我通过在for-loop中包含if (i > 165191050) printf ("%llu\n", i);来测试它(提醒我使用一维数组存储数字对,而不是二维数组,所以在条件中我只是乘以82595525*2)来测试问题是代码是否没有循环{{1} }次,但只有800.000.000。当我在165191050之后执行测试时,它刚刚开始在shell上打印出i = 165191050值,所以它确实循环了那些i次,但是当我看到行的数量时生成的文本文件,再次有800.000.000行。所以我打赌问题不在代码中(或者至少不在我使用的变量类型中)。

我也用这个算法得到了相同的结果(这只是另一个不同的伪随机数发生器):

82595525

同样,它循环#include <stdio.h> #include <stdlib.h> #include <math.h> #define MT_LEN 624 int mt_index; unsigned long mt_buffer[MT_LEN]; void mt_init() { int i; for (i = 0; i < MT_LEN; i++) mt_buffer[i] = rand(); mt_index = 0; } #define MT_IA 397 #define MT_IB (MT_LEN - MT_IA) #define UPPER_MASK 0x80000000 #define LOWER_MASK 0x7FFFFFFF #define MATRIX_A 0x9908B0DF #define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK) #define MAGIC(s) (((s)&1)*MATRIX_A) unsigned long mt_random() { unsigned long * b = mt_buffer; int idx = mt_index; unsigned long s; int i; if (idx == MT_LEN*sizeof(unsigned long)) { idx = 0; i = 0; for (; i < MT_IB; i++) { s = TWIST(b, i, i+1); b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s); } for (; i < MT_LEN-1; i++) { s = TWIST(b, i, i+1); b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s); } s = TWIST(b, MT_LEN-1, 0); b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s); } mt_index = idx + sizeof(unsigned long); return *(unsigned long *)((unsigned char *)b + idx); /* Here there is a commented out block in MB's original program */ } int main (int argc, char *argv[]){ char * endptr; const unsigned long long how_many_pairs = (unsigned long long) strtoll (argv[1], &endptr, 10); unsigned long long i = 0; FILE * file = fopen ("generated_numbers_mt.txt", "w"); mt_init (); for (i = 0LL; i < how_many_pairs; i++){ fprintf (file, "%.10lf ", ((double) mt_random () / (double) 4294967295)); fprintf (file, "%.10lf\n", ((double) mt_random () / (double) 4294967295)); } fclose (file); return 0; } 次,但它只存储800.000.000个数字。

165191050

这里发生了什么?

提前致谢。

2 个答案:

答案 0 :(得分:6)

每行长26个字符,82595525行x 26 = 2147483650字节

如果你仔细观察创建的文件,我很确定最后一行被截断,文件大小正好是2147483647,即2 ^ 31-1。

你不能写一个更大的文件的原因是由于文件系统的限制,但更可能的原因是你编译了一个(非大文件识别)32位二进制文​​件,文件不能用于超过2147483647,因为它是可以使用的最大有符号整数。

如果是这种情况,并且您的操作系统是64位,最简单的解决方法是设置正确的编译器标志以构建64位二进制文​​件,该二进制文件不具有此限制。

否则,请查看abasterfield解决方法。

答案 1 :(得分:3)

使用CFLAGS -D_FILE_OFFSET_BITS=64

进行编译
#define _FILE_OFFSET_BITS 64
在包含任何libc标头

之前,在代码中