String constructor with a int is not printed - c++

1. string s6 {0};
2. string s5 {'a','b',7};
cout << "S6 ::: " << s6 << endl;
cout << "S5 ::: " << s5 << endl;
Expect undefined behaviour 'nullptr' but does print an empty string.
Prints ab not expected behaviour.
Running on QT5.. compiler clang on MacOs

In the both cases
1. string s6 {0};
2. string s5 {'a','b',7};
there is used the constructor that accepts an initializer list.
In the second case the integer literal 7 can be represented in the type char. So there is no narrowing conversion.
Consider the following program.
#include <iostream>
#include <string>
int main()
{
std::string s6 {0};
std::string s5 {'a','b',7};
std::cout << s6.size() << ": ";
for ( char c : s6 ) std::cout << static_cast<int>( c ) << ' ';
std::cout << '\n';
std::cout << s5.size() << ": ";
for ( char c : s5 ) std::cout << static_cast<int>( c ) << ' ';
std::cout << '\n';
return 0;
}
Its output is
1: 0
3: 97 98 7

Related

C++: Addressing each byte

Trying to extract each byte in a short I've created.
While I can print the second (or first) byte, I can't get both.
With my current understanding, this should work. Hoping someone can make it clear to me what the error is here. I'm running this on windows x86, so ILP32 data format.
#include <iostream>
using namespace std;
int main()
{
short i = 0x1123;
short* p = &i;
short* p1 = p;
p1++;
char c = *p;
char c1 = *p1;
cout
<< "Short: " << hex << i << '\n'
<< "p: " << p << '\n'
<< "p1: " << p1 << '\n'
<< "c: " << hex << (unsigned int)c << '\n'
<< "c1: " << hex << (unsigned int)c1 << '\n'
;
return 0;
}
Output:
Short: 1123
p: 0041FB58
p1: 0041FB56
c: 23
c1: ffffffcc
Here is the fix:
#include <iostream>
#include <iomanip>
int main()
{
short i = 0x1123;
short* p = &i;
char* c = reinterpret_cast<char*>( p );
char* c1 = c + 1;
std::cout << "Short: " << std::showbase << std::hex << i << '\n'
<< "p: " << p << '\n'
<< "c: " << +( *c ) << '\n'
<< "c1: " << +( *c1 ) << '\n';
return 0;
}
There is no need for p1. The problem with p1++ is that it adds 2 to the value of p1 and not 1 as you would expect. And that's because p1 is a pointer to short so when you increment it, it progresses by 2 (short is 2 bytes). You need to cast it to a char* so that each time you increment it, it will add 1 to the value.
Also, notice the + operator in +( *c ). Using this operator will make sure that *c won't be printed as a character but instead as its ASCII value or whatever value it has, thus there is no need to cast it to int.
Possible output:
Short: 0x1123
p: 0xb71f3ffd8e
c: 0x23
c1: 0x11
An alternative solution that uses no pointer trix and doesn't care about endianness.
#include <iostream>
int main()
{
short i = 0x1123;
unsigned low = i % 256;
unsigned high = i / 256;
std::cout << std::hex
<< "Short: " << i << '\n'
<< "low: " << low << '\n'
<< "high: " << high << '\n';
return 0;
}
Thank you to rustyx and Pete Becker who answered this. The program is aware that the pointer is for a type short therefore when I try to increment it automatically increments the value by 2. This behaviour can be circumvented by casting the pointer to a char.
#include <iostream>
using namespace std;
int main()
{
short i = 0x1123;
cout
<< "Short: " << hex << i << '\n'
;
char* p = (char*)&i;
char c = *p;
cout
<< "p: " << hex << (unsigned int)p << '\n'
<< "c: " << hex << (unsigned int)c << '\n'
;
char* p1 = p + 1;
char c1 = *p1;
cout
<< "p1: " << hex << (unsigned int)p1 << '\n'
<< "c1: " << hex << (unsigned int)c1 << '\n'
;
return 0;
}
Output:
Short: 1123
p: 54fd54
c: 23
p1: 54fd55
c1: 11

C++: Convert string or char to int [duplicate]

This question already has answers here:
How can I convert a std::string to int?
(24 answers)
Closed 2 years ago.
If I have:
string number = "45";
How do I turn "45" into 45 as an integer?
I want to be able to do this:
string number + 20 = 65
You can use the following example from https://en.cppreference.com/w/cpp/string/basic_string/stol:
#include <iostream>
#include <string>
int main()
{
std::string str1 = "45";
std::string str2 = "3.14159";
std::string str3 = "31337 with words";
std::string str4 = "words and 2";
int myint1 = std::stoi(str1);
int myint2 = std::stoi(str2);
int myint3 = std::stoi(str3);
// error: 'std::invalid_argument'
// int myint4 = std::stoi(str4);
std::cout << "std::stoi(\"" << str1 << "\") is " << myint1 << '\n';
std::cout << "std::stoi(\"" << str2 << "\") is " << myint2 << '\n';
std::cout << "std::stoi(\"" << str3 << "\") is " << myint3 << '\n';
//std::cout << "std::stoi(\"" << str4 << "\") is " << myint4 << '\n';
}

String Functions: Strcat()

I'm currently writing a program that uses string functions. I need some advice/hints on how I can display "Hello World" and its length with myStrcat() in main(). I'm new to programming and any support would be greatly appreciated.
My Code:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int myStrlen(char str1[])
{
int i = 0;
for (i=0; str1[i] != '\0'; i++)
str1[i] = '\0';
return i;
}
int myStrcat(char str2[], char str3[])
{
}
int myStrcpy(char str4[], char str5[])
{
int i = 0;
for (i=0; str5[i] != '\0'; i++)
str4[i] = str5[i];
str4[i] = '\0';
return i;
}
int main()
{
const int SIZE = 11;
char s1[SIZE] = "Hello";
char s2[SIZE] = "World";
cout << "s1: " << " " << s1 << endl << endl; ///Should display "Hello"
cout << "The length of s1: " << myStrlen(s1) << endl << endl;
cout << "Doing strcat(s1, s2) " << endl;
myStrcat(s1, s2);
cout << "s1: " << " " << s1 << endl; /// Should display "Hello World"
cout << "The length of s1: " << myStrlen(s1) << endl << endl;
cout << "Doing strcpy(s1, s2) " << endl;
myStrcpy(s1, s2);
cout << "s1: " << " " << s1 << endl; /// Should display "World"
cout << "The length of s1: " << myStrlen(s1) << endl << endl;
My Output:
s1: Hello
The length of s1: 5
Doing strcat(s1, s2)
s1:
The length of s1: 0
Doing strcpy(s1, s2)
s1: World
The length of s1: 5
Line 6 and 7 are suppose to display Hello World and its length (which is 11).
You have a number of not just quite right beginning to each of your functions. Firstly, let's think about the returns for each. myStrlen should return size_t instead of int. C++ designates a size_type for counters, measuring, etc.. The remaining functions should return char* (or nullptr on failure).
Looking at your myStrlen function where you have
for (i=0; str1[i] != '\0'; i++)
str1[i] = '\0';
You are setting every character in str1 to the nul-character because you are applying the loop to the next expression. You should not be worrying about nul-terminating anything within myStrlen -- you are just counting characters. So you can rewrite it as follows:
size_t myStrlen (const char *str)
{
size_t l = 0;
for (; str[l]; l++) {}
return l;
}
Your myStrcpy looks workable, though you should always validate your input parameters are not nullptr before using them -- I leave that to you. Since you have a myStrlen function, you can simply use that along with memcpy to create your myStrcpy function as:
char *myStrcpy (char *dest, const char *src)
{
size_t len = myStrlen(src);
return (char *)memcpy (dest, src, len + 1);
}
(note: traditionally you have source (src) and destination (dest) parameters when copying or concatenating)
For your myStrcat function, you are just using the myStrlen function to find the offset in dest to append src, so you really just need a call to myStrlen and then a call to myStrcpy to copy src to that offset in dest, e.g.
char *myStrcat (char *dest, const char *src)
{
size_t len = myStrlen (dest);
return myStrcpy (dest + len, src);
}
In your main(), if you want a space between "Hello" and "World", then const int SIZE = 11; is one too-low to hold the concatenated string "Hello World" which would require 12-bytes (including the nul-terminating character). Do Not Skimp on buffer size. 128 is plenty small.
Remaining with your main() but updating SIZE = 12; and adding a space between "Hello" and "World" with an additional call to myStrcat, you could do the following:
int main (void)
{
const int SIZE = 12; /* too short by 1 if you add space between */
char s1[SIZE] = "Hello";
char s2[SIZE] = "World";
std::cout << "s1: " << " " << s1 << std::endl << std::endl;
std::cout << "The length of s1: " << myStrlen(s1) << std::endl << std::endl;
std::cout << "Doing strcat(s1, s2) " << std::endl;
myStrcat(s1, " ");
myStrcat(s1, s2);
std::cout << "s1: " << " " << s1 << std::endl;
std::cout << "The length of s1: " << myStrlen(s1) << std::endl << std::endl;
std::cout << "Doing strcpy(s1, s2) " << std::endl;
myStrcpy(s1, s2);
std::cout << "s1: " << " " << s1 << std::endl;
std::cout << "The length of s1: " << myStrlen(s1) << std::endl << std::endl;
}
(note: don't include using namespace std;, it is just bad form in this day and age)
Example Use/Output
$./bin/mystrcpy
s1: Hello
The length of s1: 5
Doing strcat(s1, s2)
s1: Hello World
The length of s1: 11
Doing strcpy(s1, s2)
s1: World
The length of s1: 5
Look things over and let me know if you have further questions.
First you should read Why is “using namespace std;” considered bad practice?
Don't use c style strings if you are starting programming. Use std::string. It's much simpler to use.
#include <iostream>
#include <string>
int myStrlen(const std::string &str) {
return str.length();
}
int myStrcat(std::string &str1, const std::string &str2) {
str1 += str2;
str1.length();
}
int myStrcpy(std::string &str1, const std::string &str2) {
str1 = str2;
return str1.length();
}
int main() {
std::string s1 = "Hello";
std::string s2 = "World";
std::cout << "s1: " << s1 << "\n\n"; ///Should display "Hello"
std::cout << "The length of s1: " << myStrlen(s1) << "\n\n";
std::cout << "Doing strcat(s1, s2) " << '\n';
myStrcat(s1, s2);
std::cout << "s1: " << s1 << '\n'; /// Should display "Hello World"
std::cout << "The length of s1: " << myStrlen(s1) << "\n\n";
std::cout << "Doing strcpy(s1, s2) " << '\n';
myStrcpy(s1, s2);
std::cout << "s1: " << s1 << '\n'; /// Should display "World"
std::cout << "The length of s1: " << myStrlen(s1) << "\n\n";
return 0;
}

Vector Subscript out of range error.The error occurs even if the vector has greater index than the index for which data is accessed

I am using VC++ 2013.I'm trying to access the index of the vector where it shows vector subscript out of range.My code is given below:
std::string str="1,2,3, 4 , 0.00000 , ";
vector<string>veclist;
veclist=(tokenize(str,","));
//Now the veclist has a size of 6.But when i am trying to access it through;
long num=stol(veclist.at(4));
The code crashes and shows vector subscript out of range.I don't know why the code crashes and what's the error in this!!!
The code crashes and shows vector subscript out of range.I don't know
why the code crashes and what's the error in this!!!
The message tells you all.
It crashes since you have no rights to access veclist.at(4). Simply you have not enough elements in veclist or veclist is empty.
Check the number elements in veclist by veclist.size() after executing (tokenize(str,","));
Edit:
You may have different problem then reported. Your str tokens may not be liked by the stol function. That can cause the crash.
Consider this test program. I have written tokenize_split which should match yours.
#include <vector>
#include <string>
#include <string.h>
#include <sstream>
#include<iostream>
using namespace std;
std::vector<std::string> tokenize_split(const std::string &s, char delim) {
std::stringstream ss(s);
std::string item;
std::vector<string> tokens;
while (getline(ss, item, delim)) {
tokens.push_back(item);
}
return tokens;
}
int main(void)
{
std::string str1="1 2 3 4 5 6";
std::string str2="1,2,3, 4 , 0.00000 , "; // Your string
std::string str3="1,2,3,4,5,6";
vector<string> veclist;
long num;
veclist = tokenize_split(str3, ',');
std::cout << "Size= " << veclist.size() << endl;
std::cout << "Token= " << "<" << veclist.at(4) << ">" << endl;
num = std::stol(veclist.at(4));
std::cout << "Number " << num << endl << endl;
veclist = tokenize_split(str2, ',');
std::cout << "Size= " << veclist.size() << endl;
std::cout << "Token= " << "<" << veclist.at(4) << ">" << endl;
num = std::stol(veclist.at(4));
std::cout << "Number " << num << endl << endl;
veclist = tokenize_split(str1, ' ');
std::cout << "Size= " << veclist.size() << endl;
std::cout << "Token= " << "<" << veclist.at(4) << ">" << endl;
num = std::stol(veclist.at(4));
std::cout << "Number " << num << endl << endl;
veclist = tokenize_split(str2, ' ');
std::cout << "Size= " << veclist.size() << endl;
std::cout << "Token= " << "<" << veclist.at(4) << ">" << endl;
num = std::stol(veclist.at(4));
std::cout << "Number " << num << endl;
return 0;
}
Test:
Size= 6
Token= <5>
Number 5
Size= 6
Token= < 0.00000 >
Number 0
Size= 6
Token= <5>
Number 5
Size= 5
Token= <,>
terminate called after throwing an instance of 'std::invalid_argument'
what(): stol
Aborted
Program crashes since your string str2 does not contain a valid number that could be successfully converted to long by the stol function. The token ',' will cause the abort.

stoi is not declared in this scope? [duplicate]

This question already has answers here:
Function stoi not declared
(13 answers)
Closed 8 years ago.
I am trying to convert a string into int using stoi() but i am getting error that error: ‘stoi’ was not declared in this scope. Here is the given code.
#include <iostream>
#include <string>
int main()
{
std::string str1 = "45";
std::string str2 = "3.14159";
std::string str3 = "31337 with words";
std::string str4 = "words and 2";
int myint1 = std::stoi(str1);
int myint2 = std::stoi(str2);
int myint3 = std::stoi(str3);
// error: 'std::invalid_argument'
// int myint4 = std::stoi(str4);
std::cout << "std::stoi(\"" << str1 << "\") is " << myint1 << '\n';
std::cout << "std::stoi(\"" << str2 << "\") is " << myint2 << '\n';
std::cout << "std::stoi(\"" << str3 << "\") is " << myint3 << '\n';
//std::cout << "std::stoi(\"" << str4 << "\") is " << myint4 << '\n';
}
stoi is from C++11, you should try with atoi