Reputation: 35
Source:
/*
* Name: Adam Chubbuck
* Date: 1/12/2014
* Class: CSC-1720
* Comment: Assignment #1 (Load-Sort-Print) v1
*/
#include<stdio.h>
int load(char fileName[], int array[]);
int sort(int array[], int length);
int print(int length, int array[]);
int main() {
char fileName[100];
int numList[300];
int length;
printf("File Name: ");
scanf("%s", &fileName);
length = print(sort(numList,load(fileName, numList)), numList);
printf("\nLength: %i\n", length);
printf("Finished execution.\n");
return 0;
}
int load(char fileName[], int array[]) {
FILE *input = fopen(fileName, "r");
int length = 0, i = 0;
if(input == NULL) {
fprintf(stderr, "Error accessing file.\n");
} else {
while(fscanf(input, "%i", &array[i]) != EOF) {
i++;
length++;
}
}
fclose(input);
return length;
}
int sort(int array[], int length) {
int a, b, c;
for (a = 0 ; a < ( length - 1 ); a++) {
for (b = 0 ; b < length - a - 1; b++) {
if (array[b] > array[b+1]) {
c = array[b];
array[b] = array[b+1];
array[b+1] = c;
}
}
}
return length;
}
int print(int length, int array[]) {
int i;
printf("\n[NUMBERS]\n\n");
for (i = 0; i< length; i++) {
printf("[N]%i\n", array[i]);
}
return length;
}
I've read through similar topics on the issue and they advise that I remove the ampersand from the scanf statement, but when I do this and use I/O redirection to a file as follows, it seems to become stuck in an endless loop suggesting that it cannot assign the fileName character array a value.
./a.out < test.txt > output.txt
Upvotes: 0
Views: 340
Reputation: 162164
In C an array is (almost1) the same as a pointer. So taking the address of an array gives the pointer to a pointer. Strings in C are just arrays of char
. So in your statement
scanf("%s", &fileName);
You're passing the pointer to a pointer to scanf
which is not what it expects. You should write just
scanf("%s", fileName);
However be advised, that this is a potential buffer overflow. fileName
has only a limited amount of space and if what's entered is longer it will write beyond the length of fileName
. The safe solution would be:
scanf("%99s", fileName);
[1] The notable difference is the behavior of the sizeof
operator. If it's used on an array identifier it gives the actual size in char
s occupied by the object. If it's used on a pointer it gives the size of the pointer type to the object.
Upvotes: 1
Reputation: 106012
Array names decays to pointer when pass to a function as an argument (some exception are there). fileName
decays to a pointer to the first element of the array fileName
. This is of type char *
,i.e, it is the address of the first element of the array.
On the other hand, &fileName
is the address of the entire array and is of type char (*)[100]
.
%s
specifier expects an argument of type char *
. You need to pass fileName
to scanf
as argument.
When you pass &fileName
as argument of scanf
then compiler sees that it is not the argument of the expected type by the functon scanf
and hence throws an error.
Change
scanf("%s", &fileName);
to
scanf("%s", fileName);
Side Note: Never use scanf
or gets
to read a string as it doesn't check the array bound.. Better to use fgets
.
fgets(fileName, 100, stdin);
Upvotes: 1
Reputation: 4069
What happens when you use
scanf("%99", filename);
Where '99' is the maximum length you want to accept as input, and 'filename' has no ampersand (since you want to point to the first char
of filename
, not the address of filename
)?
Upvotes: 0
Reputation: 28386
You've declared char fileName[100]
. This is almost equivalent to char*
already1. When you do
scanf("%s", &fileName);
it becomes equivalent to passing a char**
.
1: You can google around for pointers vs. arrays to see what the differences are, but for passing parameters they're basically the same.
Upvotes: 1
Reputation: 12175
Arrays pass as pointers by default. Use this instead...
scanf("%s", fileName);
Also I have read somewhere that you shouldn't use EOF to check that a file is finished being read.
Upvotes: 0