1

I want to declare two types of variables in for's init-statement. like the following codes. I know "for (string word, int numb, ; cin>>word>>numb; )" is not working. just trying to let you know what I am trying to do. My goal is to declare two types of variables with the same lifetime and cin them together. Other way of coding is helpful too. thanks in advance.

#include <iostream>
#include <vector>
#include <string>
#include <utility>
using namespace std;
int main ()
{
    cout<<"enter a word and a number"<<endl;
    for (string word, int numb, ; cin>>word>>numb; )
    {
        //do some work      
    }
return 0;
}

ok, I think this is the closest I can get as someone suggested.

#include <iostream>
#include <vector>
#include <string>
#include <utility>
using namespace std;
int main ()
{
    vector<pair<string,int> > pvec;
    cout<<"enter a word and a number"<<endl;
    {
        int numb=0; 
        for (string word; cin>>word>>numb; )
            pvec.push_back(make_pair(word,numb));
    }
    cout<<pvec[3].second<<endl;
return 0;
} 
8
  • what isn't working? is it failing to compile? Is it compiling but giving incorrect results? Commented Nov 11, 2011 at 21:14
  • for (string word, int numb, ; cin>>word>>numb; ) this statement. because "string" wants to declara int as a variable too. Commented Nov 11, 2011 at 21:17
  • 1
    In future posts please post complete, minimal sample programs. While your program is minimal, it is not complete. Why make all of us re-type the three missing header lines, instead of posting it yourself? See sscce.org for more information about complete, minimal sample programs. Commented Nov 11, 2011 at 21:18
  • @Rob: Generally, I agree. In this instance, it's fairly clear (at least to me) that the above code is syntactically invalid, and the OP wants to know if such a thing is possible. Commented Nov 11, 2011 at 21:19
  • Thanks, @OliCharlesworth. Even in this case, I was curious to see the exact error message -- which required more than a simple copy, paste, compile on my part. Commented Nov 11, 2011 at 21:21

6 Answers 6

6

About the nearest you can get is:

int main ()
{
    cout<<"enter a word and a number"<<endl;
    {
        string word;
        for (int numb; cin>>word>>numb; )
        {
            //do some work      
        }
    }
    return 0;
}

The extra set of braces limits the scope of word similarly to the way the loop limits the scope of numb. Clearly, you could reverse the declarations; it might be better (more symmetric) to use:

int main ()
{
    cout<<"enter a word and a number"<<endl;
    {
        string word;
        int numb;
        while (cin>>word>>numb)
        {
            //do some work      
        }
    }
    return 0;
}

Since there is no increment or initialize operation, the code is really a while loop with a couple of declared variables; this achieves the same result and works.

Sign up to request clarification or add additional context in comments.

1 Comment

great. I think it's the closest one. it doesn't look clean, kinda bulky though. (not trying to be an @ss). just saying
6

This is not possible. You can declare two variables of the same basic type in the initialization statement in the for loop, but you cannot declare two variables of different basic types. You have to declare one outside of the for loop.

7 Comments

Actually he can declare a struct containing both of those variables
He could, but is there really a reason to create a struct for two items that have nothing to do with each other? The right answer here is not to use a for loop, not to encourage questionable programming practice as a workaround to syntax.
That's declaring one variable of one type. Also, I find that notion offensive to the senses. If I ever saw a struct defined inside a for-loop initialization block in a code review, I would read the person who did it the riot act.
This is incorrect. for (int a, *b, &c;... has 3 different types.
A rather classic use of struct (i.e. combining several variables together) if there ever was one. Personally I probably wouldn't do it, but I wouldn't complain either.
|
3

I'm fairly certain it's not possible to declare 2 variables of 2 different types in a for statement, but I also fail to see the advantage to doing so over something like this:

int main ()
{
    cout<<"enter a word and a number"<<endl;
    while( cin.good() )
    {
        string word;
        int num;

        cin >> word >> num;
        //do some work      
    }
    return 0;
}

In general I prefer to use for loops where there is something to count or at least iterate over. Other situations should be using a while or do loop.

4 Comments

Your check is in the wrong place -- or you must have another. Your current code doesn't check whether the read operation was successful or not (and it's a good idiom to use stream operations as a condition).
It gets the idea across, I would claim. Especially as the OP asked about declaration syntax, not stream usage.
yes, this one works. but it doesn't look as clean as for loop. and this takes a lot space.
"Space taken" is a pretty awful measure for code readability, and has 0 to do with efficiency.
2

The way you are trying to do it is not the cleanest way. I'd do it like this:

string word;
int num;
while(true)
{
    cin >> word >> num;
    if (!cin.good()) break;
    // do some work
}

word and num are in the same scope (same "lifetime")

Note that you'd want to substitute the while(true) with some suitable condition.


If you want word and num to be inside the scope of the loop do something like:

while(true)
{
    string word;
    int num;
    cin >> word >> num;
    if (!cin.good()) break;
    // do some work
}

OR

{
    string word;
    int num;
    while(true)
    {
        cin >> word >> num;
        if (!cin.good()) break;
        // do some work
    }
}

I don't know why this would be necessary though.

8 Comments

yes, this works, but word and num still exist after the while loop is over
If the OP's syntax were valid, it would arguably be cleaner; it would limit the scope of the variables to the loop.
Then put them inside the scope of the loop. See my edit. Its stack allocation anyways.
Now that's just stupid, refactoring a good test (i.e. stream operation's successfulness) out of the loop condition, and not testing the status of the stream at all.
@OliCharlesworth yes, I want to make it cleaner and easy to move around.
|
1

The following is untested, but should work:

int main()
{
  std::cout << "enter a word and a number" << endl;
  for (struct { std::string word, int number } vars;
       std::cin >> vars.word >> vars.number;
      )
  {
    //do some work      
  }
  return 0;
}

2 Comments

At least on VS 2010 it does not work. Although a quick look at the C++ grammar says it should be allowed, so maybe it's a bug in VS. edit: g++ allows it.
Link to microsoft connect bug on this issue: connect.microsoft.com/VisualStudio/feedback/details/624410/…
0

Since c++17:

#include <iostream>
#include <tuple>

int main() {
    for (auto && [w,i] =  std::tuple{std::string{},int{}} ; std::cin >> w >> i ; )
        std::cout << "word " << w << " number " << i << "\n";
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.