How & makes a reference to a string variable in C++? - c++

I am little confused about the use of & literal with strings. I see a big difference in the output of following two codes:
#include <iostream>
using namespace std;
int main()
{
char st[]="This is a Sample String";
cout<<st[0];
return 0;
}
Output: T
#include <iostream>
using namespace std;
int main()
{
char st[]="This is a Sample String";
cout<<&st[0];
return 0;
}
Output: This is a Sample String
I know & is used as a reference operator to pass the value by reference. But my question is how & actually works here.

Array of characters is also called string in C++. And in C++ if you want to print the Starting address of the string then it will not print the starting address of the string it will print the whole string.
The operator& have different meaning in different situation in C++. And the meaning of & is decided by its context(where it is using).

Related

Is std::string an array of two iterators?

I do not understand the behavior of the following snippet.
How could this be happening?
#include <bits/stdc++.h>
using namespace std;
int main() {
string s = "apple";
string foo = {s.begin(), s.end()};
cout << foo << endl;
}
output:
apple
Don't confuse how an object is constructed over what it fundamentally is.
A constructor can, and will, take in all kinds of things. Quite often these arguments are converted in some way, transformed into the form that's a more natural fit for the class in question.
In this case you're constructing a string out of a range of characters, or in other words, an arbitrary substring. There are many other methods, including converting from char*, which is something you'll see all the time:
std::string example = "example";
Here you can read that as "example is initialized with the value "example"".

How to print out the first element of a const string?

How to print out the first element of a const string?
I tried to do std::cout << path[0] << std::endl; on CLion
but path[0] does not work and the IDE would warn.
CLion warns that
Cannot assign to return value because function 'operator[]' returns a const value.
type print(const std::string &path){}
You can use
std::string::at
It can be used to extract characters by characters from a given string.
Consider an example
#include <stdio.h>
#include<iostream>
using namespace std;
int main()
{
string str = "goodday";
cout << str.at(0);
return 0;
}
Hope this will help you.
First of all you can ignore the warning sometimes the compiler complains about unnecessary things, secondly do not do the following:
type print(const std::string &path){}
Dangerous, first of all Passing a string as a reference?? Think about it from the compilers point of view, the string is const, each time you use the += you are actually create a new string. But if you use the & with the string you are telling the compiler that you are planning to modify the string object which has type const..... Use string path as a parameter but never, ever use string& path......

Different output with string and char array

When I am using the following code to convert an string to a float, it is working fine. But the next code gives the error. Please tell me why is this happening? String is a char array only is what I read.
Code1 (working)
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
char str[]="301.23";
float f=atof(str);
cout<<sizeof(str)<<" is size with contents "<<str<<endl;
cout<<sizeof(f)<<" is size with contents "<<f<<endl;
return 0;
}
Code 2(not working)
#include<stdlib.h>
#include<string>
#include<iostream>
using namespace std;
int main()
{
string str="301.23";
float f=atof(str);
cout<<sizeof(str)<<" is size with contents "<<str<<endl;
cout<<sizeof(f)<<" is size with contents "<<f<<endl;
return 0;
}
Error:
error: cannot convert std::string to const char* for argument 1 to double atof(const char*)
Please help
std::string is not a char array.
Use str.c_str() to get a const char* and you should be fine
Syntax:
#include <stdlib.h>
double atof( const char *str );
The input string is a sequence of characters that can be interpreted as a numeric value of the specified return type.
The function stops reading the input string at the first character that it cannot recognize as part of a number. This character can be the null character that ends the string.
The atof() function expects a string in the following form:
Read syntax diagramSkip visual syntax diagram
>>-+------------+--+-----+--+-digits--+---+--+--------+-+------->
'-whitespace-' +- + -+ | '-.-' '-digits-' |
'- – -' '-.--digits-----------------'
Therefore your problem lies in the atof funcion which is not designed to accept string at it doesn't store characters in integer form.
Hope this helped.. :D
Try using #include<cstring> in place of #include <string>
Technically, You're only guaranteed std::string, but all popular implementations just pull in the C header and add a using statement...
is a C++ standard library include, and is C standard library include.

Write a program that reads a string of characters including punctuation and writes what was read but with the punctuation removed

Here's my attempt at it:
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s("hello world!..!.");
for (auto &c : s)
if(!ispunct(c))
{
cout<<s;
}
}
Here's the output
hello world!..!.hello world!..!.hello world!..!.hello world!..!.hello world!..!.
hello world!..!.hello world!..!.hello world!..!.hello world!..!.hello world!..!.
hello world!..!.
Here's another attempt:
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s("hello world!..!.");
for (auto &c : s)
if(!ispunct(c))
{
cout<<c;
}
}
This gives the correct output (i.e : hello world)
Why won't cout<<s; give me the correct output? After all c is a reference, so any changes to c would also apply to s. Or am I wrong about this?
This is why i don't really like the auto feature, auto in your case is a char and there is no elimination from the string.
LE: ispunct doesn't remove the character from the string, it doesn't even know (or care) that you have a string, it only returns true if the character is punctuation character or false if not, and based on that return the cout statement is executed with the character that is not punctuation or not executed for punctuation character.
s is the entire string, so cout<<s sends the entire string to your output stream :\
Your second attempt works because you're sending individual characters to the stream. In the first attempt though, you're sending the whole string for each character that exists in the string. Count the number of non-punct characters in your string, then count the number of times the string was printed out ;)
ispunct does not eliminate the character that is a punct. It only returns 0 or non-zero to indicate
if it is punct or no.
When you encounter a character that is not punct, it returns 0. And you enter your if. You are printing s that is the whole string.
Whereas, with cout<<c you only print the character (which is non punct, since you are now in the loop)
One more variant, using STL algorithms:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using std::cout;
using std::endl;
using std::string;
using std::back_inserter;
using std::copy_if;
int main()
{
string s("hello world!..!.");
string result = "";
copy_if(begin(s), end(s),
back_inserter(result),
[](char c){return !ispunct(c);}
);
cout << result << endl;
}
For real world code it's recommended to prefer suitable STL algorithms if available over a loop, because saying copy_if states your intent clearly, and does not focus on the individual steps to take. Whether or not it's better in this example I don't want to judge. But it's certainly good to keep this possibility in mind!
One more thing: It's generally regarded a bad thing to write using namespace std, because this can lead to name collisions when a future version of C++ introduces new keywords which you've already defined yourself in your own code. Either use the prefix std:: all the time, or follow the way I've shown in my example, this keeps your code safe.

In C++, I thought you could do "string times 2" = stringstring?

I'm trying to figure out how to print a string several times. I'm getting errors. I just tried the line:
cout<<"This is a string. "*2;
I expected the output: "This is a string. This is a string.", but I didn't get that. Is there anything wrong with this line? If not, here's the entire program:
#include <iostream>
using namespace std;
int main()
{
cout<<"This is a string. "*2;
cin.get();
return 0;
}
My compiler isn't open because I am doing virus scans, so I can't give the error message. But given the relative simplicity of this code for this website, I'm hoping someone will know if I am doing anything wrong by simply looking.
Thank you for your feedback.
If you switch to std::string, you can define this operation yourself:
std::string operator*(std::string const &s, size_t n)
{
std::string r; // empty string
r.reserve(n * s.size());
for (size_t i=0; i<n; i++)
r += s;
return r;
}
If you try
std::cout << (std::string("foo") * 3) << std::endl
you'll find it prints foofoofoo. (But "foo" * 3 is still not permitted.)
There is an operator+() defined for std::string, so that string + string gives stringstring, but there is no operator*().
You could do:
#include <iostream>
#include <string>
using namespace std;
int main()
{
std::string str = "This is a string. ";
cout << str+str;
cin.get();
return 0;
}
As the other answers pointed there's no multiplication operation defined for strings in C++ regardless of their 'flavor' (char arrays or std::string). So you're left with implementing it yourself.
One of the simplest solutions available is to use the std::fill_n algorithm:
#include <iostream> // for std::cout & std::endl
#include <sstream> // for std::stringstream
#include <algorithm> // for std::fill_n
#include <iterator> // for std::ostream_iterator
// if you just need to write it to std::cout
std::fill_n( std::ostream_iterator< const char* >( std::cout ), 2, "This is a string. " );
std::cout << std::endl;
// if you need the result as a std::string (directly)
// or a const char* (via std::string' c_str())
std::stringstream ss;
std::fill_n( std::ostream_iterator< const char* >( ss ), 2, "This is a string. " );
std::cout << ss.str();
std::cout << std::endl;
Indeed, your code is wrong.
C++ compilers treat a sequence of characters enclosed in " as a array of characters (which can be multibyte or singlebyte, depending on your compiler and configuration).
So, your code is the same as:
char str[19] = "This is a string. ";
cout<<str * 2;
Now, if you check the second line of the above snippet, you'll clearly spot something wrong. Is this code multiplying an array by two? should pop in your mind. What is the definition of multiplying an array by two? None good.
Furthermore, usually when dealing with arrays, C++ compilers treat the array variable as a pointer to the first address of the array. So:
char str[19] = "This is a string. ";
cout<<0xFF001234 * 2;
Which may or may not compile. If it does, you code will output a number which is the double of the address of your array in memory.
That's not to say you simply can't multiply a string. You can't multiply C++ strings, but you can, with OOP, create your own string that support multiplication. The reason you will need to do that yourself is that even std strings (std::string) doesn't have a definition for multiplication. After all, we could argue that a string multiplication could do different things than your expected behavior.
In fact, if need be, I'd write a member function that duplicated my string, which would have a more friendly name that would inform and reader of its purpose. Using non-standard ways to do a certain thing will ultimately lead to unreadable code.
Well, ideally, you would use a loop to do that in C++. Check for/while/do-while methods.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count;
for (count = 0; count < 5; count++)
{
//repeating this 5 times
cout << "This is a string. ";
}
return 0;
}
Outputs:
This is a string. This is a string. This is a string. This is a string. This is a string.
Hey there, I'm not sure that that would compile. (I know that would not be valid in c# without a cast, and even then you still would not receive the desired output.)
Here would be a good example of what you are trying to accomplish. The OP is using a char instead of a string, but will essentially function the same with a string.
Give this a whirl:
Multiply char by integer (c++)
cout<<"This is a string. "*2;
you want to twice your output. Compiler is machine not a human. It understanding like expression and your expression is wrong and generate an error .
error: invalid operands of types
'const char [20]' and 'int' to binary
'operator*'