Reputation: 29
I am really new to programming in C. I have an assignment where I have to fill an array of integers from a text file using command line arguments. The array should be able to take in all the numbers from the file. This is the segment of code that is supposed to do the above, but it fails. I still have to add error checking but I just need to know where I am going wrong, and if I am on the right path.
From what I know so far, I will have to use memory allocation to make my array dynamic. I have used ftell() to find the size of the file in bytes so I can allocate memory accordingly.
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <fstream>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc > 2) {
printf(stderr, "Error, too many arguments supplied.");
exit(1);
}
if (argc == 2) {
int *numArray = NULL; //pointer to integer
FILE* inputFile = fopen(argv[1], "r");
fseek(inputFile, 0, SEEK_END);
// calculating the size of the file
int fileSize = ftell(inputFile);
numArray = malloc(fileSize * sizeof(int));
if (numArray == NULL) {
printf(stderr, "Error: File is empty.");
exit(1);
}
int num;
int arraySize = sizeof(numArray) / sizeof(numArray[0]);
for (int i = 0; i < arraySize; i++) {
fscanf(inputFile, "%d", &num);
numArray[i] = num;
}
fclose(inputFile);
}
}
If file contains: 67, 66, 353, 789, 2342, NumArray = {67, 66, 353, 789, 2342}
Upvotes: 2
Views: 65
Reputation: 144780
There are multiple problems in the code:
<fstream>
is a C++ header, do not mix C and C++.printf(stderr, "Error, too many arguments supplied.");
should produce a warning about the type mismatch on its first argument. use fprintf
to print to stderr
.ftell()
might not return the number of bytes in the file.fileSize * sizeof(int)
is overkill. The numbers are in text format, so at most fileSize / 2
numbers can by found in the file, and likely much less than that.arraySize = sizeof(numArray) / sizeof(numArray[0])
does not compute the number of elements in the array because numArray
is a pointer to an array, not an array. Furthermore you should just keep the number of actual numbers read, which is the final value of i
in the for
loop.fscanf()
: 1 means the conversion succeeded, 0 means invalid input is present, that cannot be converted to an integer, EOF
means end of file, or possibly I/O error.Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "The program expects a single command line argument\n");
return 1;
} else {
int *numArray = NULL;
size_t arraySize = 0;
size_t arrayCount = 0;
FILE *inputFile = fopen(argv[1], "r");
int res, num;
if (inputFile == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n", strerror(errno));
return 1;
}
while ((res = fscanf(inputFile, "%d", &num)) == 1) {
if (arrayCount >= ArraySize) {
size_t newSize = arraySize ? arraySize * 2 : 32;
int *newArray = realloc(numArray, newSize * sizeof(int));
if (newArray == NULL) {
fprintf(stderr, "Out of memory for %zu elements\n", newSize);
exit(1);
}
numArray = newArray;
arraySize = newSize;
}
numArray[arrayCount++] = num;
}
if (res != EOF) {
fprintf(stderr, "Invalid input for element %zu\n", arrayCount);
}
if (arrayCount == 0) {
if (res == EOF) {
fprintf(stderr, "File %s is empty\n", argv[1]);
}
fclose(inputFile);
return 1;
}
... // do something with the arrayCount elements in numArray
free(numArray);
fclose(inputFile);
}
return 0;
}
Upvotes: 2