13

I am used to higher level languages (java, python etc.), where this is dead obvious. I am trying to pass a string the user inputs to cin, the name of a file to open. There appears to be some sort of pointer madness error, and my code will not compile. I deleted some of my code to make it more clear.

#include <iostream>
#include <fstream>
using namespace std;
       
string hash(string filename);
    
int main(){
    cout << "Please input a file name to hash\n";
    string filename;
    cin >> filename;
    cout << hash(filename);
    return 0;
}
        
        
string hash(string filename){
    file.open(filename);
    if(file.is_open()){
        file.close();
    }
    ...
    return returnval;
}

Here is the compile time error.

<code>
$ g++ md5.cpp
md5.cpp: In function ‘std::string hash(std::string)’:
md5.cpp:22: error: no matching function for call to ‘std::basic_ifstream<char, std::char_traits<char> >::open(std::string&)’
/usr/include/c++/4.2.1/fstream:518: note: candidates are: void std::basic_ifstream<_CharT, _Traits>::open(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]
</code>

(I know that there are libraries for md5 hashes, but I am trying to learn about how the hash works, and eventually hash collision)

Anton Kesy
  • 119
  • 7
Muricula
  • 1,174
  • 3
  • 9
  • 16
  • 1
    Take your line numbers and extra spacing out before posting. It makes it hard to copy and paste your code for testing. – Martin York Jun 10 '12 at 05:16
  • 1
    @LokiAstari, I found it out too late, but in most editors you can do Ctrl+Alt+Selection to select the columns with the numbers in and delete them all at once. Saved me a lot of time ever since I found out about it. – chris Jun 10 '12 at 05:21

1 Answers1

21

open() takes a C-style string. Use std::string::c_str() to get this:

file.open (filename.c_str());

In order to use just a string, as pointed out below, you'll need to use a compiler with C++11 support, as the overload was added for C++11.

The reason it's not like Java etc. is that it came from C. Classes didn't exist in C (well, not nearly as well as they do in C++), let alone a String class. In order for C++ to provide a string class and keep compatibility, they need to be different things, and the class provides a conversion constructor for const char * -> std::string, as well as c_str() to go the other way.

Consider passing the argument (and maybe the return too) as const std::string & as well; no unnecessary copies. The optimization would probably catch those, but it's always good to do.

chris
  • 60,560
  • 13
  • 143
  • 205
  • Excellent, the first part fixed my problem. But what is the differenace between a C string and a C++ string? Also, where should I put the const std::string & ? I tried the method declaration, the actual method call, but both gave compile time errors. – Muricula Jun 10 '12 at 05:00
  • @Muricula, A C-style string is more just a plain array of characters. A C++ string is an actual class with functions, state, etc. I'll try to find a good question on here. – chris Jun 10 '12 at 05:01
  • @Muricula, here's one: http://stackoverflow.com/questions/3454900/whats-the-difference-between-c-strings-and-c-strings – chris Jun 10 '12 at 05:03
  • 7
    Another option is to use a newer compiler. The C++11 standard has added an `open(string)` function to the streams. – Bo Persson Jun 10 '12 at 09:22