Program 1: Program 1 takes a line of input from the console and divides the input string into sub strings separated by space and then converts into integer value.
#include <cstring>
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
char *input;
cin.getline(input,100);
char *token = strtok(input, " ");
while (token != NULL)
{
cout << token << '\n';
token = strtok(NULL, " ");
}
return 0;
}
Program 2:
#include <cstring>
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
char *input;
cin.getline(input,100);
int a[7];
char *token = strtok(input, " ");
while (token != NULL)
{
cout << token << '\n';
token = strtok(NULL, " ");
}
return 0;
}
Program 1 works fine but programs does not work. The only difference between two program is that, an additional array a[7] variable. How does this variable leads to crashing of program 2.
Because undefined behaviour.
You never allocate memory for input, so using it with getline is undefined behaviour.
It looks like you just want to read in some text and print it out, split on whitespace. You could just use std::string and operator>> on std::cin for this.
As mentioned by others, you get an undefined behavior because you didn't allocate memory for input.
You could fix the problem by declaring a char array or by doing things in a more "C++ way". Here's an example:
[run it online]
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
std::vector<int> a;
cout << "Enter a sequence of numbers: ";
std::copy(std::istream_iterator<int>(cin),
std::istream_iterator<int>(),
std::back_inserter(a));
cout << "You've entered: ";
for (auto& num : a)
{
cout << num << " ";
}
cout << endl;
return 0;
}
If you still want to limit the input till 100 (i.e. 'd'), you can getline() from cin to a std::string that you use to initialize a std::istringstream iss for instance. Then the std::copy() code is the same, just replace cin with iss.
// #include <sstream>
std::string input;
cin.getline(input, 100);
std::istringstream iss(input);
You have not allocated any memory for input to point to, and calling getline with an uninitialized pointer is undefined behavior.
That means that anything can happen, including your program working as you expected, or not working as expected. Adding the int a[7] just changed the memory layout of your program and consequently the behavior of the undefined behavior.
To fix it, you could simply make input a static array of the desired length:
char input[100];
Related
I am working on a project where I have to parse data from user input.
#include <iostream> // for cin and cout
#include <iomanip> // for setw()
#include <cctype> // for toupper()
using namespace std;
int main(){
string playerInput;
cin >> playerInput;
//Player would input strings like C13,C 6, I1, Z 16, etc...
}
return 0;
I've tried something like this, which kinda works but only if the letter proceeds the number in the string.
int myNr = std::stoi(playerInput);
What my end goal is to grab the letter and number from the string, and place them in a char variable and a integer variable respectively. I am stuck on how to proceed from here and could use some help, thanks!
This is the simplest and the shortest way to achieve that (it also ignores spaces and tabs):
int main() {
char ch;
int n;
cin >> ch >> n;
cout << "ch = " << ch << ", n = " << n << endl;
}
I think that other answers are a bit overcomplicated.
You could do like what you had:
char letter = playerInput.front();
playerInput.erase(0);
int number = std::stoi(playerInput);
Of course, that doesn't allow for spaces. Removing spaces can be quite tedious, but it could be done like:
playerInput.erase(
std::remove_if(
begin(playerInput), end(playerInput),
[](uint8_t ch) { return std::isspace(ch); }),
end(playerInput));
Full Demo
Live On Coliru
#include <cctype> // for toupper()
#include <iomanip> // for setw()
#include <iostream> // for cin and cout
#include <algorithm> // for remove_if
static bool ignorable(uint8_t ch) {
return std::isspace(ch)
|| std::ispunct(ch);
}
int main() {
std::string playerInput;
while (getline(std::cin, playerInput)) {
playerInput.erase(
std::remove_if(
begin(playerInput), end(playerInput),
ignorable),
end(playerInput));
if (playerInput.empty())
continue;
char letter = playerInput.front();
playerInput.erase(begin(playerInput));
int number = std::stoi(playerInput);
std::cout << "Got: " << letter << " with " << number << "\n";
}
}
Prints
Got: C with 13
Got: C with 6
Got: I with 1
Got: Z with 16
You have the right idea in using std::stoi. My code expands your approach:
string playerInput;
getline(cin, playerInput);
char c1 = playerInput[0];
int num = stoi(playerInput.substr(1));
The above code receives an input string, then takes out the first character and uses std::stoi on the rest of the string.
Note that I use std::getline to account for the possibility of there being spaces in the input. If you are doing this repeatedly, you will need to add cin.ignore() after each getline() statement. See this link for more info.
std::cin stops reading input when it encounters a space. You can use std::getline() if your input has spaces. To parse your string, you should check out std::stringstream. It allows you to read from a string as if it were a stream like std::cin.
#include <iostream> // for cin and cout
#include <iomanip> // for setw()
#include <cctype> // for toupper()
#include <sstream>
int main(){
std::string playerInput;
int i;
char c;
std::getline(std::cin, playerInput); // Remove trailing newline
std::getline(std::cin, playerInput);
//Player would input strings like C13,C 6, I1, Z 16, etc...
//String Stream
std::stringstream playerInputStream(playerInput);
//Read as if you were reading through cin
playerInputStream >> c; //
playerInputStream >> i;
}
return 0;
I'm a beginner at coding and was given a project by a friend to reverse the order of a string inputted by the user, however when I run this code the program just repeatedly prints the string inputted many times over and I'm not sure whats wrong.
For instance, I input "hi", it just prints "hi" many times. I have tried using cin, getline and scanf (as recommended by a friend), but to no avail...
#include <iostream>
using namespace std;
int main()
{
char arr[5];
getline(cin, arr);
for(int x=4; x>=0; x--){
cout << arr << endl;
}
return 0;
}
Since the question is tagged C++, you should use C++ constructs such as std::string and std::reverse. This will result in more readable and understandable code.
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
std::string input;
std::getline(std::cin, input);
std::reverse(input.begin(), input.end());
std::cout << input << std::endl;
return 0;
}
This line is wrong:
cout << arr << endl;
You have to use the index operator [] like this:
cout << arr[x];
Note that there is no endl, as that would print every character in a new line.
Using arr[x] gives you the element of the array (or character of the string if you will) at index x. Please note that element indexes in C++ start at 0. So the first element is arr[0], second arr[1], and so on.
Also, why use a C-style char array of only size 5? You can use the C++ std::string just as effectively and it will work for larger strings:
string x;
getline(cin, x);
for (int i = x.size() - 1; i >= 0; i--)
{
cout << x[i];
}
cout << endl;
Hope this helps.
When you write, cout << arr << endl; you are printing the entire string in each iteration of the loop. Instead, you wish to print the character at the index x, so you should write it as cout << arr[x]; If you use endl inside the loop, you will get a new line after each character.
Moreover, in C++, there is an easier way to deal with strings, using the string library. Then, you need not specify the number of characters in your string beforehand, and helps if the user needs to enter more than 4 characters.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string arr;
getline(cin, arr);
for(int x=arr.size()-1; x>=0; x--){
cout << arr[x];
}
cout << endl;
return 0;
}
What's happening is you're sending the entire contents of arr to cout 5 times. What you want instead is to print each character in reverse; to do this, you need to send only one character of arr at a time inside your for loop:
cout << arr[x] // This sends the character at index x to cout
cout << arr // This sends the entire array to cout
Also, you should have cout << endl after the for loop; otherwise, you'll print a newline character after each letter.
Alternate solution using iterators:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
int main()
{
std::string input;
getline(std::cin, input);
for (std::string::reverse_iterator rit=input.rbegin(); rit!=input.rend(); ++rit)
std::cout << *rit;
return 0;
}
Here is part of my code:
//num is an int
string s = "" + num;
When I run this in Xcode on a Macbook, s will be assigned to a strange string.
Can any one explain this to me?
I am really confused.
Thanks.
I assume string refers to the std::string type, declared in the standard header <string>. You haven't given that as context - technically, from information you have given it could be some preceding typedef or a macro.
The explanation as to why
string s = "" + num;
gives a "strange string" is that "" is represented in memory as a const array of one char that has the value zero. In the expression "" + num, the "" is converted to a pointer (equal to the address of that char with value zero), and + num then gives the address of some location in memory, num characters after.
If num is non-zero, that memory address may not exist, or (if it exists) might contain arbitrary data.
In any event, that pointer is passed to the constructor of std::string (in order to construct s). That constructor starts at the address given, and keeps copying data into the std::string until it happens to find a character with value zero. The characters in between could be anything - they are whatever happens to be at that memory location.
Formally, the C++ standard describes all this (accessing data via a bad pointer) as undefined behaviour. That means the C++ standard says nothing about what result is permitted, so any result is allowed. It could result in strange data in your string. The operating system might detect your program accessing memory it shouldn't, and forceably terminate your program. It could reformat your hard drive and reinstall your operating system.
Assuming you just want to write num to a string (e.g. num with value 42 results in a string like "42"), then the usual technique is to convert num to a std::string. For example;
std::string s = to_string(num); // C++11 or later
or
#include <sstream> // pre_C++11 (albeit valid in C++11)
std::ostringstream ostr;
ostr << num;
std::string s(ostr.str());
string s = std::to_string(num);
Try this one.
The idea about std::to_string() is good, but it unfortunately only works with C++11 and I have seen compilers that do not fully support that aspect though they support C++11. If you can use it, use it.
If it does not work try this:
#include <sstream>
...
int num = 5;
float rNum = 63.2;
std::stringstream ss;
ss << num;
ss << rNum;
std::string s;
ss >> s;
cout << s << endl;
You are going to get the float and int values formatted to one string. Actually I think you are better off with stringstreams if you have multiple variables get formatted. Pull them out as string with ss >> s and you are done!
The reason you were getting undesirable answer is the arithmetic addition of num to the empty string s, which is basically like pointer addition in C language.
See the examples for better explanation:
Eg. 1:
#include <iostream>
#include <string>
using namespace std;
int main() {
int num = 0;
string s = "1234567890" + num;
cout << s << endl;
return 0;
}
OUTPUT: 1234567890
Eg. 2:
#include <iostream>
#include <string>
using namespace std;
int main() {
int num = 1;
string s = "1234567890" + num;
cout << s << endl;
return 0;
}
OUTPUT: 234567890
Eg. 3:
#include <iostream>
#include <string>
using namespace std;
int main() {
int num = 4;
string s = "1234567890" + num;
cout << s << endl;
return 0;
}
OUTPUT: 567890
Eg. 4:
#include <iostream>
#include <string>
using namespace std;
int main() {
int num = 8;
string s = "1234567890" + num;
cout << s << endl;
return 0;
}
OUTPUT: 90
so on..
Since, here the string s is empty and the num has garbage value which leads to undefined result.
Better use to_string() before appending num to the empty string s.
Example:
#include <iostream>
#include <string>
using namespace std;
int main() {
int num = 1000;
string s = "" + to_string(num);
cout << s << endl;
return 0;
}
I'm trying to make a program that will receive a string and output an uppercase version of that. My code works, however once it loops through the string and changes it, it immediately crashes and I'm not completely sure why. Here are my two pieces of code.
/*This program is to intended to receive a string and return a version of it in all upper case*/
#include <iostream>
#include <string>
#include <locale>
using namespace std;
string toUpper ( string str)
{
cout <<"\n"; //Puts spaces between the input and output
for (int i=0; i<str.length(); i++;)
std::cout << std::toupper(str[i]); //A loop which goes through each digit of the string
break;
cout <<"\n\n"; //Creates spaces after the output
return str;
}
/*This program calls a function to make a string in upper case*/
#include <iostream>
#include <string>
#include <sstream>
#include <locale>
#include "toUpper1.h" //Calls the header file which contains the loop
using namespace std;
int main ()
{
cout<<"\nPlease type in a word\n\n";
string input; //Creates a variable of cin that can be used in the toUpper command
cin>>input; //Makes a user input command part of the declared variable
cout<<toUpper(input); //The command that causes the user input string to be transformed into upper case
return 0;
}
You can make string to uppercase using code bellow
Boost string algorithms:
#include <boost/algorithm/string.hpp>
#include <string>
std::string str = "Hello World";
boost::to_upper(str);
std::string newstr = boost::to_upper_copy("Hello World");
Or use like this
#include <algorithm>
#include <string>
std::string str = "Hello World";
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
You are breaking the function without returning anything. Use {} to close for loops if you want to use break
prog.cpp:16:5: error: break statement not within loop or switch
break;
Also your for loop has an extra ; at the end.
std::cout and std::toupper are useless as you are already including namespace std;
and why are you using break;? there is no need of it.
just write
for (int i=0; i<str.length(); i++)
cout << toupper(str[i]);
Remove break;
You are not transforming the string, you are outputting its transformation in the function.
instead of
std::cout << std::toupper(str[i]);
use
str[i]=std::toupper(str[i]);
And move all printing out of the function. Changing the string doesn't include printing!
Notice the #bbdude95 answer, too.
edit
Instead of
cout<<"\nPlease type in a word\n\n";
string input; //Creates a variable of cin that can be used in the toUpper command
cin>>input;
use
char input[256];
cout << "Please type in a word:\n>";
cin.getline( input, 256, '\n' );
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string toUpper ( string str)
{
cout <<"\n"; //Puts spaces between the input and output
for (int i=0; i<str.length(); i++)
str[i] = std::toupper(str[i]); //A loop which goes through each digit of the string
//break;
cout <<"\n\n"; //Creates spaces after the output
return str;
}
int main ()
{
cout<<"\nPlease type in a word\n\n";
string input; //Creates a variable of cin that can be used in the toUpper command
cin>>input; //Makes a user input command part of the declared variable
//The command that causes the user input string to be transformed into uppe case
cout << toUpper(input);
cout << std::endl << "The original string is" << input << std::endl;
return 0;
}
EDIT: Note that keeping the function signature as above (string toUpper ( string str), as were required), we are making some extra string copies, and, most important: we are NOT modifying the original string (excute the code and see the result of last cout.
I want to ask for word from the user and then convert the word from string to char using 'strcpy'. Then I want to determine the sum of the ascii codes for all of the letters in the word.
However, I am having difficulties. I don't understand exactly how I can do that. This is what I have been able to do so far.
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main()
{
string word;
cout << "Enter word: ";
getline(cin, word);
/*
char w[word];
strcpy(w,word.c_str());
int ('A');
cout<<char(65);
*/
return 0;
}
The commented part is where I have been trying to do the converting. I copied the code from a worksheet. Even if it did work, I don't know how, and what it all means.
Thanks for your help.
char w[word];
strcpy(w, word.c_str());
char w[word] is incorrect. The square brackets is for the size, which must be a constant integral expression. word is of type std::string, so this makes neither logical nor practical sense. Maybe you meant it as:
char w = word;
But that still won't work because word is a string, not a character. The correct code in this case is:
char* w = new char[word.size() + 1];
That is, you allocate the memory for w using a char*. Then you use word.size() + 1 to initialize heap-allocated memory amounting to those bytes. Don't forget for the obligatory delete[] when you're finished using w:
delete[] w;
However, note that using raw pointers and explicit new is not needed in this case. Your code can easily be cleaned up into the following:
#include <numeric>
int main ()
{
std::string word;
std::getline(std::cin, word);
int sum = std::accumulate(word.begin(), word.end(), 0); /*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
std::cout << "The sum is: " << sum << std::endl;
}
You don't need to use strcpy() (or use a char * at all, for that matter), but this'll do your counting using a char pointer:
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "Enter word: ";
std::cin >> word;
const char * cword = word.c_str();
int ascii_total = 0;
while ( *cword ) {
ascii_total += *cword++;
}
std::cout << "Sum of ASCII values of characters is: ";
std::cout << ascii_total << std::endl;
return 0;
}
Output:
paul#local:~/src/cpp/scratch$ ./asccount
Enter word: ABC
Sum of ASCII values of characters is: 198
paul#local:~/src/cpp/scratch$
If you really do want to use strcpy(), I'll leave it as an exercise to you to modify the above code.
Here's a better way to do it, just using std::string (and C++11, and obviously presuming your system uses the ASCII character set in the first place):
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "Enter word: ";
std::cin >> word;
int ascii_total = 0;
for ( auto s : word ) {
ascii_total += s;
}
std::cout << "Sum of ASCII values of characters is: ";
std::cout << ascii_total << std::endl;
return 0;
}