Make a habit of initializing variables. Your scanf
might fail:
scanf("%d", &number_of_files);
What happens if I answer "many"
? Well, first of all, scanf
will return 0
, and next number_of_files
won't get changed. So its value is unknown. If we use it, we end up with undefined behaviour, which is a fancy term to say "we have no idea what will happen".
So in order to at least prevent something like number_of_files = 1000000000
and number_of_values = 10000000
just because the input failed, make sure to initialize your values and maybe check whether scanf
succeeded:
int main()
{
int number_of_files = 0;
int number_of_values = 0;
srand(time(NULL));
printf("before using this program create a folder with the name \"folder\"\nin the same folder this program is located\n");
printf("number of files: ");
if(scanf("%d", &number_of_files) != 1) {
// handle the error?
}
printf("number of values: ");
if(scanf("%d", &number_of_values) != 1) {
// handle the error?
}
create_files(number_of_files, number_of_values);
}
Note that your usage is misleading: the folder has to be located in the folder the program is run, not located.
Let the compiler help you
Note that I got rid of the int i
? You declared it, but you've never used it. You probably had all of your program in your main
and decided to refactor (good!), but you forgot not only the i
, but to return
something in create_files
. Both of these mishaps could have been found with compiler flags:
$ gcc -Wall -pedantic main.c
main.c: In function 'int main()':
main.c:10:9: warning: unused variable 'i' [-Wunused-variable]
int i;
^
main.c: In function 'int create_files(int, int)':
main.c:44:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
Initialize the seed once
I've moved the srand
call into main
. That way there will be only one call to srand
, regardless of how many times you call create_files
. That's handy since
- we can now reconstruct the flow if we print the seed
- we can reconstruct the flow even if we call
create_files
multiple times
- we don't have to worry about calling
create_files
twice in the same second
Simplify and continue to check errors
You can use sprintf
to print your file_name
directly:
char file_name[50] = "";
sprintf(file_name, "./folder/trash-%015d");
This will format file_name
as "./folder/trash-000000000000001"
. Since every file name has the same length, the sorting is somewhat better, and the trash-
prefix will simplify the users life in case they accidentally had a folder called folder
(but they should really rename that folder).
That being said, you should check whether you were able to open that file at all, and whether you could actually write to it. Remember, you're trying to fill a disk (not memory) to the brim. If it's full, you cannot continue to write, and either fopen
or fprintf
will fail:
if(!(file = fopen(file_name, "w+")))
{
perror("Could not open file");
return i;
}
for(int j = 0; j < number_of_values; j++)
{
int random_value = rand();
if(fprintf(file, "%d", random_value) < 0)
{
fclose(file);
return i;
}
}
Note that I return i
because I think you've wanted to return the number of created files, but I'm not sure. If you didn't want to return anything at all, change create_files
return type to void
.
char
for file_name and file_number? Shouldn't they bestring
andint
respectively? \$\endgroup\$string
. You work withchar *
orchar [N]
. \$\endgroup\$