How to tell stringstream to ignore null terminating character? - c++

Is there any way to tell a stringstream to ignore a null terminating char and read a certain amount of chars anyway?
As you can see from this minimum example, even though the char array consists of 3 chars, the stringstream terminates at the second position:
#include <sstream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
char test[3];
test[0] = '1';
test[1] = '\0';
test[2] = '2';
stringstream ss(test);
char c;
cout << "start" << endl;
while (ss.get(c)) {
cout << c << endl;
}
if (ss.eof()) {
cout << "eof" << endl;
}
}
$ ./a.out
start
1
eof

This question is not about stringstreams. The problem is you are implicitly constructing a std::string from a const char* for that stringstream constructor argument, and doing so using the overload that expects a C-string. So, naturally, you should expect C-string-like behaviour.
Instead you can form the argument using the std::string(const char*, std::size_t) constructor, or send the data to a default-constructed stringstream using .write.

In addition to the other answer explaining the underlying problem (creating a std::string from a char*), here's one (of many) ways around the problem, using std::string_literals:
#include <iostream>
#include <string>
#include <sstream>
int main(){
using namespace std::string_literals;
const std::string str_with_null = "1\0002"s;
std::stringstream ss(str_with_null);
char c;
while (ss.get(c)) {
std::cout << static_cast<int>(c) << '\n';
}
}
When run, this should print out:
49
0
50

Related

How to combine few bacis chars into one string in c++

As a topic says. I try to combine few chars (from array) into one string.
i tried
char test[]={'A'};
char testt[]={'a'};
string testtt= test[0]+testt[0];
But it doesn't work.
char test[]={'A'};
char testt[]={'a'};
string testtt="";
testtt+=test[0];
testtt+=testt[0];
You can either use the constructor that takes char*, length.
#include<iostream>
#include<string>
int main(){
char test[]={'A'};
char testt[]={'a','w'};
std::string testtt= std::string(&test[0], 1) + std::string(&testt[1],1);/
std::cout<<testtt<<std::endl;
return 0;
}
or constructor that takes a range:
std::string testtt= std::string(&test[0], &test[1]) + std::string(&testt[0],&testt[1]);
It will do the trick ;)
#include <sstream>
string toStr(char* tab, int length)
{
stringstream ss;
for (int i=0 ; i<length; i++)
ss << tab[i];
return ss.str();
}
if you look inside class string you'll find that it doesn't overload copy constructor to take one character parameter.
you may think that you implement your own class containing a string object:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class MyStr
{
public:
MyStr(char c){ itsString = c;}
string GetStr()const {return itsString;}
private:
string itsString;
};
int main(int argc, char* argv[])
{
char test[]={'A'};
char testt[]={'a'};
MyStr testtt = test[0] + testt[0];
cout << testtt.GetStr() << endl;
cout << endl << endl << endl;
return 0;
}
this program runs and the compiler never complains BUT the result won't be as you may think: it won't be "Aa" but just: 'ت' because in fact the above statement: string testtt= test[0]+testt[0]; is equivalent to write: cout << (char)('A' + 'a');
which means summing two characters and the result is the integer ASCII value then this value will be converted back again to charater because you are really ivoking string(char); which will result to (charater of 162)

String to Integer Conversion

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];

C++ add char to char[1024]

#include <iostream>
#include <conio.h>
using namespace std;
int main(){
char command[1024];
char newchar;
cout << "Command Line Interface Test with Intellisense" << endl;
cout << endl;
newchar = _getch();
command = command + newchar;
}
Why does this not work?
Why command = command + newchar is wrong?
You should use std::string and append the char to it.
http://en.cppreference.com/w/cpp/string/basic_string/append
Or with C++11, you can use the += operator with std::string
(You will have to #include string header)
It doesn't work because C++ is statically typed. A char[1024] object will stay the same type for its entire life, and it can't change to a char[1025]. The same applies to a std::string, but the size of a string is not part of its type and can therefore change:
std::string command = "abc";
comamnd += "d";
In command + newchar, command becomes a (const) pointer and newchar is an integer value, so you are making a pointer to a "bigger" address, but when assigning the result to command, you are trying to change the (const) pointer to an array, which luckily is not allowed.
char* pNew = command + newchar;
This would have worked, but not doing as expected. As others already answered: use std::string.
Are You trying to do something like this?
#include <iostream>
#include <conio.h>
using namespace std;
#define BUFFER_SIZE 1024
int main(){
char command[BUFFER_SIZE];
cout << "Command Line Interface Test with Intellisense" << endl;
cout << endl;
for(unsigned int i = 0; i < BUFFER_SIZE; ++i)
char newchar = _getch();
if(newchar == '\n') break;
// do some magic with newchar if you wish
command[i] = newchar;
}
}

How do I store user input as a char*?

In my main method,
int main()
{
char *words = (char *)"GETGETYETYET";
char *pattern = (char *)"GET";
return 0;
}
Instead of *words and *pattern being a predefined char set, I want to get user input, the user types in the name of a .txt file, and I want the strings in that .txt file to be stored as (char *).
How can I do this?
You don't.
Unless you want to deal with string allocations, deallocations, and ownerships, with buffer overruns and security problems, you just use std::string...
Like this:
#include <iostream>
#include <string>
int main() {
std::string a = "abcde";
std::string b;
getline(std::cin, b);
std::cout << a << ' ' << b;
return 0;
}
Suppose your strings are on the file x.txt, one per line:
#include <iostream>
#include <string>
#include <fstream>
int main() {
std::string line;
std::ifstream f("x.txt");
while( std::getline(f, line) )
std::cout << ' ' << line << '\n';
return 0;
}
The point here being that you really don't want to store things in char*...

Convert string to char for ascii

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;
}