问题
The goal of the program is to generate a random sequence of numbers between 1 and N, where N is passed as an argument to the program, and write the resulting sequence to a file.
My file isn't produced. What am I doing wrong? Are there any errors in my code? Is there something wrong with my code? Am I outputting the file correctly?
/*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*/ }
回答1:
the posted code contains LOTS of serious problems. Specifically:
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.
Notice that final message: Compilation finished successfully.
This only means that the compiler applied some 'workaround' to each of the problems, it does NOT mean that the 'workaround' was correct.
Please correct your code so it cleanly compiles, then post a EDIT
to your question
a few hints:
- never access beyond
argv[0]
without first checkingargc
to assure the user actually entered the expected command line parameter. - the syntax for
fprintf()
isint fprintf(FILE *stream, const char *format, ...);
- the syntax for
strtoul()
isunsigned long int strtoul(const char *nptr, char **endptr, int base);
also, regarding:
FILE *fd = fopen("results.txt", "w+");
always check (!=NULL) the returned value. If failed (I.E. ==NULL) then call
perror( "fopen failed" );
so both the error message and the text reason the system thinks the error occurred to stderr
.
来源:https://stackoverflow.com/questions/62804356/why-isnt-my-code-producing-a-random-sequence-of-numbers-between-1-and-n-no-fil