Why does adding two spaces produce incorrect output? - c++

I have the following program meant to calculate primes:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
bool primeTest(int number){
if ((number == 0) || (number == 1)){
return false;
}
if ((number == 2) || (number == 3)){
return true;
}
for (int j = 2; j <= number / 2; j++){
if (number%j == 0){
return false;
}
}
return true;
}
int main(){
vector<int> primeVector;
for (int i = 0; i <= 100; i++){
if (primeTest(i)){
primeVector.push_back(i);
}
}
int pvSize = primeVector.size();
for (int i = 0; i < pvSize; i++){
cout << primeVector[i] << ' ';
}
cin.get();
}
If I change the line cout << primeVector[i] << ' '; to cout << primeVector[i] << ' '; (I added a space) it gives me
28224382245822478224118224138224178224198224238224298224318224378224418224438224
478224538224598224618224678224718224738224798224838224898224978224
instead of
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Why does this occur? Only a space was added. It doesn't occur with double quotes.

String literals should be enclosed in double quotes, not single quotes. Single quotes are used for character literals. If you have multiple characters in a single character literal, the value is some implementation-defined integer. Multi-character literals are rarely useful.
(Note that this doesn't apply to something like '\n', which is a single character represented by an escape sequence.)
Use " " instead.

Simply put, one space is one characer, two spaces is two characters or a C-Style string.
' ' -- single character.
" " -- two spaces require double quotes.

Related

C++ String insert iteration

I have the string:
string str = "1234567890";
//Magic code
cout<<str<<endl;
Which i want to output: 12 34 56 78 90
I assume std has some neat feature/function to help solve this. How do I that in the most convenient way?
The std::string::insert with a for loop could help you to insert spaces into an std::string very easely:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str = "1234567890";
for(auto it = str.begin(); it != str.end(); it += min<int>(str.end() - it, 2))
it = (it != str.begin() ? str.insert(it, ' ') + 1 : it);
cout << str << endl;
}
The std::string::insert returns an iterator pointing to the character inserted, therefore it has to be incremented to step over the inserted character.
Because std::string has a random-access iterator it can be incremented or decremented more than by one. The min<int>(str.end() - it, 2) ensures that the next step won't go out of bounds.
A more general approach. Define a function that inserts a given character char_to_insert into a given string s every interval characters, excluding beginning and end of string:
std::string insert_char(const std::string& s, char char_to_insert, size_t interval)
{
// corner cases
if (!interval || !s.length()) return s;
// compute number of characters to insert
auto number_of_chars_to_insert = (s.length()-1)/interval;
// compute total length
auto output_length = s.length() + number_of_chars_to_insert;
// pre-allocate output string with all characters equal to char_to_insert
std::string retval(output_length, char_to_insert);
// cycle input string, keeping track of position in input and output strings
size_t pos = 0, pos_in_input = 0;
for (const auto& c : s)
{
// copy from input to output
retval[pos++] = c;
// advance in output every interval chars
if ((++pos_in_input) % interval == 0)
++pos;
}
return retval;
}
Then:
int main()
{
std::string s = "1234567890";
for (size_t i = 1; i != 5; ++i)
std::cout << insert_char(s, ' ', i) << std::endl;
return 0;
}
The output:
1 2 3 4 5 6 7 8 9 0
12 34 56 78 90
123 456 789 0
1234 5678 90
There is no built-in to do what you want.
Instead, the most convenient solution is probably to iterate through the string and output pairs of digits as you go:
string str = "1234567890";
for (auto it = str.begin(); it != str.end(); ++it){
std::cout << *(it);
if (++it != str.end()){
std::cout << *it << " ";
}
}
std::cout << std::endl;
Or non-iterator version:
string str = "1234567890";
for (idx = 0; idx < str.length(); idx += 2){
std::cout << str.substr(idx, 2) << " ";
}
std::cout << std::endl;
Both of these examples will have a trailing space on the line, but I've left it in to keep the examples simpler.

Programming Principles & Practices Using C++ - Ch 04 'Try This' exercise

I'm a bit confused about this exercise in the above mentioned book-
"The character 'b' is char('a'+ 1), 'c' is char('a'+ 2), etc. Use a loop to write out a table of characters with their corresponding integer values:
a 97
b 98
c 99
...
z 122"
The book has just gone over while loops, and I read a bit ahead as I was still confused as to how to do this without just listing out each value individually (which I assume isn't the point here), and the next section is about for loops. I thought that maybe you can somehow increase letters in the alphabet by 1 in a loop (so a -> b, b -> c, etc.), but if this is indeed possible, the book hasn't yet gone over how to accomplish this yet.
Thanks in advance, I'm working through this book alone in my spare time so I don't have a professor to ask questions like this, and the Try This exercises don't have their answers listed on Bjarne's website.
Just write a simple loop:
for(auto c = 'a';c <= 'z' ;c++)
cout<<c<<" "<<int(c)<<endl;
Here is my solution to your problem :)
int main (void) {
char c = 'a';
while (c <= 'z') {
std::cout << c << "\t" << c - 0 << '\n'; // c - 0 is convertion to int without cast
++c;
}
return 0;
}
The book is referring to the idea that you can iterate over integers and use the control variable in character arithmetic to get the table. For example, with integers you can iterate over the integers 0 to 25 with
int i = 0;
while (i <= 25) {
cout << i << endl;
i = i + 1; // or ++i
}
Now you can apply the problem hint char('a' + i) to get the rest of the answer. I'll let you work that out.
int main()
{
char ch = 'a';
int i = 0;
while(i < 26)
{
cout << (char)(ch + i) << "\t" << (ch + i) << "\n";
++i;
}
}
You can do something like this:
char ch = 'a';
for (int i = 0; i < 26; ++i)
cout << (char)(ch + i) << " " << (ch + i) << endl;
This will generate the output that you expect.
Here is one way to do it using the while loop:
#include <iostream>
int main()
{
int i = 0; //Initialize i to 0.
while (i < 26) // 0 - 25.
{
int val = 'a' + i; // char('a' + 1), int('a' + 1).
std::cout << char(val) << "\t" << int(val) << std::endl;
++i; //Increments the while loop variable i
}
return 0;
}
Output:
a 97
b 98
c 99
d 100
e 101
f 102
g 103
h 104
i 105
j 106
k 107
l 108
m 109
n 110
o 111
p 112
q 113
r 114
s 115
t 116
u 117
v 118
w 119
x 120
y 121
z 122
I included comments so that you can understand my thoughts and also so that it can be updated.
Here's the answer to the Chapter 4 Try this exercise for the book by Bjarne Stroustrup: Programming Principles and Practice Using C++:
// Description- Try this exercise using a while statement to provide a series of characters from the ASCII code.
#include "stdafx.h"
#include "Std_lib_facilities.h"
int main()
{
int i = 96; // Beginning/initialisation of the integers which will be converted to char (s) in cout.
while (i<122) // The limit for the while statement is the integer which will be safely converted to the last char.
{
cout << i + 1 << '\t'<< char (i+1)<<'\n'; ++i; // The first integer will be 1 plus the initial = 97. Then followed by a tab.
// Then followed by the integer 97 being safely converted to an char using the ASCII.
// The while loop in the two comments is repeated till 122 is converted safely to z.
}
}

How to parse a part of a string, which have characters other than digits, to integer

I am currently trying to read information from an .txt file and essentially store this appropriately. Data from the input file would look something like this
10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
765DEF 01:01:05:59 enter 17
ABC123 01:01:06:01 enter 17
765DEF 01:01:07:00 exit 95
ABC123 01:01:08:03 exit 95
My question is that, assuming I have read "01:01:05:59" into a string, how do I parse this to store the numbers in an int variable. In addition, all I really need is the third pair of numbers in that string(from the left) and I was also wondering how to skip the first two and last pair of numbers in that string. I have read on delimiters but I'm a little confused on how to use them. The code I have so far is shown below and is basically that information to strings.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
int arr[25];
ifstream File;
File.open("input.txt");
for (int a = 0; a < 25; a++)
{
File >> arr[a];
}
for (int i = 0; i < 25; i++)
{
cout << arr[i] << " ";
}
cout << endl;
string license, datetime;
File >> license >> datetime; // reads in license plate and datetime information into two separte strings
cout << license << endl << datetime;
system("pause");
}
Background:
If we know the start and end indices (or the length) of the sub-string we need, then we can read it by using std::string::substr.
Its usage is as follows:
#include <string>
...
std::string foo = "0123456789stack:overflow";
// start index = 4, length = 2
std::string subStr1 = foo.substr(4,2); // result = "45"
// start index = 3, end index = 5 => length = 5 - 3 + 1 = 3
std::string subStr2 = foo.substr(3,3); // result = "345"
// The first parameter is the start index whereas the second one is
// the length of the wanted sub-string.
// If only the start index is known:
std::string subStr2 = foo.substr(9); // result = "9stack:overflow"
// In that case we get the rest of the string starting from the start index 9.
For more information on that please refer to: http://www.cplusplus.com/reference/string/string/substr/
Suggested solution to the OP:
Since you said "all I really need is the third pair of numbers" then you need two characters starting from index 6:
std::string a = "01:01:05:59";
std::string sub = a.substr(6, 2); // will give you "05"
then convert them using:
int number = std::stoi(sub);
These steps can be shortened to:
int number = std::stoi( a.substr(6, 2) );
Further references:
First part: http://en.cppreference.com/w/cpp/string/basic_string/substr
Second part: How to parse a string to an int in C++?
PS: if you want to use character array instead of std::string then you just can get the characters with their corresponding indices. For example: i = 6 and i = 7 in your specific case. Then, get yourArray[6]=0 and yourArray[7]=5. Then perform integer conversion on them.
Could you do:
int num = std::stoi(string.substr(6, 2);
assuming I have read "01:01:05:59" into a string
One easy way is using streams:
#include <iostream>
#include <sstream>
int main()
{
int n[4];
std::istringstream iss("02:30:41:28");
if (iss >> n[0] && iss.get() == ':' &&
iss >> n[1] && iss.get() == ':' &&
iss >> n[2] && iss.get() == ':' &&
iss >> n[3] >> std::ws && iss.eof())
std::cout << n[0] << ' ' << n[1] << ' ' << n[2] << ' ' << n[3] << '\n';
else
std::cerr << "parsing error\n";
}
On ideone.com

Reading integer input from file into a dynamic array and printing it

I am attempting to write a program that reads in integers from an input file and outputs a dynamic array. This array would be the size of the input. For verification, I'd also like to print the array. The output will be passed to a function to create a sorted linked list.
I tried the following, but it did not work:
istringstream input(R"inp(
23 43 12 67
18 15 22
12 xxx 23 12 xx 34556 11 11 www
)inp");
int get, count = 0;
while (input >> get)
count++;
cout << "Number of integers: " << count << endl;
int *array = new int [count];
for (int i = 0; i < count; i++)
{
input >> array[i];
}
for (int i = 0; i < count; i++)
{
cout << *(array+i) << endl;
}
delete[] array;
Here's an online example of my code.
The problem is that the output shows some weird numbers, completely unrelated to the input:
Number of integers: 8
-1217944384
-1217944384
-1
538976266
540226080
824193844
Where did I go wrong?
As πάντα ῥεῖ pointed out, the solutions that I did provide are not totally safe, that's why I will provide a third example, using boost::spirit.
See the points fast fix and good solution, as well as πάντα ῥεῖ's answer to get it working without using boost.
my personal favourite solution: note that this example does require to have read the text file into a string.
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
template<typename Iterator>
bool
parse_numbers(Iterator first, Iterator last, std::vector<int>& v)
{
bool r =
boost::spirit::qi::parse(first, last,
// Begin grammar
(boost::spirit::qi::int_[boost::phoenix::push_back(
boost::phoenix::ref(v), _1)]
% *(boost::spirit::qi::char_("a-zA-Z")
| boost::spirit::ascii::space)));
if (first != last) // fail if we did not get a full match
return false;
return r;
}
const std::string s = "23 43 12 67 \n18 15 22\n12 xxx 23 12 xx 34556 11 11 www";
std::string::const_iterator start = s.begin(), stop = s.end();
std::vector<int> results;
parse_numbers(start, stop, results)));
for(int i : results)
std::cout << value << ' ';
the result would be, as expected:
23 43 12 67 18 15 22 12 23 12 34556 11 11
The above example is partially built on the example given in the boost::spirit documentation.
input >> get moves the current curser position, so after your while loop you have nothing left to read.
fast fix:
ifstream input;
input.open("file.txt");
int get, count = 0;
while (input >> get)
count++;
input.close();
input.open("file.txt");
int *array = new int [count];
for (int i = 0; i < count; i++)
{
input >> array[i];
}
for (int i = 0; i < count; i++)
{
cout << *(array+i) << endl;
}
input.close();
delete[] array;
To close and reopen the stream should work, but there are more efficient solutions out there...
good solution:
One could be to read and insert into a dynamically growing vector for example. See the documentation for further reference.
std::vector<int> dataArray;
while (input >> get)
{
dataArray.insert(dataArray.end(), get);
}
for(auto&& value : dataArray)
{
std::cout << value << std::endl;
}
That would have multiple advantages:
allocating the vector on the stack prevents you from being forced to call delete. An alternative would be a standard smart pointer.
the for each loop works even without counting the elements. If you need the number of elements you could just ask the vector about his size.
Your code has several misconceptions and flaws:
(1) After applying this loop to count your inputs
while (input >> get)
count++;
the input stream's state is left over the result of last extraction operation (input >> get) that has failed. Thus no further input can be read, without completely resetting the stream.
(2) The second loop you're showing
for (int i = 0; i < count; i++) {
input >> array[i];
}
uses the input stream in invalid state (the whole stream was already read to input.eof()), and thus reading from it results in 'weird values' (in other words: It's undefined behavior at this point).
I would write the following proven code to solve this
// Your literal input file formatting goes here
istringstream input(R"inp(
23 43 12 67
18 15 22
12 xxx 23 12 xx 34556 11 11 www
)inp");
int current;
vector<int> allIntInputs;
while (input >> current || !input.eof()) {
if(input.fail()) {
input.clear();
string crap;
input >> crap; // read anything up to the next
// whitespace delimiter (the default deleimiters)
continue; // with the next item
}
// Everything's fine we'll add another number
allIntInputs.push_back(current);
}
// Print all integer values extracted
cout << "Integer values read from input:" << endl;
for(vector<int>::iterator it = allIntInputs.begin();
it != allIntInputs.end();
++it) {
if(it != allIntInputs.begin()) {
cout << ' ';
}
cout << *it;
}
cout << endl;
Output
Integer values read from input:
23 43 12 67 18 15 22 12 23 12 34556 11 11

Code adding \n and 1, and I don't know why

This is a bit complicated, but basically I'm making a program and one of my functions is acting a bit strange. The function is fed an array of characters, the first time it's
new_sensor_node SN42 42 3.57 5.0 7.
right now the function just prints out each individual "token" (each set of characters separated by spaces). Then prints a space, and then prints the number of characters in the token. But for some reason, the last token is always printed weird, and 1 character extra is counted.
Here's the function:
int parseCommandLine(char cline[], char *tklist[]){
int i;
int length;
int count = 0; //counts number of tokens
int toklength = 0; //counts the length of each token
length = strlen(cline);
for (i=0; i < length; i++) { //go to first character of each token
if (((cline[i] != ' ' && cline[i-1]==' ') || i == 0)&& cline[i]!= '"') {
while ((cline[i]!=' ')&& (cline[i] != '\0')){
toklength++;
cout << cline[i];
i++;
}
cout << " " << toklength << "\n\n";
cout << "\n";
toklength = 0;
count ++;
}
if (cline[i] == '"') {
do {
i++;
} while (cline[i]!='"');
count++;
}
}
//cout << count << "\n";
return 0;
And here's the output (for that first array):
new_sensor_node 15
SN42 4
42 2
3.57 4
5.0 3
7.
3
Any thoughts on what could be causing this? I suspect it might have to do with how I'm dealing with the null character
It's very likely that the input string actually contains the newline at the end. Depending on how you read the input, it may or may not be in the input. For example, the fgets function reads the newline and leaves it in the buffer.
Especially since you don't actually do any actual tokenization or modification of the input string, you just print character by character, this is a very likely scenario.