This question already has answers here:
How do I tokenize a string in C++?
(37 answers)
Closed 10 years ago.
I have this code currently in which the user would enter a number for how many numbers they want in the array. followed by '12345' however about a second after writing it i realized this would only work if they entered number 0-9 anything in double figures or more wouldnt work.
int numberOfValues;
cout << "Please enter the amount of integers you want in the array" << endl;
cin >> numberOfValues;
int valuesArray[numberOfValues];
string valuesString;
cout << "Please Enter " << numberOfValues << " numbers" << endl;
cin>>valuesString;
for(int i = 0; i < numberOfValues; i++)
{
valuesArray[i] = valuesString[i];
}
return valuesArray;
im thinking that the best way to do this would be for the user to enter numbers separated by a comma and to split them afterwards (iv done this same little porgram in java and trying to change it to C++ for my own personal learning) like in java i used string.split(",") i was wondering if there is anything similar in c++??
The simplest way I can think of would be to avoid reading to an intermediate string and let cin do the work for you:
std::vector<int> valuesArray;
int i = 0;
do {
cin >> i;
valuesArray.push_back(i);
} while (valuesArray.size() < numberOfValues && cin.get() == ',');
/* edit: You may need to consume a '\n', if you expect one, too: */
do {
i = cin.get();
} while (i != '\n');
Use strtok. Documentation and example can be found Here
use combination of string::substr() and string::find().
Find the next comma charater and then find the substring from current location to next command character
It is not standard C++ string, but still, Qt's QString class provides a ready-to-use method QString::split(...) with support for stuff like regular expressions, options for split behavior, case sensitivity and whatnot...
I wrote a tokenizer time ago, hope it works for you:
std::vector<std::string> tokenize(const std::string &_line,const char *_delimeter)
{
std::vector<std::string> Tokens;
if(_line.empty()) return Tokens;
std::string str;
BOOST_FOREACH(char c,_line){
if(c==*_delimeter)
{
Tokens.push_back(str);
str.clear();
continue;
}
str += c;
}
if(!str.empty())
Tokens.push_back(str);
return Tokens;
}
it is not efficient, but works for testing purpose.
Related
This question already has answers here:
Case-insensitive string comparison in C++ [closed]
(30 answers)
Closed 5 years ago.
How do you accept case-insensitive and allow embedded blanks in a user input? So the user can enter “hong konG” and get a correct match to the input.
I only have the input[0] = toupper(input[0]); which only accepts if the case sensitive is at the beginning of the word.
while(true){
cout << "Enter a city by name: "<< " ";
std::getline (std::cin,input);
if (input == "quit")
{
break;
}
input[0] = toupper (input[0]);
//....how do I loop to find all letter's in the input string variable?
}
You can use a loop to convert the entire string to upper case one character at a time, but a better solution is to use C++ standard library's transform function for that:
std::string hk = "hong konG";
std::transform(hk.begin(), hk.end(), hk.begin(), ::toupper);
This would apply ::toupper to all characters of your string, resulting in a string that reads "HONG KONG".
Demo on ideone.
for (auto& c : str)
c = std::toupper(c)
You can convert the whole string to upper-case like this
for (size_t i = 0; i < input.size(); ++i)
input[i] = toupper (input[i]);
The other suggestion to use std::transform is also a perfectly good solution.
This may be a total beginner's question, but I have yet to find an answer that works for me.
Currently, I'm writing a program for a class that takes in a user's input (which can be one or more numbers separated by spaces), then determines whether the number is prime, perfect, or neither. If the number is perfect, then it will display the divisors.
Thus far, I've already written the code for the prime, perfect, and listing the divisors. I'm stuck on the input portion of my program. I don't know how to get the input that's separated by spaces to go through my loops one at a time.
This is my current program:
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin>>num;
while (divisor<=num)
if(num%divisor==0)
{
cout<<divisor<<endl;
total=total+divisor;
divisor++;
}
else divisor++;
if(total==num*2)
cout<<"The number you entered is perfect!"<<endl;
else cout<<"The number you entered is not perfect!"<<endl;
if(num==2||num==3||num==5||num==7)
cout<<"The number you entered is prime!"<<endl;
else if(num%2==0||num%3==0||num%5==0||num%7==0)
cout<<"The number you entered is not prime!"<<endl;
else cout<<"The number you entered is prime!"<<endl;
return 0;
It works, but only for a single number. If anyone could help me to get it to be able to read multiple inputs separated by spaces, it'd be greatly appreciated. Also, just a side note, I do not know how many numbers will be entered, so I can't just make a variable for each one. It will be a random amount of numbers.
Thanks!
By default, cin reads from the input discarding any spaces. So, all you have to do is to use a do while loop to read the input more than one time:
do {
cout<<"Enter a number, or numbers separated by a space, between 1 and 1000."<<endl;
cin >> num;
// reset your variables
// your function stuff (calculations)
}
while (true); // or some condition
I would recommend reading in the line into a string, then splitting it based on the spaces. For this, you can use the getline(...) function. The trick is having a dynamic sized data structure to hold the strings once it's split. Probably the easiest to use would be a vector.
#include <string>
#include <vector>
...
string rawInput;
vector<String> numbers;
while( getline( cin, rawInput, ' ' ) )
{
numbers.push_back(rawInput);
}
So say the input looks like this:
Enter a number, or numbers separated by a space, between 1 and 1000.
10 5 20 1 200 7
You will now have a vector, numbers, that contains the elements: {"10","5","20","1","200","7"}.
Note that these are still strings, so not useful in arithmetic. To convert them to integers, we use a combination of the STL function, atoi(...), and because atoi requires a c-string instead of a c++ style string, we use the string class' c_str() member function.
while(!numbers.empty())
{
string temp = numbers.pop_back();//removes the last element from the string
num = atoi( temp.c_str() ); //re-used your 'num' variable from your code
...//do stuff
}
Now there's some problems with this code. Yes, it runs, but it is kind of clunky, and it puts the numbers out in reverse order. Lets re-write it so that it is a little more compact:
#include <string>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
There's still lots of room for improvement with error handling (right now if you enter a non-number the program will crash), and there's infinitely more ways to actually handle the input to get it in a usable number form (the joys of programming!), but that should give you a comprehensive start. :)
Note: I had the reference pages as links, but I cannot post more than two since I have less than 15 posts :/
Edit:
I was a little bit wrong about the atoi behavior; I confused it with Java's string->Integer conversions which throw a Not-A-Number exception when given a string that isn't a number, and then crashes the program if the exception isn't handled. atoi(), on the other hand, returns 0, which is not as helpful because what if 0 is the number they entered? Let's make use of the isdigit(...) function. An important thing to note here is that c++ style strings can be accessed like an array, meaning rawInput[0] is the first character in the string all the way up to rawInput[length - 1].
#include <string>
#include <ctype.h>
...
string rawInput;
cout << "Enter a number, or numbers separated by a space, between 1 and 1000." << endl;
while( getline( cin, rawInput, ' ') )
{
bool isNum = true;
for(int i = 0; i < rawInput.length() && isNum; ++i)
{
isNum = isdigit( rawInput[i]);
}
if(isNum)
{
num = atoi( rawInput.c_str() );
...//do your stuff
}
else
cout << rawInput << " is not a number!" << endl;
}
The boolean (true/false or 1/0 respectively) is used as a flag for the for-loop, which steps through each character in the string and checks to see if it is a 0-9 digit. If any character in the string is not a digit, the loop will break during it's next execution when it gets to the condition "&& isNum" (assuming you've covered loops already). Then after the loop, isNum is used to determine whether to do your stuff, or to print the error message.
You'll want to:
Read in an entire line from the console
Tokenize the line, splitting along spaces.
Place those split pieces into an array or list
Step through that array/list, performing your prime/perfect/etc tests.
What has your class covered along these lines so far?
int main() {
int sum = 0;
cout << "enter number" << endl;
int i = 0;
while (true) {
cin >> i;
sum += i;
//cout << i << endl;
if (cin.peek() == '\n') {
break;
}
}
cout << "result: " << sum << endl;
return 0;
}
I think this code works, you may enter any int numbers and spaces, it will calculate the sum of input ints
std::vector<int> num{};
int buf;
do{
std::cin >> buf;
num.push_back(buf);
}while(std::cin.peek() == ' ');
In C language you can to it using scanf like this:
scanf('%d %d',&a,&b);
How would I split an inputted string such as "one two three four five" into an array.
currentyly I have this:
const int SIZE = 5;
string digit[SIZE];
cout << "Enter the five here:";
for(int i = 0; i < SIZE; i++)
{
cout << i+1 << ")";
getline(cin, digit[i]);
}
but as it stands, the user has to hit enter every time. How do I get it so when I call digit[1] for the example input above, I get two. Hopefully that makes sense, I would imagine there is some function to do this for you, but if there is really elementary way of doing it, that would probably benefit me best, I'm still learning. thx
If you want to read words separated by whitespace, you can take advantage of the fact that extracting a string from an input stream will stop at whitespace:
for(int i = 0; i < SIZE; i++)
{
cout << i+1 << ")";
cin >> digit[i];
}
well if you want to take all the 'five' in a single line you can do that also.
and then you can use strtok() to split the string into five strings.
see: http://www.cplusplus.com/reference/clibrary/cstring/strtok/
You also may use getline function with 3 arguments. 3rd is delimiter.
getline(cin, digit[i], ' ');
Of course, it isn't best way to read input from cin. But you can use such approach for splitting full string, which you've get from user.
Hi guys i am new to c++, I just wrote this code to find min/max of a array of numbers.
I just want to know how can I make the no. of entries flexible(I mean the user should be able to enter as many entries as possible without specifying how many in the starting)
Here's the code, but its not working, can someone please help?
Thanks
code:
#include <iostream>
using namespace std;
int main(){
cout<<"Program to calculate max/min/second max\n";
int *A;
A=new int[5];
bool flag=false;
int x=0,i=0;
cout<<"Enter the numbers\n";
do{
cin>>x;
if(x=='\0'){
flag=true;
}
*(A+i)=x;
i++;
}
while(!flag);
for(int j=0;j<i;j++){
cout<<*(A+j)<<"\n";
}
return 0;
}
You are confused that pressing enter will just give you the null terminator. It will not. Depending on your platform it will give you a carriage return/line-feed (\r\n in Win, \n in *ix). The best way to do this is to just have them use a letter like 'q' for quit or a number like -1, and then compare on that.
Dynamic Memory Allocation is a bit of a tricky subject for a beginning programmer (in C and C++ in any case.) The easiest way is to have the user specify how many entries, but you don't want this.
Otherwise using the vector class over an array is probably a better (and easier to grapple with than directly using pointers.)
http://www.cplusplus.com/reference/stl/vector/ is a good place to start. Look at the syntax for creating the vector and the push_back() member function to accomplish your task.
Good Luck,
SegFaults McGee
You will have to use some sort of variable length datastructure and Vector is the best choice for this since you are working in C++. Therefore, instead of your fixed length array:
int *A;
A=new int[5];
use a vector like this:
std::vector<int> input;
And then to add values to this, use the following:
input.push_back(10);
There is an example on this page about using vectors.
mean the user should be able to enter as many entries as possible without specifying how many in the starting
With the above requirement and with the code you have, you can enter no more than 5 elements to an array.
do{
cin>>x;
if(x=='\0'){
flag=true;
}
*(A+i)=x;
i++;
}while(!flag);
Use std::vector instead for the requirement where it implicitly manages memory for you.
If you use
std::vector<int> a;
then the input becomes simply
while (std::cin >> x)
a.push_back(x);
Then the user can press ^D (Unix/Linux/etc) or ^Z (DOS/Win) when they've entered all the numbers, or use the program as in:
echo 1 4 22 | program
program < input_file
If you want to have an empty line denote the end of input, then with input validation:
std::string line;
while (getline(std::cin, line))
{
char c;
std::istringstream iss(line);
int x;
if (iss >> x)
{
a.push_back(x);
char c;
if (iss >> c)
{
std::cerr << "unexpected character '" << c << "' in line '" << line << "', terminating\n";
exit(EXIT_FAILURE);
}
}
else if (!iss.eof())
break; // empty line...
else
{
std::cerr << "unexpected characters in line '" << line << "', terminating\n";
exit(EXIT_FAILURE);
}
}
First off, this is a "homework" question so vector libraries and string libraries are off limits. I'm trying to get to the basics of c++.
My intention with this code is to make and use an array of string arrays. A list of words in other words.
When I run this code I get a bunch of nonsense.
If there is a better way to make a list of words in c++, I would love to hear about it.
const int cart_length = 50;
const int word_length = 50;
int main()
{
char cart_of_names[cart_length][word_length];
float cart_of_costs[cart_length];
char name[word_length];
cout << "enter the name of the first item: ";
cin >> name;
for(int i=0; i<word_length; i++)
{
cart_of_names[0][i] = name[i];
}
cout << endl;
cout << "that is: ";
for(int x=0; x<word_length; x++)
{
cout << cart_of_names[0][x];
}
cout << endl;
return 0;
}
If the string entered is not 50 characters long (cart_length), then less than 50 characters will be valid in the name. You should have an if(cart_of_names[0][x]==0) break; in your second loop.
I don't exactly understand what you are looking for. Following code will help you to read and print a list of 50 words. Hope this would help you.
const int cart_length = 50;
const int word_length = 50;
int main()
{
char cart_of_names[cart_length][word_length];
float cart_of_costs[cart_length];
for(int i=0; i<cart_length; i++)
{
cout << "enter the name of the " << i + 1 << "th item: ";
cin >> cart_of_names[i];
}
cout << "that is: ";
for(int x=0; x < cart_length; x++)
{
cout << cart_of_names[x] << endl;
}
return 0;
}
Check out STLSoft's fixed_array_2d (and it's higher order siblings). There's a detailed discussion of how they're implemented for maximum performance in Matthew Wilson's Imperfect C++.
If you can't use std::string, at least look at the functions like strncpy() from C for your name copying. Also, you're forgetting that c-style strings are null terminated.
Unless you're forbidden to use STL (which would be just mean), just use std::list<std::string>. www.cplusplus.com has detailed descriptions and examples for those classes.
Otherwise, you're stuck with an array of char arrays: in that case, be prepared for a lot of buffer overflow errors. Look around on the above site for the char[] management functions (strncpy() and the like), they'll make your life a bit easier (but not a lot).
In C, the best way I found to conceptualize what you are trying to do is using an array of char*. Same effect, but if you start to work with it I believe you may find it is easier on the brain.
It looks pretty close to me. Strings in C are null-terminated, which means that the end of the string is indicated by a null character. In a sense, a string in C is really just an array of bytes.
When you do:
cout << "enter the name of the first item: ";
cin >> name;
If I enter the string "Book", in memory it'll look like something like:
|0|1|2|3|4|5..49|
|B|o|o|k|0|*HERE BE DRAGONS*
Well, really it will contain the ASCII values corresponding to those letters, but for our purposes, it contains those letters. There here be dragons is memory that that you didn't initialize, so it contains whatever garbage your platform sets it to.
So when you copy your string, you need to instead look for that 0 byte at the end of the string.
for(int i=0; name[i]!=0; i++)
{
cart_of_names[0][i] = name[i];
}
Then when you output it, you don't actually need to do it a character at a time. You can just do cout<<cart_of_names[0]. cout knows where the string ends because of that terminating null character.
If you use strcpy() instead of
cart_of_names[0][i] = name[i];
it may work better but I cringe just looking at all that code.
"If there is a better way to make a list of words in c++, I would love to hear about it."
Include #include <string> and use std::string. The std::string type is part of the C++ specification, I think.
#include <iostream>
#include <string>
int main(void) {
std::string list[7];
list[0] = "In C++";
list[1] = "you can use";
list[2] = "the `std::string` type.";
list[3] = "It removes";
list[4] = "many of the problems";
list[5] = "introduced by";
list[6] = "C-style strings.";
for (int k=0; k<7; k++) std::cout << list[k] << ' ';
std::cout << '\n';
return 0;
}