array size and split of string - c++

Ok guy i had to make a program to split elements of a string. And after that print those words.
there are some problems i am facing:
1) the array prints more than the size of the words in string i want that it should end printing as soon as last word is printed. i tried to prevent that but it always gives runtime error when i try to break at the last word.
2)is there any other efficient way to split and print ???
#include <sstream>
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include <string>
using namespace std;
int main()
{
std::string line;
std::getline(cin, line);
string arr[1000];
int i = 0;
int l=line.length();
stringstream ssin(line);
while (ssin.good() && i < l)
{
ssin >> arr[i];
++i;
}
int size = sizeof(arr) / sizeof(arr[0]);
for(i = 0; i <size; i++){
cout << arr[i] << endl;
}
return 0;
}

int size = sizeof(arr) / sizeof(arr[0]);
That is a compile time value, and it's always going to be the number of elements in your array (1000). It has no idea how many strings you assigned to in your loop. You stored the number of successfully read strings (plus 1) in the i variable, so you could do this instead:
int size = i - 1;
But if it were up to me, I would just use a growable structure, like vector (#include <vector>)
std::vector<std::string> arr;
std::string temp;
while (ssin >> temp)
{
arr.push_back(temp);
}
for (auto const & str : arr)
{
std::cout << str << std::endl;
}
/* If you're stuck in the past (can't use C++11)
for (std::vector<std::string>::iterator = arr.begin(); i != arr.end(); ++i)
{
std::cout << *i << std::endl;
}
*/
For general purpose character based splitting, I would much prefer boost::split (I know you can't use it, but for future reference)
std::vector<std::string> arr;
boost::split(arr, line, boost::is_any_of(".,;!? "));

Read up on the function strtok. It is old school but very easy to use.

1) there are a couple of changes you should make to your program:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
std::string line("hello string world\n");
string arr[1000];
int i = 0;
stringstream ssin(line);
while (ssin.good() && i < 1000)
{
ssin >> arr[i++];
}
int size = i-1;
for(i = 0; i < size; i++){
cout << i << ": " << arr[i] << endl;
}
return 0;
}
namely, you don't want to print sizeof(arr)/sizeof(arr[0]) (i.e. 1000) elements. There is no point in the condition i < l
2) stringstream is fine if you just want to separate the single strings; if more is needed, use boost/tokenizer for splitting strings. It's modern c++, once you try it you'll never come back!

this is the best method i think no worry now
#include <sstream>
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include <cstring>
#include <string>
using namespace std;
int main ()
{
std::string str;
std::getline(cin, str);
string arr[100];
int l=0,i;
char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());
// cstr now contains a c-string copy of str
char * p = std::strtok (cstr,".,;!? ");
while (p!=0)
{
//std::cout << p << '\n';
arr[l++]=p;
p = strtok(NULL,".,;!? ");
}
for(i = 0; i <l; i++)
{
cout << arr[i] << endl;
}
delete[] cstr;
return 0;
}

Related

free(): invalid pointer when using scanf

Hello guys so this is my code.
I could not use cin nor getline() so I had to use scanf.
It reads all the values in as expected but after entering the last value it says:
free(): invalid pointer ./comp: line 8: 877 Aborted (core dumped) ./$BIN
Anyways, here is the code.
Help would be appreciated.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
// n -> amount of lines of code.
// q -> amount of queries.
int n, q;
cin >> n >> q;
// Handle source code Input.
vector<string> v(n);
for (unsigned i = 0; i < n; ++i)
{
cout << "i: " << i << endl;
scanf("%s", &v[i]);
}
return 0;
}
scanf is designed to work with character buffers, not strings. You probably want to use std::string (it's more intuitive and manages memory for you), so scanf is a poor fit. There's a version of getline that works with string.
std::vector<std::string> v(n);
for (int i = 0; i < n; i++) {
cout << "i: " << i << endl;
std::getline(std::cin, v[i]);
}
The %s specifier of scanf() expects a pointer to a char[] array, not a std::string object. By reading directly into a std::string object, you are corrupting its internals.
So, you need to either:
read into a char[] first, then assign that to your std::string:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
// n -> amount of lines of code.
// q -> amount of queries.
int n, q;
cin >> n >> q;
// Handle source code Input.
vector<string> v(n);
char buf[256];
for (unsigned i = 0; i < n; ++i)
{
cout << "i: " << i << endl;
scanf("%255s", buf);
v[i] = buf;
/* or:
int len = scanf("%255s", buf);
v[i] = string(buf, len);
*/
}
return 0;
}
pre-allocate the std::string's internal character buffer, then read directly into it (note, this approach is only guaranteed to work in C++11 and later, but in practice will typically work in most implementations of std::string in earlier versions, too):
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
// n -> amount of lines of code.
// q -> amount of queries.
int n, q;
cin >> n >> q;
// Handle source code Input.
vector<string> v(n);
for (unsigned i = 0; i < n; ++i)
{
cout << "i: " << i << endl;
v[i].resize(256);
int len = scanf("%255s", &v[i][0]/* or: v[i].data() in C++17 and later */);
v[i].resize(len);
}
return 0;
}

How do I flip the first number in the string with the last number and then second and second last and so on?

Here's what I tried and it's not logical. First_num++ is just copying 2 numbers instead of the second number and so is the last_num++
How do I continue copying like that and cout them
I know I can just cout the thing in reverse because the output is the same.I can do that by reversing the count but the question wants me to exchange the characters one by one. Please help, thanks.
#include <iostream>
#include <cctype>
using namespace std;
void reverse_word(char character[]);
int main()
{
char characters[50];
reverse_word(characters);
return 0;
}
void reverse_word(char character[])
{
char temp1[2] = "\0";
char temp2[2] = "\0";
char first_num = 1;
char last_num = 1;
cout << "Enter a word to reverse first word last word second first second last and so on: ";
cin >> character;
for (int i=0;i<strlen(character)/2;i++)
{
strncpy(temp1, character, first_num);
first_num++;
strcpy(temp2 , &character[strlen(character)-last_num]);
last_num++;
}
for (int i = 0; i < strlen(character) / 2; i++)
{
cout << temp2;
cout << temp1;
}
}
You can use the build-in function of c++ reverse(begin, end) where the begin and end iterator are as parameter like below:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "String example";
reverse(str.begin(), str.end()); // outputs --> elpmaxe gnirtS
cout<<"\n"<<str;
return 0;
}
This is a short and fast solution , but if you want to get a more depth view you can apply some nice alogrithm .
You should cout the temp variables in the same for loop, not in a different one.

I want to create a c++ program that will generate a random string of user specified lenght (i.e min and max) at runtime

The objective is to create it using user defined functions. such a C++ program which have a user defined function (Name: GenerateRandomWords) whose functionality is to generate random words using english alphabets e.g. Differerent website offer random generated password to use. Save All these words in text File (Name: Output.txt) as well as in an array of type string. The problem I am facing being an amaetuer is that it successfully generates 1st word and stores it in the string but when The loop starts for the second word to be generated the program runs for a while and then ends. this is the code , thanks in advance for the help:
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
static const char alphanum[] =
"0123456789"
"!##$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum)-1;
char genRandom()
{
return alphanum[rand() % stringLength];
}
int main()
{
int n = 0, a = 0;
cout << "Howe many strings you want to generate\t";
cin >> n;
cout << "Lenght of each :\t";
cin >> a;
string le;
string ar[] = { "" };
for (int i = 0; i < n; i++)
{
for (int j = 0; j < a; j++)
{
le += genRandom();
}
ar[i] = le;
le = "";
cout << ar[i] << endl;
}
cout << "Out of both loop\n";
for (int i = 0; i < n; i++)
cout << ar[i] << endl;
}
On this line:
string ar[] = { "" };
you are creating an array of strings of size 1. So when you try to add the second string into this array, you invoke undefined behaviour. If you just use a vector<string> you won't have this problem:
vector<string> ar;
and on the line you are doing:
ar[i] = le;
you should do:
ar.push_back(le);
Here's a working demo.
Also, your "random" choices are not very random. Check out the random header for how you can do this better.
According to your requirement, you wants to get the length of each string and the number of strings to be printed using a specified character arrayed variable alphanum and create output.txt to save it.
Consider at the following code:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
const char alphanum[] =
"0123456789"
"!##$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
void generate(int, int);
void setOutput(char[]);
main(void)
{
int length, strings;
std::cout << "How many strings & length (sep. by SPACE): ";
std::cin >> strings >> length;
srand(time(0));
generate(length, strings);
return 0;
}
void generate(int len, int str)
{
char array[len];
int max = sizeof(alphanum) / sizeof(alphanum[0]);
std::ofstream output("output.txt");
for (int k = 1; k <= str; k++)
{
for (int i = 0; i <= len; i++)
array[i] = alphanum[(rand() % max) + 1];
std::cout << array << std::endl;
output << array << std::endl;
}
}
Output
How many strings & length (sep. by SPACE): 5 5
5Xe*%%
xOD8TQ
YfrM*X
#j&L5&
U8*EYB
Note: Firslty, remember the srand() will let the random values change each time you execute the program. Secondly, this program will generate an output.txt to meet your criteria.
Enjoy!

C++ simple string program

beginner here
i wrote the below in C++, it's a short program that currently takes 2 words as inputs, and outputs the same words back but the words are split into even and odd instead. I would like to be able to do this for 'T' words instead, but I can't figure it out. I would like to be able to first input the number of words that will follow, for example 10. Then to input the words and get T results back. So instead of just 2 words, an unlimited amount with the user specifying.
I need to put the below into a function and go from there sometime, but I want to learn the best technique to do so - any advice please?
Thanks!
Alex
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
int T;
cin >> T;
string FirstWord;
cin >> FirstWord;
int LengthFirst;
LengthFirst = FirstWord.length();
string EvenFirst;
string OddFirst;
for (int i = 0; i < LengthFirst; i += 2){
EvenFirst = EvenFirst + FirstWord[i];
}
for (int i = 1; i < LengthFirst; i += 2){
OddFirst = OddFirst + FirstWord[i];
}
string SecondWord;
cin >> SecondWord;
int LengthSecond;
LengthSecond = SecondWord.length();
string EvenSecond;
string OddSecond;
for (int i = 0; i < LengthSecond; i += 2){
EvenSecond += SecondWord[i];
}
for (int i = 1; i < LengthSecond; i += 2){
OddSecond += SecondWord[i];
}
cout << EvenFirst << " " << OddFirst << endl;
cout << EvenSecond << " " << OddSecond << endl;
return 0;
}
Think I got it here, I was over-thinking this one
I put it in a for loop, as below - so any number of words can be input, user has to input the number of test cases at the
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
int T;
cin >> T;
for (int i = 0; i < T; i++){
string FirstWord;
cin >> FirstWord;
int LengthFirst;
LengthFirst = FirstWord.length();
string EvenFirst;
string OddFirst;
for (int i = 0; i < LengthFirst; i += 2){
EvenFirst = EvenFirst + FirstWord[i];
}
for (int i = 1; i < LengthFirst; i += 2){
OddFirst = OddFirst + FirstWord[i];
}
cout << EvenFirst << " " << OddFirst << endl;
}
return 0;
}
Ultimately, you are performing the same task N times.
First, let's discuss how to store the information. Functionally, we have one string as input which yields two strings as output. std::pair (from <utility>) lets us easily represent this. But for sake of even-odd, std::array might be a better representation for us. Since we have a variable number of words as input, a variable number of std::array will be output. std::vector (from <vector>) is our friend here.
Second, let's discuss how to process the information. Using named variables for each output component does not scale, so let's switch to a fixed array (noted below as array<string,2>. By switching to a fixed array for output, addressing each split becomes a function of the loop index (index % 2). Below is a solution that generalizes on a known split size at compile time.
#include <string>
#include <array>
#include <vector>
#include <iostream>
int main() {
int N;
std::cin >> N;
constexpr const int Split = 2;
using StringPack = std::array<std::string, Split>;
std::vector<StringPack> output;
for (int wordIndex = 0; wordIndex < N; ++wordIndex) {
std::string word;
std::cin >> word;
StringPack out;
{
int index = 0;
for (char c : word) {
out[index % Split] += c;
++index;
}
}
output.emplace_back(out);
}
for (const auto & out : output) {
for (const auto & word : out) {
std::cout << word << ' ';
}
std::cout << '\n';
}
}

strtok() analogue in C++

I just can't find an algorithm to split the string into words by numerous delimiters. I know how to split a string by whitespace with istringtream and by single delimiter with getline. How can I connect them all.
For instance:
input: This -is-a!,string;
output:
This
is
a
string
Why not just #include <cstring> and use std::strtok() in your C++ program?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void SplitToVector(vector<string> &v, string dlm, string src){
string::size_type p, start=0, len=src.length();
v.clear();
start = src.find_first_not_of(dlm);
p = src.find_first_of(dlm, start);
while(p != string::npos){
v.push_back(src.substr(start, p-start));
start = src.find_first_not_of(dlm, p);
p = src.find_first_of(dlm, start);
}
if(len>start)//rest
v.push_back(src.substr(start, len - start));
}
int main(void){
char input[256] = "This -is-a!,string;";
vector<string> v;
int i, size;
SplitToVector(v, "-!,;", input);
//cout << input << endl;
size = v.size();
for(i=0; i<size; i++)
cout << v.at(i) << endl;
return 0;
}
I would recommend split in boost (string algorithm), see http://www.boost.org/doc/libs/1_53_0/doc/html/string_algo/usage.html#idp163440592.