Tuple templates in GCC - c++

I first started C++ with Microsoft VC++ in VS2010. I recently found some work, but I've been using RHEL 5 with GCC. My code is mostly native C++, but I've noticed one thing...
GCC doesn't appear to recognize the <tuple> header file, or the tuple template. At first I thought maybe it's just a typo, until I looked at cplusplus.com and found that the header is indeed not part of the standard library.
The problem is that I like to write my code in Visual Studio because the environment is way superior and aesthetically pleasing than eclipse or netbeans, and debugging is a breeze. The thing is, I've already written a good chunk of code to use tuples and I really like my code. How am I supposed to deal with this issue?
Here's my code:
using std::cout;
using std::make_tuple;
using std::remove;
using std::string;
using std::stringstream;
using std::tolower;
using std::tuple;
using std::vector;
// Define three conditions to code
enum {DONE, OK, EMPTY_LINE};
// Tuple containing a condition and a string vector
typedef tuple<int,vector<string>> Code;
// Passed an alias to a string
// Parses the line passed to it
Code ReadAndParse(string& line)
{
/***********************************************/
/****************REMOVE COMMENTS****************/
/***********************************************/
// Sentinel to flag down position of first
// semicolon and the index position itself
bool found = false;
size_t semicolonIndex = -1;
// Convert the line to lowercase
for(int i = 0; i < line.length(); i++)
{
line[i] = tolower(line[i]);
// Find first semicolon
if(line[i] == ';' && !found)
{
semicolonIndex = i;
// Throw the flag
found = true;
}
}
// Erase anything to and from semicolon to ignore comments
if(found != false)
line.erase(semicolonIndex);
/***********************************************/
/*****TEST AND SEE IF THERE'S ANYTHING LEFT*****/
/***********************************************/
// To snatch and store words
Code code;
string token;
stringstream ss(line);
vector<string> words;
// A flag do indicate if we have anything
bool emptyLine = true;
// While the string stream is passing anything
while(ss >> token)
{
// If we hit this point, we did find a word
emptyLine = false;
// Push it onto the words vector
words.push_back(token);
}
// If all we got was nothing, it's an empty line
if(emptyLine)
{
code = make_tuple(EMPTY_LINE, words);
return code;
}
// At this point it should be fine
code = make_tuple(OK, words);
return code;
}
Is there anyway to save my code from compiler incompatibility?

As long as it's just a pair you can use
typedef pair<int,vector<string>> Code;
But I don't think tuple is standard C++ (turns out it is included in TR1 and consequently also standard C++0x). As usual Boost has you covered though. So including:
#include "boost/tuple/tuple.hpp"
will solve your problem across compilers.

Compilers that ship the TR1 library should have it here
#include <tr1/tuple.hpp>
//...
std::tr1::tuple<int, int> mytuple;
Of course for portability you can use the boost library version in the meantime

Related

gets() is causing compilation failure with ''use of undeclared identifier 'gets'" error

I am trying to solve e problem. I am taking characters as input and using gets(). But the function is showing the above mentioned error.
I don't know why this function is misbehaving. Please help me to find the fault. I am a beginner.
As mentioned the error message is:
Use of undeclared identifier 'gets'
My C++ code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
char line[1000];
bool open = true;
while (gets(line)) //***in this line gets() is showing error***
{
int len = strlen(line);
for (int i = 0; i < len; i++)
{
if (line[i] == '"')
{
if (open)
{
printf("``");
}
else
{
printf("''");
}
open = !open;
}
else
{
printf("%c", line[i]);
}
}
printf("\n");
}
return 0;
}
std::gets was deprecated in C++11 and removed from C++14, this a dangerous function and it should never be used, though some compilers still provide it, it looks like it's not your case, which is a good thing.
You should use something like std::getline, note that for this you'll need the line argument to be std::string.
string line;
//...
while (getline(cin, line)){
//...
}
Alternatively, if you really need a char array, you can use fgets instead:
char line[1000];
//...
while(fgets(line, sizeof line, stdin)){
//remove newline character using strcspn
line[strcspn(line, "\n")] = '\0';
//or with C++ std::replace
replace(&line[0], &line[1000], '\n', '\0'); //&line[1000] one past the array end
//...
}
Side note:
Consider not using using namespace std; and #include <bits/stdc++.h>, follow the links for details.
gets() is deprecated as already mentioned. Read about it here
But let's get to the root cause of why you got the error in the first place.
An
undeclared identifier 'gets'
error is because the compiler can't find the declaration of the function you are using. In your case gets() is defined in stdio.h
I also see that you're using std::getline() as recommended and for that you need to include the string header.
Take a look at the 2 links I've mentioned to understand proper usage.

read and extract informations from file c++

I am trying to find a solution for the error that the c++ compiler (codeblocks) keeps showing to me,I searched for answers on the net but none of them seemed to be helpful.
I have a txt file in which there are numbers,each of them is written in a line.
What i want is to read each number(line by line)and store it in a variable after converting it from string to float.
This my code
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
float z;
int j=0;
stringstream s;
const ifstream fich1;
fich1.open("test.txt",ios::in);
if(!fich1)
{
cerr<<"could not open the file";
EXIT_FAILURE;
};
else const string ligne1;
while((!fich1.eof())
{
if(j!=i)
{
j++;
getline(fich1,l1); // the first error is: no matching function for call to ‘getline(const ifstream&, const string&)
else if(j == i)
{
fich1>>s; // the second error is: ambiguous overload for ‘operator>>’ (operand types are ‘const ifstream {aka const std::basic_ifstream<char>}’ and ‘std::stringstream {aka std::basic_stringstream<char>}’)
z=(float)s; // I couldn't find a clear answer to convert from string to float
}
}
if anyone wants to ask any question about the code to make it clearer may ask it please,I am waiting for your answers as well as your questions :)
After the edit, I am able to read some code, but still I am suggesting the example I have below, since I am see scary things, like an EOF inside a loop!
Oh also, if you have C++11 support, then you could use std::stof.
You could try this (since your post is not readable), which reads a file line by line and stores every float number in a vector:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
int main() {
std::vector<float> v;
std::string rec_file = "test.txt";
std::string line;
std::ifstream myfile(rec_file.c_str());
if(myfile.is_open()) {
while(std::getline(myfile,line)) {
if(!line.empty())
v.push_back(atof(line.c_str()));
}
myfile.close();
} else {
std::cerr << "Unable to open file";
}
for(unsigned int i = 0; i < v.size(); ++i)
std::cout << v[i] << std::endl;
return 0;
}
with the test.txt to be:
1.2
2.3
3.4
4.5
5.6
6.7
and the output:
1.2
2.3
3.4
4.5
5.6
6.7
Your ifstream shouldn't be constant, as getline alters the ifstream.
To convert from char array to float use atof(chararray)
To convert from string to float you could use atof(string.cstr())
You cannot use const here. But that's not your only problem.
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
Looks good.
float z;
int j=0;
stringstream s;
There should be some int main() { here, because that is the function called by the runtime when a C++ executable starts. This isn't Bash or Perl where execution simply picks up at the first statement.
And you either need to write using namespace std; or prefix identifiers like stringstream as std::stringstream.
const ifstream fich1;
This won't work. ifstream must not be declared const. (This is actually the explanation for the errors you encountered, but you made many more.)
An input file stream is an object with complex inner state, like where in the file you're currently at, error flags etc.; this inner state is changing so const ifstream simply won't work.
fich1.open("test.txt",ios::in);
This can't work either due to const, just like all the other operations on fich1 you're doing further down.
if(!fich1)
{ cerr<<"could not open the file";
EXIT_FAILURE;
};
EXIT_FAILURE is a symbolic constant for a return value. As-is, you could just as well have written 0;. If you expected this to end your program, you're wrong.
;
The semicolon ends the if.
else
Since the if has ended, this is a syntax error.
const string ligne1;
If you declare a string const, you cannot assign to it. Besides, even if the else were correct, that semicolon would have ended the else, because you didn't add braces (as you should always do, even with one-line blocks, because it's so easy to make mistakes otherwise).
The way the code continues, I very much doubt this was your intention. (Some discipline with the indenting makes this kind of mistakes really easy to spot.)
while((!fich1.eof())
How to read until EOF from cin.
{ if(j!=i)
{j++;
Do some proper indenting, will you? Besides, no i has been declared at this point.
getline(fich1,l1);
I assume l1 is the string you declared earlier as ligne1. (Since that happened inside the else, ligne1 is no longer in scope, but I'll let that one pass since you obviously intended the while to be inside the else block.)
Anyway, this can't work because both your ifstream and your string are constant, i.e. cannot be changed. This does not make sense, and thus getline() was not defined for const parameters.
else if(j == i)
Since you didn't close the brace of the if statement above, this is a syntax error as well. Again, proper indenting discipline would have made this immediately obvious.
{ fich1>>s;
I very much doubt there exists an operator>>() for const ifstream, so I am not surprised you get an error here.
z=(float)s;
You're trying to cast (C style, too...) a stringstream object to a float number? What do you expect the result might be? It will definitely not be the 3.14 or whatever you've written into test.txt...
}
}
Lost track of your braces. This code is FUBAR, I didn't even check if it makes sense semantically once all the errors are fixed, and I suspect you're pulling some elaborate troll prank here. If that isn't the case, I suggest you take another good look at whatever textbook you're using to learn C++, because you got a good many things very wrong.
Purely style-related advice: fich1, ligne1... don't use localized (non-English) identifiers. It just adds another problem when communicating about your code. (And this is coming from a non-native English speaker.)

Dumping a File into a String Array

I am using Visual C++ with an MFC program, using Visual Studio 2008, and I will be creating or appending to an XML file.
If the file doesn't exist, it will be created, and there is no worries, but it's when the file already exists and I have to append to it that there seems to be an issue.
What I was instructed, and found through some research, was to read the file into a string, back up a bit, and write to the end of the string. My idea for that was to read the file into an array of strings.
bool WriteXMLHeader(string header, ofstream xmlFile)
{
int fileSize = 1;
while(!xmlFile.eof())
{
fileSize++;
}
string entireFile[fileSize];
for(int i = 0; i < fileSize; i++)
{
xmlFile >> entireFile[i];
}
//Processing code to add more to the end
//Save the File
return true;
}
However, this causes an error where entireFile is of unknown size, and there are constants errors popping up.
I am not allowed to use any third party software (already looked into TinyXML and RapidXML).
What would be a better way to append to the end of an XML file above an unknown amount of closing tags?
Edit: My boss keeps talking about sending in a path to a node, and writing after the last instance of the node. He wants this capable of processing xml files with a million indents if needed. (Impossible for one man to accomplish?)
std::vector < std::string>
"I mentioned that, and my boss said no and to focus on strings"
Well this is what a most preferred, easiest, least error prone solution.
Keeping aside you xml parsing, (if any), coming to the question/confusion, whatever it is.
Consider following:
#include <vector>
#include <string>
//...
std::vector < std::string > entireFile;
while ( std::getline(xmlFile, line) )
{
entireFile.push_back( line ) ;
}
xmlFile.close( );
// entireFile now contains all lines from xml file.
// To iterate its just like simple array
for( std::size_t i = 0; i < entireFile.size( ); ++i )
{
// entireFile[i]
}
Note: with <algorithm> and <iterators> you can achieve this in still fewer lines of code.
Suggested Reading: Why is iostream::eof inside a loop condition considered wrong?
If your boss says no, ask him why with courtesy, why ?
There can't be any valid reason unless you're tired with specific environment/platform with limited capabilities.

What is the C++ convention when I need to add a useless return statement?

I was trying to write a function that returns the first non-repeated character in a string. The algorithm I made was:
Assert that the string is non-empty
Iterate through the string and add all non-repeated characters to a set
Assert that the set be non-empty
Iterate through string again and return the first character that's in the set
Add a useless return statement to make the compiler happy. (Arbitrarily return 'F')
Obviously my algorithm is very "brute force" and could be improved on. It runs, anyhow. I was wondering if there's a better way to do this and was also wondering what the convention is for useless return statements. Don't be afraid to criticize me harshly. I'm trying to become a C++ stiffler. ;)
#include <iostream>
#include <string>
#include <set>
char first_nonrepeating_char(const std::string&);
int main() {
std::string S = "yodawgIheardyoulike";
std::cout << first_nonrepeating_char(S);
}
// Finds that first non-repeated character in the string
char first_nonrepeating_char(const std::string& str) {
assert (str.size() > 0);
std::set<char> nonRepChars;
std::string::const_iterator it = str.begin();
while (it != str.end()) {
if (nonRepChars.count(*it) == 0) {
nonRepChars.insert(*it);
} else {
nonRepChars.erase(*it);
}
++it;
}
assert (nonRepChars.size() != 0);
it = str.begin();
while (it != str.end()) {
if (nonRepChars.count(*it) == 1) return (*it);
++it;
}
return ('F'); // NEVER HAPPENS
}
The main problem is just getting rid of warnings.
Ideally you should be able to just say
assert( false ); // Should never get here
but unfortunately that does not get rid of all warnings with the compilers I use most, namely Visual C++ and g++.
Instead I do this:
xassert_should_never_get_here();
where xassert_should_never_get_here is a function that
is declared as "noreturn" by compiler-specific means, e.g. __declspec for Visual C++,
has an assert(false) to handle debug builds,
then throws a std::logic_error.
The last two points are accomplished by a macro XASSERT (its actual name in my code is CPPX_XASSERT, it's always a good idea to use prefixes for macro names so as to reduce name conflict probability).
Of course, the assertion that you should not get to the end, is equivalent to an assertion that the argument string does contain at least one non-repeated character, which therefore is a precondition of the function (part of its contract), which I think should be documented by a comment. :-)
There are three main "modern C++" ways of coding things up when you do not have that precondition, namely
choose one char value to signify "no such", e.g. '\0', or
throw an exception in the case of no such, or
return a boxed result which can be logically "empty", e.g. the Boost class corresponding to Barton and Nackmann's Fallible.
About the algorithm: when you're not intested in where the first non-repeating char is, you can avoid the rescan of the string by maintaining a count per character, e.g. by using a map<char, int> instead of a set<char>.
There is a simpler and "cleaner" way of doing it, but it is not computationally faster than "brute force".
Use a table that counts the number of occurrences of each character in the input string.
Then go over the input string one more time, and return the first character whose count is 1.
char GetFirstNonRepeatedChar(const char* s)
{
int table[256] = {0};
for (int i=0; s[i]!=0; i++)
table[s[i]]++;
for (int i=0; s[i]!=0; i++)
if (table[s[i]] == 1)
return s[i];
return 0;
}
Note: the above will work for ASCII strings.
If you're using a different format, then you'll need to change the 256 (and the char of course).

ITERATOR LIST CORRUPTED in std::string constructor

The code below compiled in Debug configuration in VS2005 SP1 shows two messages with “ITERATOR LIST CORRUPTED” notice.
Code Snippet
#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0
#include <sstream>
#include <string>
int main()
{
std::stringstream stream;
stream << "123" << std::endl;
std::string str = stream.str();
std::string::const_iterator itFirst = str.begin();
int position = str.find('2');
std::string::const_iterator itSecond = itFirst + position;
std::string tempStr(itFirst,itSecond); ///< errors are here
return 0;
}
Is it a bug in the compiler or standard library?
My bad! Edit: Yeah problem with compiler. See this -- particularly the Community Content section.
What #dirkgently said in his edit.
Apparently, some code for std::string is located in the runtime dll, in particular the macro definition does not take effect for the constructor an the code for iterator debugging gets executed. You can fix this by linking the runtime library statically.
I would consider this a bug, though perhaps not in the Visual Studio itself, but in the documentation.
There is a problem with your code. Well, several in fact:
std.find('2') returns a size_t, you have a potential cast problem if the value of the size_t returned (like std::string::npos) is superior to what an int can hold (you would end up with a negative int I think...)
if position is negative, or equal to std::string::npos then the range itFirst,itSecond is ill-defined (either because itSecond is before itFirst or because it is past str.end())
Correct your code, and check if it stills throw. Iterator Debugging is here to help you catch these mistakes, disabling it acting like an ostrich.