Invalid use of auto - c++

In this code:
for ( ;(auto i = std::find(some_string.begin(),some_string.end(),'%')) != some_string.end();)
{
}
I'm getting error from gcc 4.7.1:
error: invalid use of 'auto'|
any ideas why? shouldn't that be correctly compiled?

I think it has nothing to do with auto. You just cannot declare variables in random places, for example this will not compile either - an equivalent of what you were trying to do, but without auto:
int main() {
for ( ; (int i = 0) != 1; ++i)
;
return 0;
}

If this is in a loop, you'll only ever find the first '%'. You need to resume searching from i, not some_string.begin() to find subsequent '%'.
auto i = std::find(some_string.begin(), some_string.end(), '%'));
while (i != some_string.end()) {
// Your code here.
i = std::find(i, some_string.end(), '%')); // Find next '%'.
}

Related

g++ error: stray '\177' in program

I was trying to code for following program
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals [1,3],[6,9] insert and merge [2,5] would result in [1,5],[6,9].
Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] would result in [1,2],[3,10],[12,16].
This is the relevant part of my program
here. I want to erase the few positions from the vector
then I am getting the following error
error: stray '\177' in program
intervals.erase(intervals.begin()+(p+1),intervals.begin()+(q+1));
vector<Interval> Solution::insert(vector<Interval> &intervals, Interval newInterval) {
int n = intervals.size();
int p=-1,q=-1,a,b;
for(int i=0;i<n;++i){
if(intervals[i].start <= newInterval.start <= intervals[i+1].end)
p = i;
else if(intervals[i].end < newInterval.start < intervals[i+1].start)
a = i;
if(intervals[i].start <= newInterval.end <= intervals[i+1].end)
q = i;
else if(intervals[i].end < newInterval.end < intervals[i+1].start)
b = i;
}
int x,z;
if(p != -1 && q != -1)
x = q-p;
if(x > 0){
z=intervals[q].end;
intervals.erase(intervals.begin()+(p+1),intervals.begin()+(q+1));
intervals[p].end = z;
}
return vector
}
Did you copy that code from a website?
I managed to reproduce your result with this snippet:
const char* msg = "You can't copy this";
When copied and put on coliru here you'll get the same error code.
What I used for the above snippet in HTML code was:
<code>const char* msg = </code><code>"You can't copy this";
</code>
Note the  character I put in there.
To fix that, you can use a decent editor like Notepad++ that will make the stray characters visible:

Segmentation fault issue with isdigit

I have a function that will check if a string has any non-digit chars in it and returns a bool. But when I run it thru a debugger I get a segmentation fault.
Here is the function in question.
bool checkInt(string myString){
for (int i=0; i<myString.length; i++){
if (!isdigit(myString[i])){
return false;
};
return true;
}
I get the segfault on lines two and three on the for and if statements
if it helps here is the build log as well.
C:\Users\conner\Desktop\programing\for dummes\main.cpp: In function 'bool checkInt(std::string)':
C:\Users\conner\Desktop\programing\for dummes\main.cpp:78:30: error: invalid use of member function (did you forget the '()' ?)
C:\Users\conner\Desktop\programing\for dummes\main.cpp:84:1: warning: control reaches end of non-void function [-Wreturn-type]
A compiler error is not a "segfault". The error messages are telling you that there is a mistake in your source code, and the compiler can't finish compiling your program.
In your case, the error appears to be in the use of myString.length. This should be myString.length() because length is a member function and must be called (with ()).
i is being compared as greater than, not less than, in the for loop. This is causing access outside of the string buffer inside of myString[i] and a segmentation fault. Also, myString.length() should be used instead of myString.length. (As per manlio's comment).
Change to i < myString.length();
Your code misses a curly bracket. You should test whether i is less than myString.length, rather than greater. The semicolon after closing the if branch isn't needed.
bool checkInt(string myString)
{
for (int i=0; i < myString.length(); i++)
if(isdigit(myString[i]))
return false;
return true;
}
You got the segmentation fault because it seems you run an object module that was built with compilation errors. For example MS VC++ allows to do so.
Your function has a compilation error. Instead of correct syntax of calling member function length as
myString.length()
you wrote
myString.length
Also the condition in the loop statement is invalid
Instead of
for (int i=0; i>myString.length; i++){
there should be at least
for (int i=0; i < myString.length; i++){
The correct function could look as
bool checkInt( const string &myString )
{
string::size_type i = 0;
while ( i < myString.length() && isdigit( myString[i] ) ) ++i;
return ( i == myString.length() );
}
Also you could use standard algorithm std::all_of declared in header <algorithm>
For example
inline bool checkInt( const string &myString )
{
return std::all_of( myString.begin(), myString.end(),
[]( char c ) { return ::isdigit( c ); } );
}

Reversing for loop causing system errors

This feels like a newbie issue, but I can't seem to figure it out. I want to iterate over the items in a std::vector. Currently I use this loop:
for (unsigned int i = 0; i < buffer.size(); i++) {
myclass* var = buffer.at(i);
[...]
}
However, I realised that I actually want to iterate over it in the opposite order: starting at the end and working my way to 0. So I tried using this iterator:
for (unsigned int i = buffer.size()-1; i >= 0; i--) {
myclass* var = buffer.at(i);
[...]
}
But by simply replacing the old line with the new (and of course, recompiling), then it goes from running properly and iterating over the code, it instead causes the program to crash the first time it hits this line, with this error:
http://i43.tinypic.com/20sinlw.png
Followed by a "[Program] has stopped working" dialog box.
The program also returns exit code 3, according to Code::Blocks, which (if this article is to be believed) means ERROR_PATH_NOT_FOUND: The system cannot find the file specified.
Any advice? Am I just missing something in my for loop that's maybe causing some sort of memory issue? Is the return code of 3, or the article, misleading, and it doesn't actually mean "path not found"?
An unsigned integer is always >= 0. Furthermore, decrementing from 0 leaps to a large number.
When i == 0 (i.e. what should be the last iteration), the decrement i-- causes i to wrap around to the largest possible value for an unsigned int. Thus, the condition i >= 0 still holds, even though you'd like the loop to stop.
To fix this, you can try something like this, which maintains the original loop logic, but yields a decrementing i:
unsigned int i;
unsigned int size = buffer.size();
for (unsigned int j = 0; j < size; j++) {
i = size - j - 1;
Alternatively, since std::vector has rbegin and rend methods defined, you can use iterators:
for(typename std::vector<myclass *>::reverse_iterator i = buffer.rbegin(); i != rend(); ++i)
{
myclass* var = *i;
// ...
}
(There might be small syntactic errors - I don't have a compiler handy)
#include <vector>
using namespace std;
int main() {
vector<int> buffer = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (vector<int>::reverse_iterator it = buffer.rbegin(); it != buffer.rend(); it++) {
//do your stuff
}
return 0;
}

How can I fix an int-to-bool warning in C++?

I get a warning in MSVC++ when I try to read an integer from a file and make a bool variable equal it.
accessLV[i] = FileRead(file1, i + 1);
(accessLV is an array of bools, FileRead is a function I made to decrease the syntax involved in reading from a file, i is because the statement is within a for loop)
I've tried using a static_cast:
accessLV[i] = static_cast<bool>(FileRead(file1, i + 1));
But I still get the warning. I've tried doing this (I'm not sure the exact term):
accessLV[i] = (bool)FileRead(file1, i + 1));
And the warning is still there. Is there anyway to get rid of the warning without making accessLV an array of ints?
NB: this is the syntax of FileRead, if it helps:
int FileRead(std::fstream& file, int pos)
{
int data;
file.seekg(file.beg + pos * sizeof(int));
file.read(reinterpret_cast<char*>(&data), sizeof(data));
return data;
}
How about
accessLV[i] = FileRead(file1, i + 1) != 0;
What you want to do is basically
accessLV[i] = (FileRead(file1, i + 1) != 0)
accessLV[i] = FileRead(file1, i + 1) != 0;
Above, you were casting from int to bool: if you use this, the result of the comparison is put in accessLV[i], so not type warnings occur.
As other posters have suggested, !=0 is what you need. I prefer a wrapper like this because I find it more readable:
// myutil.hpp
template< typename T >
inline bool bool_cast( const T & t ) { return t != 0; }
Which you would use in this case like this:
// yourcode.cpp
accessLV[ i ] = bool_cast( FileRead( file1, i + 1 ) );
This related question has additional discussion you might find useful.

How should I correct this code that causes "value computed not used" warning?

I have an array of doubles and need to do a calculation on that array and then find the min and max value that results from that calculation. Here is basically what I have:
double * array;
double result;
double myMin;
double myMax;
// Assume array is initialized properly...
for (int i = 0; i < sizeOfArray; ++i) {
result = transmogrify(array[i]);
if (i == 0) {
myMin = result;
myMax = result;
}
else if (result < myMin) {
myMin = result;
}
else if (result > myMax) {
myMax = result;
}
}
I'm getting a warning that the value computed for result is never used, and since we treat all warnings as errors, this doesn't compile. How can I fix this code to avoid the warning? I'm using g++ for my compiler.
Here's the warning text:
cc1plus: warnings being treated as errors
foo.cc:<lineno of transmogrify call>: error: value computed is not used
Edit: I don't understand the down votes, but I've got things working now. Thanks to everyone for taking the time to help me out.
Assuming you don't need result outside of the loop, you could declare result inside the loop thusly:
for( int i=0; i < sizeOfArray; ++i ) {
double result = transmogrify( array[i] );
...
}
I'm getting a warning that the value computed for result is never used because (theoretically) it's possible that none of the if/else branches will be selected
That can't be the reason for the warning, because result is also used in the if conditions. Even if none of the branches are taken, result is still used to decide that they should not be taken.
Initialize myMin and myMax with DBL_MAX and DBL_MIN respectively and get rid of the first time through the loop check.
result = [...]
if (i == 0) {
[... do something with result ...]
}
else if (result < myMin) {
In both branches of the if(), result is used. In the 1st case it's assigned to a variable, in the 2nd it's used in a comparison. So the compiler shouldn't warn.
I suspect you might have misdiagnosed the problem. Please can you say exactly what the error message is (copy-paste it). Also, please try to post the smallest piece of code you can that actually compiles and gives the warning? (Simply trying to do that will probably let you find the problem)
EDIT: Is it possible that transmogrify() is a macro that uses result internally?
Before the "if" statement:
result = 0.0;
or some other value. It is always good form to set a variable to some value before using it.
I'm getting a warning that the value computed for result is never used because (theoretically) it's possible that none of the if/else branches will be selected, and since we treat all warnings as errors, this doesn't compile. How can I fix this code to avoid the warning? I'm using g++ for my compiler
The value used for result is always used. If not assigned it's used in the comparator. Therefore the compiler is faulty.
I don't think the code as posted should produce the error, unless the compiler is doing some phenomenal flow analysis. It certainly compiles OK with g++, but I'm not sure that g++ even supports the warning you are getting.
The following adaptation of your code, which preserves its structure, produces no error with g++:
int main() {
double * array;
double result;
double myMin;
double myMax;
double t(double);
// Assume array is initialized properly...
for (int i = 0; i < 10; ++i) {
result = t(array[i]);
if (i == 0) {
myMin = result;
myMax = result;
}
else if (result < myMin) {
myMin = result;
}
else if (result > myMax) {
myMax = result;
}
}
}
A quick solution might be to unroll the first iteration, like this:
double * array;
double result = transmogrify(array[0]);
double myMin = result;
double myMax = result;
int i;
for (i = 1; i < sizeOfArray; ++i) {
result = transmogrify(array[i]);
if (result < myMin) {
myMin = result;
}
if (result > myMax) {
myMax = result;
}
}
EDIT: I'll expand a bit on this. You haven't given any detailed information on sizeOfArray, but my guess is that it's a signed integer type.
I believe you've misunderstood the cause of the warning, result might be unused because sizeOfArray might be less than or equal to zero, not because of the if..else clauses inside the loop. In the code above, it might be a bit clearer why you need careful handling of the case (sizeOfArray <= 0), but it's equally important in the original code snippet as well.
Removing the first else only impacts the running time of the first run through the loop. I'd eliminate it rather.
if (i == 0) {
myMin = result;
myMax = result;
}
if (result < myMin)
myMin = result;
else if (result > myMax)
myMax = result;