Adam Chubbuck
Adam Chubbuck

Reputation: 35

C Programming - Compiling Error: format '%s' expects type 'char *'

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

Answers (5)

datenwolf
datenwolf

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 chars occupied by the object. If it's used on a pointer it gives the size of the pointer type to the object.

Upvotes: 1

haccks
haccks

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

OnlineCop
OnlineCop

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)?

cplusplus.com::scanf

Upvotes: 0

Jimmy
Jimmy

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

chasep255
chasep255

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

Related Questions