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;
}
Related
I have the following code:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream os;
char fileName[] = "0.txt";
for(int i = '1'; i <= '5'; i++)
{
fileName[0] = i;
os.open(fileName);
os << "Hello" << "\n";
os.close();
}
return 0;
}
The aim is to write my code output into multiple .txt files up to, say 64 different times. When I change this loop to run more than 10, that is
for(int i = '1'; i <= '10'; i++)
I get the following error:
warning: character constant too long for its type
Any ideas how to write to more than 10 files? Moreover, how do I write a number after each "Hello", e.g. "Hello1 ... Hello10"?
Cheers.
I believe the reason you receive that warning is because you're attempting to assign two chars into one slot of the char array:
fileName[0] = i;
because when i = 10;, it's no longer a single character.
#include <fstream>
#include <iostream>
#include <string>//I included string so that we can use std::to_string
using namespace std;
int main() {
ofstream os;
string filename;//instead of using a char array, we'll use a string
for (int i = 1; i <= 10; i++)
{
filename = to_string(i) + ".txt";//now, for each i value, we can represent a unique filename
os.open(filename);
os << "Hello" << std::to_string(i) << "\n";//as for writing a number that differs in each file, we can simply convert i to a string
os.close();
}
return 0;
}
Hopefully this resolved the issues in a manner that you're satisfied with; let me know if you need any further clarification! (:
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];
I need to convert a string in C++ to full upper case. I've been searching for a while and found one way to do it:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string input;
cin >> input;
transform(input.begin(), input.end(), input.begin(), toupper);
cout << input;
return 0;
}
Unfortunately this did not work and I received this error message:
no matching function for call to 'transform(std::basic_string::iterator, std::basic_string::iterator, std::basic_string::iterator,
I've tried other methods that also did not work. This was the closest to working.
So what I'm asking is what I am doing wrong. Maybe my syntax is bad or I need to include something. I am not sure.
I got most of my info here:
http://www.cplusplus.com/forum/beginner/75634/
(last two posts)
You need to put a double colon before toupper:
transform(input.begin(), input.end(), input.begin(), ::toupper);
Explanation:
There are two different toupper functions:
toupper in the global namespace (accessed with ::toupper), which comes from C.
toupper in the std namespace (accessed with std::toupper) which has multiple overloads and thus cannot be simply referenced with a name only. You have to explicitly cast it to a specific function signature in order to be referenced, but the code for getting a function pointer looks ugly: static_cast<int (*)(int)>(&std::toupper)
Since you're using namespace std, when writing toupper, 2. hides 1. and is thus chosen, according to name resolution rules.
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");
Convert a String In C++ To Upper Case
Try this small program, straight from C++ reference
#include <iostream>
#include <algorithm>
#include <string>
#include <functional>
#include <cctype>
using namespace std;
int main()
{
string s;
cin >> s;
std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int, int>(std::toupper));
cout << s;
return 0;
}
Live demo
You could do:
string name = "john doe"; //or just get string from user...
for(int i = 0; i < name.size(); i++) {
name.at(i) = toupper(name.at(i));
}
Uppercase to Lowercase and viceversa using BitWise operators
1.
string s = "cAPsLock";
for(char &c: s)
c = c | ' '; // similar to: c = tolower(c);
cout << s << endl; // output: capslock
string s = "cAPsLock";
for(char &c: s)
c = c & ~' '; // similar to: c = toupper(c);
cout << s << endl; // output: CAPSLOCK
PS: for more info check this link
#include <iostream>
using namespace std;
//function for converting string to upper
string stringToUpper(string oString){
for(int i = 0; i < oString.length(); i++){
oString[i] = toupper(oString[i]);
}
return oString;
}
int main()
{
//use the function to convert string. No additional variables needed.
cout << stringToUpper("Hello world!") << endl;
return 0;
}
Like leemes said, you can use toupper(int). Like this:
void ToUpper(string &str) {
for (auto beg = str.begin(); beg != str.end(); ++beg) {
*beg = toupper(*beg);
}
}
It'll through in each character from str and convert it to upper. Example:
int main()
{
string name;
cout << "Insert a name: ";
cin >> name;
ToUpper(name);
cout << "Name in upper case: " << name << endl;
}
You can also use the function from code below to convert it to Upper-case.
#include<iostream>
#include<cstring>
using namespace std;
//Function for Converting Lower-Case to Upper-Case
void fnConvertUpper(char str[], char* des)
{
int i;
char c[1 + 1];
memset(des, 0, sizeof(des)); //memset the variable before using it.
for (i = 0; i <= strlen(str); i++) {
memset(c, 0, sizeof(c));
if (str[i] >= 97 && str[i] <= 122) {
c[0] = str[i] - 32; // here we are storing the converted value into 'c' variable, hence we are memseting it inside the for loop, so before storing a new value we are clearing the old value in 'c'.
} else {
c[0] = str[i];
}
strncat(des, &c[0], 1);
}
}
int main()
{
char str[20]; //Source Variable
char des[20]; //Destination Variable
//memset the variables before using it so as to clear any values which it contains,it can also be a junk value.
memset(str, 0, sizeof(str));
memset(des, 0, sizeof(des));
cout << "Enter the String (Enter First Name) : ";
cin >> str; //getting the value from the user and storing it into Source variable.
fnConvertUpper(str, des); //Now passing the source variable(which has Lower-Case value) along with destination variable, once the function is successfully executed the destination variable will contain the value in Upper-Case
cout << "\nThe String in Uppercase = " << des << "\n"; //now print the destination variable to check the Converted Value.
}
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;
}
I want to copy the contents of a float to a string in C++. This doesn't work.
#include <iostream>
#include <sstream>
using namespace std;
int main() {
float ans = getFloat();
stringstream ss;
string strAns;
ss >> ans;
strAns = ss.str();
cout << strAns << "\n"; // displays "0"
return 0;
}
How do I do this?
I think
ss>>ans;
should be
ss<<ans;
Edit:
As James Kanze noted, you are better off using std::ostringstream instead of std::stringstream as you are not using the bidirectional functionality of the first one. This way the compiler would also throw an error that you extracting ans from the string instead of inserting it into the string.
ss << ans; instead of ss >> ans and it will work
To work with stringstreams, you have to use the PUT TO operator( << ), with an object on the right hand side. That will convert the operator to a string(if the operator is defined for the particular type)(this operator<< is already defined for a stringstream object with float object).
Then, convert the string stream to a string.. and you will have successfully converted the object to string.
As the other answers show, it should be ss << ans, since << is used for ostreams and >> is used for istreams.
If you want just to print the float to cout, you can of course avoid the detour and just write std::cout << ans;, but I guess you want to use the string otherwise.
You should however be aware of the simplifications provided by Boost's and C++11's libraries:
#include <iostream>
#include <string> //for std::string and std::to_string
#include <boost/lexical_cast.hpp>
using namesapce std;
int main() {
float ans=getFloat();
string strAns1 = boost::lexical_cast<string>(ans); //boost way
auto strAns2 = std::to_string(ans); //C++11 way
cout << "boost: " << strAns1 << "\n"
<< "C++11: " << strAns2 << "\n";
}
You are using wrong operator:
#include <iostream>
#include <sstream>
using namespace std;
int main() {
float ans=getFloat();
stringstream ss;
string strAns;
ss << ans;
strAns=ss.str();
cout<<strAns<<"\n"; // displays "0"
return 0;
}
Just one line wrong here by the look of it. You need to stream the float into the stringsteram like this:
ss << ans;
Use
strAns = std::to_string(ans);