Thread: noob question about variables

  1. #1
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41

    noob question about variables

    What am I doing wrong here?
    Code:
    void calc_vector_sum() {
    	
    	string tmp, iqfile, outname;
    	int ny, nx;
    	float data;
    	iqmatrix iqsum;
    	
    	
    	ifstream file ("inputfile.txt");
    
    	if (file.is_open()) {
    
    		file >> outname;
    		file >> ny;
    		file >> nx;
    		
    		iqmatrix iqsum (ny,iqvector(nx));
    
    		while (file >> iqfile) {
    
    			add_data(iqfile, iqsum);
    
    		}
    
    		file.close();
    
    
    		cout << "iqsum.size() " << iqsum.size() << endl;
    		cout << "iqsum[0].size() " << iqsum[0].size() << endl;
    	}
    	else {
    		cout << "Could not open parameterfile" << endl;
    		exit(1);
    	}
    	
    	cout << "iqsum.size() " << iqsum.size() << endl;
    	cout << "iqsum[0].size() " << iqsum[0].size() << endl;
    
           return 0;
    }
    with these in the header
    Code:
    typedef complex<float> fcomplex;
    typedef vector<vector<fcomplex> > iqmatrix;
    typedef vector<fcomplex> iqvector;
    When I print out dimensions the first time it works, second time it doesnt. How should I do to access iqsum outside the IF. I tried make it global, but didnt work for me... Any idea?
    Cheers

  2. #2
    Registered User
    Join Date
    Feb 2009
    Posts
    138
    you declare iqsum twice. the one inside the if statement hides the one outside, and when execution leaves the if, you lose the iqsum you worked with and get the default initialized one. change iqmatrix iqsum (ny,iqvector(nx)); to iqsum = iqmatrix(ny,iqvector(nx));.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by larne
    How should I do to access iqsum outside the IF. I tried make it global, but didnt work for me... Any idea?
    The thing is that you declared a local variable named iqsum directly in the scope of the calc_vector_sum() function, and then declared another local variable named iqsum in the scope of the if statement. What you probably want to do is say, only create iqsum when you have read the values, e.g.,
    Code:
    void calc_vector_sum() {
        ifstream file("inputfile.txt");
        if (!file.is_open()) {
            cout << "Could not open parameterfile" << endl;
            exit(1);
        }
    
        string outname;
        int ny, nx;
        file >> outname >> ny >> nx;
    
        iqmatrix iqsum(ny, iqvector(nx));
    
        string iqfile;
        while (file >> iqfile) {
            add_data(iqfile, iqsum);
        }
    
        file.close();
    
        cout << "iqsum.size() " << iqsum.size() << endl;
        cout << "iqsum[0].size() " << iqsum[0].size() << endl;
    }
    You might want to check that the values have been read before using them. It might also be better to throw an exception instead of terminating the program immediately when you are unable to open the file.

    EDIT:
    You could use Meldreth's suggestion as well, but it is better to declare variables near first use, i.e., to postpone creating objects as long as feasible.

  4. #4
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41
    Thanks!

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Also, I suggest you think before using typedefs, since they can actually obfuscate code. They can be good, and they can be bad, so sometimes I'd like to think twice about using them.
    Just something to think on.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41
    above solution worked fine at work using vc++ 6.0, but at home using gcc it doesnt work. I get an error in the second line (iqsum):
    Code:
    			iqfile.read(reinterpret_cast < char * > (&data), sizeof(data));
    			iqsum[y][x].real(iqsum[y][x].real() + data);
    where iqsum is of type iqmatrix as stated in previous post.
    I get error: no matching function for call to `std::complex<float>::imag(float)' and after googling I still dont get it, once I had a similar issue with a zip header and I had to had to an L or two =) somewhere.
    Any clue?
    cheers

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You might want to post more code so that we have to guess less. Do your best to post the smallest and simplest program that demonstrates the error (i.e., you think that it should compile, but the compiler reports the error that you mentioned).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41
    Thanks for your reply. My header is:
    Code:
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <complex>
    
    using namespace std;
    
    typedef complex<float> fcomplex;
    typedef vector<vector<fcomplex> > iqmatrix;
    typedef vector<fcomplex> iqvector;
    
    
    //functions
    void calc_vector_sum();
    void add_data(string, iqmatrix &);
    void write_data(string, iqmatrix &);
    Function add_data is:
    Code:
    #include "average_phase.h"
    
    void add_data(string filename, iqmatrix &iqsum) {
    
    	// open iq file
    	ifstream iqfile (filename.c_str(), ios::in|ios::binary);
    
    	if (!iqfile.is_open()) {
    		cout << "Unable to open binary file" << endl;
    		exit(1);
    	}
    
    	// get dimensions of matrix
    	int ny = iqsum.size();
    	int nx = iqsum[0].size();
    	float data;
    	for (int y=0;y<ny;y++){
    		for (int x=0;x<nx;x++){
    
    			// add real part I
    			iqfile.read(reinterpret_cast < char * > (&data), sizeof(data));
    			iqsum[y][x].real(iqsum[y][x].real() + data);
    
    			// add imag part Q
    			iqfile.read(reinterpret_cast < char * > (&data), sizeof(data));
    			iqsum[y][x].imag(iqsum[y][x].imag() + data);
    
    		}
    	}
    	iqfile.close();
    
    
    }
    The add_data calling code is given in previous post, I hope the rest is irrelevant.
    Best regards

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Right. The problem is that you are calling the real() member function with a float argument, but std::complex's real() member function takes no arguments. To change the real part of the complex number object, you should assign a new complex object with the desired value. In fact, this implies that you should change both parts in one go, e.g.,
    Code:
    iqsum[y][x] = std::complex<float>(iqsum[y][x].real() + real_data, iqsum[y][x].imag() + imag_data);
    where real_data and imag_data replace your single data variable.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41
    Thanks again, you are the best!
    A little follow-up question, why do you put "std::complex<float>" in front of "iqsum" since it compiles without it. Should I always do that and do you agree with that I should avoid typedef commented previously?
    Kisses from Barcelona

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by larne
    why do you put "std::complex<float>" in front of "iqsum" since it compiles without it.
    Because you want to construct a std::complex<float> object with both the real and imaginary parts. If you leave that out, you get:
    Code:
    iqsum[y][x] = iqsum[y][x].real() + real_data, iqsum[y][x].imag() + imag_data;
    What happens here is that the expression on the left of the command is evaluated, then the expression on the right of the comma is evaluated, and that second expression's value is the result of the whole expression. Consequently, the code is effectively equivalent to:
    Code:
    iqsum[y][x] = iqsum[y][x].imag() + imag_data;
    which will set the complex number's real part to the computed imaginary part. That would certainly be a logic error.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41
    Does this mean that the previous code was erroneous or was it the VC++ 6.0 compiler that took care of these errors?
    Visualizing my resulting binary file it looked OK, although I'd have to check it thoroughly to be certain.
    Best Regards

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by larne
    Does this mean that the previous code was erroneous or was it the VC++ 6.0 compiler that took care of these errors?
    VC++ 6.0 is a pre-standard compiler, so it might not be up to date with the C++ standard in this area. It could also have been up to date, but provided a compiler extension that allowed you to change the complex number object via a non-standard real() member function that takes an argument.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Jul 2008
    Location
    Barcelona
    Posts
    41
    In your opinion I should change from vc++ 6.0 to Codeworks (or something else) using gcc at work? I know it's not the latest.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by larne
    In your opinion I should change from vc++ 6.0 to Codeworks (or something else) using gcc at work?
    I have no idea about "Codeworks", but if you want to stick with a Microsoft compiler, MSVC 7.1 onwards would be reasonably standards compliant. MSVC 8 is included in Visual Studio 2005, MSVC 9 in Visual Studio 2008. If not, a switch to a recent version of GCC is a good choice.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. question about some variables in my code
    By XodoX in forum C Programming
    Replies: 4
    Last Post: 02-03-2009, 06:29 PM
  2. Noob printf question
    By lolguy in forum C Programming
    Replies: 3
    Last Post: 12-14-2008, 08:08 PM
  3. Real Noob question
    By Dark Greek in forum C++ Programming
    Replies: 8
    Last Post: 09-09-2007, 06:49 PM
  4. super noob question
    By verbity in forum C++ Programming
    Replies: 6
    Last Post: 06-23-2007, 11:38 AM
  5. Noob question (redeclaring a array)
    By Demon.killer in forum C Programming
    Replies: 8
    Last Post: 10-21-2006, 12:06 PM