Do you include the "string" header when a library such as "iostream" already provides a solution?
Example: Do you include the string library if you have already included the iostream library? Which is the right professional method?
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream fin;
fin.open("input.txt");
string data;
fin >> data;
cout << data << endl; // Works with <iostream>, and without <string>
fin.close();
return 0;
}
Example 2: Use string library if another library provides functionality, even if program compiles without string?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
ifstream fin;
fin.open("input.txt");
string data;
fin >> data;
cout << data << endl; // Even though <iostream> allowed program to compile, we include the <string> library.
fin.close();
return 0;
}
Received points off my CSC 101 class programming assignment because even though program worked, teacher said when using the string datatype I needed to include the string library. Even though technically it was fine without it possibly. Thats the question.
Your teacher was correct.
Your program worked without <string> by chance. Your standard library implementation, of that version, on that platform, under those circumstances, on that day, transitively included what you needed via <iostream>. The standard library is just code, like yours, and it just so happens that your particular implementation contains, inside <iostream>, an #include <string>. It could be buried behind many other #includes but got there eventually. But that's honestly pure chance, and does not mean that this is something the language guarantees, or something that must always be the case even in practice.
You should always code to standards.
If you're using features from <string>, include <string>.
Just today I was trying to build my big project with a new toolchain and found a few places where I'd accidentally relied on transitive includes, and it broke the build as a result because the new standard library implementation had a slightly different arrangement of headers. I dutifully added the missing #includes and now the world is a better place for it.
Related
I've been puzzled by this for a while. To test this out, I made a simple program that just creates a std::string variable and prints it out to the screen. However, it doesn't include <string.h>.
#include <iostream>
using namespace std;
int main()
{
string name = "Test";
cout << name << endl;
return 0;
}
What confuses me is that this program compiles and runs perfectly. Right now I'm using the clang compiler that came with the XCode Developer Tools. Is this intended behavior? I hope this question isn't too ridiculous since I just started learning C++.
The reason you do not need to include the #include <string.h> header file is because when you include the #include <iostream> header file it includes std::string.
However, do not rely on it. What may work on your compiler may not work on another. Always include the proper header files.
To edit your example this is how you should use it:
#include <iostream>
#include <string>
int main()
{
std::string name = "Test";
std::cout << name << std::endl;
return 0;
}
Also note: why you should not use using namespace std;.
Why does my program compile successfully if I don't include <string.h>?
Because you don't use any definition / declaration from <string.h>.
program compiles and runs perfectly ... Is this intended behavior?
It is incidental behaviour.
There are no guarantees that one standard header wouldn't include other standard headers. It just so happens that <iostream> included <string> in this particular version of the standard library. Since there is no guarantee for this, it would be a mistake to rely on such transitive inclusion.
I was splitting up my program into a header and implementation file per usual, however, when I tried to run the code, I got a ton of compile errors. This seems to be an issue with my computer or IDE, but I have not seen it before. This should be relatively simple as it is for a class project.
The code is as follows:
colorPicker.h
#pragma once
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
colorPicker.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
colorPicker::colorPicker() {
colorArray[0] = "Red";
colorArray[1] = "Green";
colorArray[2] = "Purple";
colorArray[3] = "Yellow";
colorArray[4] = "Orange";
colorArray[5] = "Indigo";
colorArray[6] = "Pink";
}
void colorPicker::printAllColors() {
for (int i = 0; i < 7; i++) {
cout << colorArray[i] << endl;
}
}
string colorPicker::randomColor() {
srand((unsigned)time(0));
int j = 0;
j = rand() % 7;
return colorArray[j];
}
main.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
colorPicker p;
p.printAllColors();
cout << "Random Color: " << p.randomColor() << endl;
system("pause");
return 0;
}
There are 20 errors given by the compiler, however, they all seem to be stemming from two undeclared identifiers which are most definitely declared. I am at a loss for what I could possibly do to fix it, and this project is due Sunday. Thank you.
Here are the errors
Tons of Errors
You need #include "colorPicker.h" in colorPicker.cpp. Each .cpp file is handled basically independently by the compiler and they are all joined at the end by the "linker." When the compiler looks at colorPicker.cpp without an include of the corresponding header, it's at a loss as to the definition of all the classes you're working with.
There are a few things you are doing wrong. I'll just pick on a couple.
Firstly, each header file you write should be self-contained - in the sense that, if it relies on content of some other headers, it includes that header. If a compilation unit (a formal name for a source file with a .cpp in your case) includes your header, it should not have to include something else your header depends on.
Second, it is a bad idea for a header to rely on any using directive, such as using namespace std. There are plenty of explanations of that available, so I won't repeat.
To understand the above, look at colorPicker.h
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
Firstly, this depends on string, but there is no definition of string visible in the header file. Usage of that type depends on the standard header <string>.
Second, that string type is within namespace std. So your header relies on the compilation unit (the source file that includes your header) having previously used a using directive i.e. using namespace std.
To fix these two problems, change the header to
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#include <string>
class colorPicker
{
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
(I've also done some minor changes of layout, since I have various reasons to prefer that.
However, the #include <string> means that this version will not fail to compile, as yours does, if it is included by a compilation unit that does not have #include <string>.
The usage of the fully qualified name std::string, rather than string, also means there is no dependence on the using directive using namespace std. It also means compilation errors can't be triggered in your header if your compilation unit has another using directive.
I've also used an include guard, rather than #pragma once. Although most modern compilers support #pragma once, it is actually not standard C++ (a #pragma, by definition in the standard, is a compiler-specific hook). Include guards are supported in standard C++.
If you've done that, your code should mostly compile as is. However, optionally, you may wish to
remove the using directives using namespace std from your other files. If you do that, you will need to change the definition of colorPicker::randomColor() in colorPicker.cpp so it returns the fully qualified type std::string rather than string.
Remove #include <string> from files that have #include "colorPicker.h". This is possible, since colorPicker.h now includes <string>. This step is optional, since there is no problem with including standard headers more than once in a compilation unit.
A few other notes
In C++, although it is not a major concern, it is usually considered better to use include <cstdio> and <cstdlib> rather than the C headers <stdio.h> and <stdlib.h>.
Your code is calling srand((unsigned)time(0)) whenever colorPicker::randomColor() is called. It is better to only call it once in an entire program, not in a function that may be called multiple times.
A header file should be self-contained as far as #includes go. That means that you should be able to #include the header file without having to include other stuff before it!
Your colorPicker.h does not meet that requirement. It apparently uses std::string from the standard library but does not have an #include <string> on top, so everyone who uses colorPicker.h has to remember to put an #include <string> before it. That's pretty annoying.
Even worse, colorPicker.h refers to std::string as string, which implies a using std::string; or using namespace std; somewhere before any #include "colorPicker.h" line, and both of those are very bad coding style in C++, if not used in tighter scopes.
Here's how to fix the header file:
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
As far as your *.cpp files go, I can see that you are using #include "stdafx.h". Why? It's a non-standard Microsoft thing completely unnecessary in your case. You are also using it incorrectly. It must be the first include. Just remove it entirely.
Some other suggested cleanup:
using namespace std; lines in *.cpp files is not as bad as in header files, but if I were you, I'd just get rid of it completely. Just use complete names. Say std::cout, not cout. And so on. It's just the most consistent way and it avoids a lot of trouble.
You include a lot of headers which you don't need. For example, what's <ctime> for?
Don't use system("pause");. Do not look for artificial ways of pausing a command-line program.
You may need add head file and in colorPicker.h.
And the std namespace is needed while using string.
BTW, the header guards is recommended strongly.
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
So I'm learning to use a class .h and .cpp files in my program that reads a file containing information about a bank account. Initially the code worked fine, however after creating the .h and .cpp class files, things don't work so smoothly anymore, as I'm getting strange errors that don't make sense to me.
This is my MAIN cpp file:
#include "Bankaccount.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{ string fileName;
cout << "Enter the name of the data file: ";
cin>>fileName;
cout<<endl;
bankAccount object(fileName);
return 0;
}
This is my Bankaccount.h file
#ifndef BANKACCOUNT_H
#define BANKACCOUNT_H
#include <iostream>
#include <fstream>
#include <string>
class bankAccount
{
public:
bankAccount(string n);
bankAccount();
private:
ifstream sourceFile;
}
And lastly this is the Bankaccount.cpp file
#include "Bankaccount.h"
#include <iostream>
#include <fstream>
#include <string>
bankAccount::bankAccount(string n)
{
sourceFile.open(n.c_str());
}
Which is now generating these errors:
include\Bankaccount.h|13|error: expected ')' before 'n'|
include\Bankaccount.h|18|error: 'ifstream' does not name a type|
include\Bankaccount.h|14|note: bankAccount::bankAccount()|
include\Bankaccount.h|14|note: candidate expects 0 arguments, 1 provided|
include\Bankaccount.h|4|note: bankAccount::bankAccount(const bankAccount&)|
include\Bankaccount.h|4|note: no known conversion for argument 1 from 'std::string {aka std::basic_string}' to 'const bankAccount&'|
I think it might be an issue with the headers? I went a little bit crazy and put all of my relevant headers on each file trying to get it to work.
using namespace std;
This is considered a bad programming practice, and you will do yourself a favor if you forget that this is actually a part of C++ language. Although there are proper situations where one would employ using namespace, this should be avoided until one has a much better technical understanding of C++, its structure, and its grammar; in order to recognize and understand when this can be used correctly (if at all).
In your main() you have:
string fileName;
There is no such class in the C++ library whose name is string. The class's correct name is std::string; however by shoving using namespace std; a few lines above, you end up blissfully unaware of this basic, fundamental fact.
Now, after you understand this, let's go back and look at your header file:
ifstream sourceFile;
Well, there's no such class in the C++ library called ifstream, either. The class's proper name is std::ifstream. All classes and templates from the C++ library exist in the std namespace.
However, because when you #included the header file your using namespace std; alias is not yet defined, your compiler doesn't recognize the class name, and you get this compilation error as a reward.
The solution is not to cram a using namespace std; in your header file. That will simply lead to more chaos and confusion. The proper fix is:
Remove using namespace std; from your code, completely.
Use full names of all classes from the C++ library, everywhere. Replace all references to string, ifstream, and everything else, with their actual class names: std::string, std::ifstream, and so on. Get into the habit of explicitly using the std namespace prefix every time. It might seem like a bother at first, but you'll quickly pick up the habit before long, and you won't think of it twice.
And you'll never be confused by these kinds of compilation errors ever agin.
I am a newbie or noob if you prefer it that way in C++ programming and I'm trying to use std:: because someone told me that is a good habit rather than putting in using namespace std; because it pollutes the global namespace. I'm not sure why std::cin >> name; from my code below produce an error no operator '>>' matches these operands below is the full source code.
#include "stdafx.h"
#include <ios>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
int x, y;
std::string name;
std::cin >> name;
std::cin >> x;
return 0;
}
You forgot this:
#include<string>
You're using std::string which is defined in the above header. You need to include it.
If you use anything from the Standard Library, whether it is container or algorithm, make sure that you have included the appropriate headers which define them. Standard library has lots of header files, especially for containers. As a general rule, each container is defined in its own header file.
You forgot to
#include <string>
Also
#include <ios>
is not necessary.
Hi I am just starting to learn C++. I bought this big C++ for Dummies book and have been going through it. Its been really interesting so far but now I am stuck. I have been googling this problem, but to no avail. I am using I am using codeblocks 10.05 with GNU GCC.
I keep getting an error that says:
In function 'main':
undefined reference to 'SafeCracker(int)'
The code isn't complicated. I am just new and am extremely frustrated. I don't want to skip over this part; I want to know what is going on.
Main:
#include <iostream>
#include "safestuff.h"
using namespace std;
int main()
{
cout << "Surprise, surprise!" << endl;
cout << "The combination is (once again)" << endl;
cout << SafeCracker(12) << endl;
return 0;
}
Function:
#include <iostream>
using namespace std;
string SafeCracker(int SafeID)
{
return "13-26-16";
}
Header:
using namespace std;
#ifndef SAFESTUFF_H_INCLUDED
#define SAFESTUFF_H_INCLUDED
string SafeCracker(int SafeID);
#endif // SAFESTUFF_H_INCLUDED
You are not compiling the second file you listed along with the first one. Try compiling directly with gcc to understand this.
assuming your files are named:
main.cpp
SafeCracker.cpp
safestuff.h
This is what you are doing
gcc main.cpp
While you should be doing this
gcc main.cpp SafeCracker.cpp
Also, SafeCracker.cpp should be including the header file as well, just for clarity. Any reasons why you have them separated?
On another note, from seeing Daniel Hu's answer, <iostream> is automatically including <string> for you. You should not depend on this functionality, and should instead include <string> in each file that uses strings.
(From comment below)
You're probably trying to build your main.cpp as a stand-alone file. This will leave SafeCracker.cpp uncompiled. What you need is create a project in Codeblocks and add all three files to it (both *.cpp files as well as the *.h file).
I think it's because you did not #include <string>
C++ has to import the string library to use strings or else everything is treated as char arrays.