If you use dynamic memory allocation, you neither need to define the array of a fixed size and run the risk of needing more space than you've allocated nor need to reread the file. (On the other hand, for files of a few dozen — or even a few thousand — numbers, this is probably overkill.)
You could also use the standard library sort function, qsort(), rather than use a bubble sort. Granted, for the size of data you're dealing with, the difference between qsort() and bubble sort is not likely to be easily measured, but if you move from tens of numbers to thousands of numbers, the difference between an O(N2) and an O(N log N) algorithm becomes apparent. (See How to sort an array of structures in C? for a discussion of why intcmp() below is written as it is.)
Also, you should error check input operations (and memory allocation). Using a simple function like the err_exit() function shown in the code makes error reporting succinct, and therefore less onerous and reduces the excuses for omitting the error checking. I use a more featureful variant of err_exit() in the majority of my programs, but that is code in its own source file with its own header. Many programs (including the rewrite below) do not check output operations for success; they probably should.
This leads to code similar to this:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static int intcmp(const void *p1, const void *p2);
static void err_exit(const char *fmt, ...);
int main(void)
{
static const char n1[] = "data.in";
static const char n2[] = "data.out";
FILE *f1 = fopen(n1, "r");
FILE *f2 = fopen(n2, "w");
int *V = 0;
char line[1024];
int n = 0;
int max_n = 0;
if (f1 == 0)
err_exit("Failed to open file %s for reading\n", n1);
if (f2 == 0)
err_exit("Failed to open file %s for writing\n", n2);
while (fgets(line, sizeof(line), f1) != NULL)
{
int v;
if (sscanf(line, "%d", &v) != 1)
break;
if (n == max_n)
{
int new_n = (max_n + 2) * 2;
int *new_V = realloc(V, new_n * sizeof(*V));
if (new_V == 0)
err_exit("Failed to realloc array of size %d\n", new_n);
V = new_V;
max_n = new_n;
}
V[n++] = v;
}
qsort(V, n, sizeof(V[0]), intcmp);
for (int i = 0; i < n; i++)
fprintf(f2, "%d\n", V[i]);
free(V);
fclose(f1);
fclose(f2);
return(0);
}
static int intcmp(const void *p1, const void *p2)
{
int i1 = *(int *)p1;
int i2 = *(int *)p2;
if (i1 < i2)
return -1;
else if (i1 > i2)
return +1;
else
return 0;
}
static void err_exit(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(1);
}
int n,i,a,V[i],I'm not quite sure what you expect from that declaration ofV. And whatever it is you expect, I'm pretty sure you're not getting it.fscanf()calls would return EOF, for example). You should check that yourfopen()calls succeed too, though they must be OK in fact since your code is not crashing. You should also defer the definition ofVuntil you know the value ofnand you can writeint V[n];.