Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 316
  • Last Modified:

IstringStream Problems

Basically, I'm trying to take a string, switching it to integers and printing it out.. But for some reason, no matter what char it finds, it gives it the same value..

code:

#include <iostream> // For COUT
#include <string> // Strings
#include <sstream> // StringStreams
#include <iomanip>

using namespace std;

int main() {
      string name;
      cout << "Enter your name: ";
      getline(cin, name);
      int count = name.length();
      string split;
      int intcode;
      for (int j=0; j <= count; j++) {
            split = name.substr(0, j+1);
            istringstream toint(split);
            toint >> intcode;
      cout << intcode;
      ostringstream tostr(intcode);
      string code;
      tostr << setprecision(15) << code;
      cout << code;
      }
  return 0; // End
}

end code:

thanks alot,

Rob
0
masta_mind
Asked:
masta_mind
1 Solution
 
n_fortynineCommented:
A quick test I can think of...

string num, test;
int i;
istringstream strm(num);
strm >> i;
stringstream buff;
buff << i;
buff >> test;
if(test != num) cout << "num is not an legal integer\n";
else cout << "num is a legal integer\n";
0
 
efnCommented:
If the characters you feed the program can't be converted to an integer, the line

toint >> intcode;

is not going to change intcode, so it will always contain the same thing (uninitialized garbage).

When I fed digits to the program, it behaved reasonably according to the code.  When I entered "123", it put out 112123123, which makes sense the way the loop is coded.

It doesn't make sense to initialize tostr with intcode.  The constructor will take this as a bunch of flags, which is probably not what you want.

The string named "code" is constructed empty by default and never gets any content, so it doesn't do anything useful to put it into either cout or tostr.

--efn
0
 
SteHCommented:
         split = name.substr(0, j+1);
puts the first j elements in the substr. Intcode gives the integer of the first element in the substring which stays the first element of the name. Did you ment
         split = name.substr (j,j+1); ?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
masta_mindAuthor Commented:
SteH::  Ya, I noticed that, I was thinking that might be the problem, but it wasn't.

efn:: Ya, I see what you mean.  So I came up with this:

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

using namespace std;

int main() {
      string name;
      cout << "Enter your name: ";
      getline(cin, name);
      int count = name.length();
      string split;
      int intcode;
      for (int j=0; j <= count; j++) {
            split = name.substr(j, j+1);
            istringstream toint(split);
            int intcode = toint.get(); // NEW LINE
      cout << intcode;
      }
  return 0; // End
}

So I changed it to toint.get.. but my question now is how to use setprecision.  I'm not sure, I have tried a few different combos and none seem to work
0
 
masta_mindAuthor Commented:
Well, the more I read up on setprecision, it looks as though it doesn't *seem* to change things to the left of the decimal.  So is there any better way cause i want it no matter what name you have the same length of numbers, and I also want to get rid of the -1 after everything.
0
 
efnCommented:
Sorry, I can't tell what you are trying to do here.  Perhaps it would help if you showed some input strings and the integers you would like the program to get from those inputs.

--efn
0
 
masta_mindAuthor Commented:
Well when I enter my name:

Rob Shaw .. it outputs::

8211198328310497119-1

I am not sure what the -1 means..

And if I enter like RS::

8283-1

So basically, I want to set it so they all have the same length.. is this possible at all?
0
 
masta_mindAuthor Commented:
I know that each integer is basically one or two numbers so if I enter R it equals 82 and so forth, but I am wondering what other way I could get the same length..
0
 
masta_mindAuthor Commented:
I also put it in a menu program and am having a hard time getting it to display outside the for statement...

#include <iostream>
#include <algorithm>
#include <string>
#include <stdio>
#include <sstream>
#include <iomanip>

using namespace std;

      int menu(); // Menu Function
       void Validate(); // Program
       void Keygen(); // Program

int main() {
      bool exit = false;
      for (;;) {
        int choice = menu();
        switch(choice) {
            case (1):
              Validate(); //
              break;
            case (2):
              Keygen();
              break;
            case (3):
              exit=true;
              break;
            default:
              cout << "Please select again!\n";
              system("PAUSE");
              break;
            }
      if (exit)
            break;
      }      
}

int menu() {
               int choice;
            system("CLS");
            cin.clear(); // clear all previous cin's
            cout << "*******************************" << "\n"
               << "*             Menu            *" << "\n"
               << "*******************************" << "\n\n";
                  cout << "(1) Validator.\n";
                  cout << "(2) Key Generator.\n";
                  cout << "(3) Quit. \n\n";
                  cout << "Enter Choice --> ";
                  cin >> choice;
                  cout << "\n";
                  return choice;
}

int length(string name) {
      int x = name.length();
      return x;
}

int split(string name) {
         string split;
     int count = length(name);
     int intcode;
     for (int j=0; j <= count; j++) {
          split = name.substr(j, j+1);
          istringstream toint(split);
          intcode = toint.get();
              intcode = intcode;
            }
            return intcode; // outside the for loop i get -1, and inside i get the int for the first letter of string name..
}
// *** //
void Keygen() {
            string name, blank; // declare the strings
      getline (cin, blank);
      cout << "Please Type In Your Name: ";
      getline (cin, name);
      cout << "Key: " << split(name) << endl;
      system("PAUSE");
}
// *** //
void Validate() {
            string name, blank; // declare the strings
            int key;
      getline (cin, blank);
      cout << "Please Type In Your Name: ";
      getline (cin, name);
      cout << "\nPlease Enter The KeyGen: ";
      cin >> key;
      if (key == split(name)) cout << "Valid Keygen!" << endl;
      else cout << "Invalid." << endl;
      system("PAUSE");
}



// outside the for loop i get -1, and inside i get the int for the first letter of string name..
0
 
masta_mindAuthor Commented:
Also don't worry, this key-generator is for a school project soo nothing illegal.. ;)
0
 
efnCommented:
OK, I can explain the -1.  Let's take the case where you enter "RS".  Then name == "RS" and count == 2.

The first time through the loop, j == 0 and split == "R".  So intcode gets the numeric value of 'R'.

The second time through the loop, j == 1 and split == "S", so intcode gets the numeric value of 'S'.

After the second time through the loop, j is incremented to 2 and j <= count is still true, so the loop runs a third time.  There are only two characters in name, with indexes 0 and 1, so name.substr(2, 3) returns an empty string.  So split is an empty string.  So toint has no character in its buffer.  So toint.get() returns the EOF (end of file) code, which is -1.

As you may have figured out by now, when there are two characters, you only want to run the loop two times, but the test j <= count makes it run three times.

The second parameter to substr is a length, so name.substr(j, j + 1) doesn't make sense.  In the example above, the second time through the loop, it would be getting name.substr(1, 2), but 2 is the length and there are not 2 characters available at position 1.

You can get the numeric value of character j of name much more simply, like this:

int intcode = name[j];

You don't need the stringstream.

I don't understand what you mean by all having the same length.  If you can explain more, I may be able to advise you.

--efn
0
 
masta_mindAuthor Commented:
Well, the whole reason for the program is to have a key-generator so if someone in class wants to log-in they have a special keygen to login as.  So basically, I want every output to be let's say 7 numbers long so if I enter::

Rob Shaw  --> (i get)  123-4567
RS --> 345-1234

Not necessarily those numbers but the same numeric length.
0
 
efnCommented:
OK, it looks like you want to define a mapping from strings to k-digit numbers where k is a constant.  To do that, you need an algorithm, a precise method.  What's your algorithm?

--efn
0
 
masta_mindAuthor Commented:
I have no idea.. I'm still really new to C++ so...

I figured you might be able to do something like test for different string lengths and ****.. or maybe at least have it test if less then 5 chars then it says invalid input.  [since i don't know algorithms too well]
0
 
masta_mindAuthor Commented:
The only other problem I seem to be having is inside my menu program, trying to get it to return the code, because I can't get it to work outside the for statement..
0
 
efnCommented:
For a simple approach, you could just add up all the characters:

     int intcode = 0;
     for (int j=0; j < count; j++) {
          intcode += name[j];
          }

If you want to avoid negative numbers, you can use unsigned integers.

The code you have now sets intcode to the value of each character successively, ending with the -1 EOF character.  So each assignment to intcode wipes out any previously assigned value.

When you read it in, you can check the length of the string read.  That would mean that if the name were short, the number might have to be entered with leading zeros.

--efn
0
 
masta_mindAuthor Commented:
Ahh thank you!
0
 
masta_mindAuthor Commented:
I dunno if you can also look up at my for statement to return intcode in my void Keygen thing and tell me how I can get it out of there to return it..


Thanks..
0
 
masta_mindAuthor Commented:
My new menu code is:


#include <iostream>   // for cout function
#include <string>        // for string related stuff

using namespace std;

      int menu();         // declare menu function
       void Validate();   // declare validator function
       void Keygen();     // declare keygenerator function

int main() {
      bool exit = false;
      for (;;) {
        int choice = menu();
        switch(choice) {
            case (1):
              Validate();
              break;
            case (2):
              Keygen();
              break;
            case (3):
              exit=true;
              break;
            default:
              cout << "Please select again!\n";
              system("PAUSE");
              break;
            }
      if (exit)
            break;
      }      
}

int menu() {
               int choice;
            system("CLS");
            cin.clear();
            cout << "*******************************" << "\n"
               << "*             Menu            *" << "\n"
               << "*******************************" << "\n\n";
                  cout << "(1) Validator.\n";
                  cout << "(2) Key Generator.\n";
                  cout << "(3) Quit. \n\n";
                  cout << "Enter Choice --> ";
                  cin >> choice;
                  cout << "\n";
                  return choice;
}

int length(string name) {
      int x = name.length();
      return x;
}

int split(string name) {
         string split;
     int count = length(name);
     int intcode;
     for (int j=0; j<count; j++) {
              split = name.substr(j, count-j);
          intcode = name[j];
       }
             return intcode;
}

void Keygen() {
 string name, blank; // declare the strings
      getline(cin, blank);
      cout << "Please Type In Your Name: ";
      getline(cin, name);
      if (length(name) < 5) {
             cout << "Invalid Input.." << endl;
      } else {  // if length >= 5
             cout << "Key: " << split(name) << endl;
      }
 system("PAUSE");
}

void Validate() {
 string name, blank; // declare the strings
            int key;
      getline(cin, blank);
      cout << "Please Type In Your Name: ";
      getline(cin, name);
      if (length(name) < 5) {
             cout << "Invalid Input.." << endl;
      } else {  // if length >= 5
      cout << "\nPlease Enter The KeyGen: ";
      cin >> key;
      if (key == split(name)) cout << "Valid Keygen!" << endl;
      else cout << "Invalid." << endl;
      }
 system("PAUSE");
}
0
 
efnCommented:
Sorry, I don't understand your last question.
0
 
masta_mindAuthor Commented:
Well, when I enter a name after selecting keygenerator in my menu program there, it returns :: 119 instead of the actual number...

Basically because I put it outside the for statement,but if I put it in, I get an even weirder number..

0
 
efnCommented:
This is your loop for calculating intcode:

     for (int j=0; j<count; j++) {
            split = name.substr(j, count-j);
          intcode = name[j];
      }

name is a string.  name[j] is a character.  Each iteration of the loop assigns a different character to intcode, wiping out whatever was there before.  At the end of the loop, intcode will contain the numeric value of the last character in the string.  You could do the same thing in one statement without a loop:

intcode = name[name.length() - 1];

Presumably you have a loop because you want each character of the name to have some effect on the integer in which it is encoded.  Just assigning each character to the integer won't do that.  I suggested one way to do it in a previous comment.  Bear in mind, though, that if you use that algorithm, you may get what you consider a weird number.

--efn
0
 
masta_mindAuthor Commented:
Ahh.. Alright, so I can can use algorithms better to get to my answer.  Thanks alot..


lol about the weird number part.. The only reason I called it a weird number was because whatever name I would enter, I would get [123] <--always and [xxx] for the rest..
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now