【问题标题】:Why isn't my code producing a random sequence of numbers between 1 and N? No file is produced. What is the error in my code? What am I doing wrong?为什么我的代码没有生成 1 到 N 之间的随机数字序列?不产生文件。我的代码有什么错误?我究竟做错了什么?
【发布时间】:2020-10-29 10:17:03
【问题描述】:

程序的目标是生成一个介于 1 和 N 之间的随机数字序列,其中 N 作为参数传递给程序,并将生成的序列写入文件。

我的文件没有生成。我究竟做错了什么?我的代码中是否有任何错误?我的代码有问题吗?我输出的文件是否正确?

/*01*/ //
/*02*/ // random_sequence_v6.c
/*03*/ // Generate a random sequence of all numbers between 1 to N
/*04*/ //
/*05*/ #include "stdio.h"
/*06*/ #include "stdint.h"
/*07*/ #include "stdlib.h"
/*08*/ #include "stdint.h"
/*09*/ #include "sys/types.h"
/*10*/ #include "sys/stat.h"
/*11*/ #include "fcntl.h"
/*12*/ #include "assert.h"
/*13*/ #include "inttypes.h"
/*14*/
/*15*/ typedef uint64_t value_t;
/*16*/
/*17*/ value_t* generate_sequence(int num_values)
/*18*/ {
/*19*/     assert(num_values > 0);
/*20*/     value_t* data = calloc(num_values, sizeof(int));
/*21*/     for (int i = 0; i <= num_values; i++) {
/*22*/        data[i] = i;
/*23*/     }
/*24*/     return data;
/*25*/ }
/*26*/
/*27*/ int random_value(int min, int max)
/*28*/ {
/*29*/     int random_number;
/*30*/     do {
/*31*/         random_number = rand();
/*32*/     } while ((random_number <= min) || (random_number >= max));
           return random_number;
/*33*/ }
/*34*/
/*35*/ void randomize_sequence(value_t* sequence, int num_values)
/*36*/ {
/*37*/     // Fisher-Yates
/*38*/     for(int i = 0; i < num_values-2; i++) {
/*39*/         int random_index = random_value(i, num_values-1);
/*40*/         // Swap them
               int temp = sequence[i];
/*41*/         sequence[i] = sequence[random_index];
/*42*/         sequence[random_index] = temp;
/*43*/     }
/*44*/ }
/*45*/
/*46*/ int main(int argc, char* argv[])
/*47*/ {
/*48*/     int num_values = strtoul(argv[1], NULL, 10);
/*49*/     value_t* pValues = generate_sequence(num_values);
/*50*/
/*51*/     randomize_sequence(pValues, num_values);
/*52*/
/*53*/     // Record results
/*54*/     FILE *fd = fopen("results.txt", "w+");
/*55*/     for (int i = 0; i < num_values; i++) {
/*56*/         fprintf("%i = %"PRIu64"\n", i, pValues[i]);
/*57*/     }
/*58*/     fclose(fd);
/*59*/
/*60*/     return EXIT_SUCCESS;
/*71*/ }

【问题讨论】:

  • for (int i = 0; i &lt;= num_values; i++) 应该是 &lt;random_value() 可能需要很长时间。
  • 分配错误。 value_t* data = calloc(num_values, sizeof(int)); --> value_t* data = calloc(num_values, sizeof *data);
  • fprintf("%i = %"PRIu64"\n", i, pValues[i]); --> fprintf(fd,"%i = %"PRIu64"\n", i, pValues[i]);
  • 您也可以用random_number = (rand() % (max - min + 1)) + min ; 替换整个do while 循环......每次都会保证您的值在您的范围内。它会让它更快。在网上找到的

标签: c file random


【解决方案1】:

发布的代码包含很多严重的问题。具体来说:

gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c" -o "untitled2.o" 

untitled2.c: In function ‘generate_sequence’:
untitled2.c:20:35: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
 /*20*/     value_t* data = calloc(num_values, sizeof(int));
                                   ^~~~~~~~~~

untitled2.c:22:25: warning: conversion to ‘value_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
 /*22*/        data[i] = i;
                         ^

untitled2.c: In function ‘randomize_sequence’:
untitled2.c:42:27: warning: conversion to ‘int’ from ‘value_t {aka long unsigned int}’ may alter its value [-Wconversion]
                int temp = sequence[i];
                           ^~~~~~~~

untitled2.c:44:41: warning: conversion to ‘value_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
 /*42*/         sequence[random_index] = temp;
                                         ^~~~

untitled2.c: In function ‘main’:
untitled2.c:50:29: warning: conversion to ‘int’ from ‘long unsigned int’ may alter its value [-Wconversion]
 /*48*/     int num_values = strtoul(argv[1], NULL, 10);
                             ^~~~~~~

untitled2.c:58:24: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
 /*56*/         fprintf("%i = %"PRIu64"\n", i, pValues[i]);
                        ^~~~~~~~

In file included from untitled2.c:5:0:
/usr/include/stdio.h:312:12: note: expected ‘FILE * restrict {aka struct _IO_FILE * restrict}’ but argument is of type ‘char *’
 extern int fprintf (FILE *__restrict __stream,
            ^~~~~~~

untitled2.c:58:44: warning: passing argument 2 of ‘fprintf’ makes pointer from integer without a cast [-Wint-conversion]
 /*56*/         fprintf("%i = %"PRIu64"\n", i, pValues[i]);
                                            ^

In file included from untitled2.c:5:0:
/usr/include/stdio.h:312:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
 extern int fprintf (FILE *__restrict __stream,
            ^~~~~~~

untitled2.c:48:21: warning: unused parameter ‘argc’ [-Wunused-parameter]
 /*46*/ int main(int argc, char* argv[])
                     ^~~~

Compilation finished successfully.

请注意最后一条消息:Compilation finished successfully. 这仅表示编译器对每个问题都应用了一些“解决方法”,并不意味着“解决方法”是正确的。

请更正您的代码,使其能够干净地编译,然后在您的问题中发布EDIT

一些提示:

  1. 在没有首先检查argc 以确保用户确实输入了预期的命令行参数之前,永远不要访问argv[0] 以外的地方。
  2. fprintf() 的语法是int fprintf(FILE *stream, const char *format, ...);
  3. strtoul() 的语法是unsigned long int strtoul(const char *nptr, char **endptr, int base);

另外,关于:

FILE *fd = fopen("results.txt", "w+");

始终检查 (!=NULL) 返回值。如果失败(I.E. ==NULL)然后调用

perror( "fopen failed" );

因此系统认为错误发生的错误消息和文本原因都为stderr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 2015-05-10
    相关资源
    最近更新 更多