views:

85

answers:

5
#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

const int FILENAME_MAX=20;

int main() {

    ifstream input;
    char name[FILENAME_MAX + 1];
    int value;

    do {

        cout << "Enter the filename (maximum of " << (FILENAME_MAX+1) 
        << " characters: ";
        cin >> name;
        input.open(name);

    } while(input.fail() );

    while(input >> value) {
    int count=1;

    cout << "value #" << count << "\t" << value << endl;

    count++;
    }

return 0;
}

This is a very simple piece of code for reading some numbers from a file. Unfortunately I can't get it to compile. There is an error after/on the line "const int FILENAME_MAX=20;" The error says "expected unqualified-id before numeric constant."

Could someone please tell me what I am doing wrong?


I am compiling on Mac OS 10.5.8 with Xcode 3.0

+1  A: 

FILENAME_MAX is probably a #define somewhere. Try #undef FILENAME_MAX.

pascal
What does the #undef do?
Grady Knotts
Undefine the constant. So that you could reuse its name for your variable.
pascal
sbi
@sbi The problem was that the name `FILENAME_MAX` retained for the `const` was already defined in a `#define` somewhere. So we could have used the `#undef` to remove this previous definition, not to un-define some previous `const`.
pascal
@pascal: That was nit-picking. In C++, we have `const`, and don't need macros, and I wouldn't want newbies to learn that "constant" refers to a `#define`.
sbi
+5  A: 

FILENAME_MAX is a macro that is defined by the standard library*, and so it is already taken for use as an identifier. When you try to use it as an identifier, it's actually being replaced during preprocessing to some number. A number is not a valid identifier, so you get an error. (Which is why it's saying "I was expecting an identifier, not a numeric constant.")

Rename it to something else. (Or use std::string, though it seems you aren't quite there yet.)

*It is defined by <cstdio>. While you don't include it directly, other standard library headers are free to include any other standard headers as they see fit.

GMan
@GMan : You seem to be some C++ Guru ! ..... cheers !
Arkapravo
+1  A: 

FILENAME_MAX is already defined in stdio.h. Change your const name.

Lior Kogan
A: 

Hi

I am on Ubuntu Linux and I could compile it. I changed the FILENAME_MAX to F_M and it worked.

Arkapravo
+3  A: 

Why do you make FILENAME_MAX all upper-case? All upper-case is usually used for macros, and when you hit one (as you do) the preprocessor will mindlessly trample over your code doing the dumbest replacements.

Reserve such identifiers for macros, don't use macros unless you really must (which is rarely ever the case in C++), and this won't happen.

sbi
I wrote FILENAME_MAX in uppercase because the textbook I am using says that constant variables are supposed to be written in uppercase letters. Do you think it is a bad practice to do this? Also, what exactly are macros?
Grady Knotts
@Grady: Yes, that is a _very_ bad practice. It comes from the old times when (in C) macros were all we had to for constants. (Macros are traditionally all upper-case.) Nowadays this makes C++ constants clash with macros from C headers. (If macros clash with macros, compilers are able to provide meaningful error messages.) What book are you using? Have a look at the [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) for community-approved C++ beginner's books.
sbi
Thanks. I think my classes and books are fairly useless; no one has even *mentioned* anything about macros! I believe the book I am using is called *C++ From the Ground Up*.
Grady Knotts
@Grady: Have a look at [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list).
sbi