Printing all Blanks (literally no tokens are printed) - c++

Basically my code doesn't print the tokens. It just prints blanks. What am I doing wrong?
I've consulted many other guides on this issue and I can't seem to understand what I'm doing wrong.
Thanks.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stack>
#include <stdexcept>
#include <string>
#include <stdlib.h>
#include <cstring>
using namespace std;
int main() {
stack<double> s;
string str = "";
getline(cin, str);
char *cstr = new char [str.length()+1];
strcpy(cstr, str.c_str());
char* strp = strtok(cstr, " ");
while (strp != 0){
double n = strtod(cstr, &strp);
s.push(n);
cout << strp << endl;
strp = strtok(0," ");
}
return 0;
}

This code works for me:
int main()
{
stack<double> s;
string str = "";
getline(cin, str);
char *cstr = new char [str.length()+1];
strcpy(cstr, str.c_str());
char* strp = strtok(cstr, " ");
while (strp != NULL)
{
double n = strtod(strp, NULL);
s.push(n);
cout << n << endl;
strp = strtok(NULL, " ");
}
return 0;
}
But hell, this really is a painfull mix of C and C++. You should get rid of those strcpy, strtok and strod functions. Use istringstream instead.

Related

How to concatenate strings in an output function?

Some languages have easy ways of doing this, but my question revolves in C and C++.
I wanna do something like this in Java:
public class sandbox {
public static void main(String[] args) {
System.out.println("Thank" + " you!");
}
}
And transfer it in C:
#include <stdio.h>
int main() {
/* The easiest way is like this:
char *text1 = "Thank";
char *text2 = " you";
printf("%s%s\n", text1, text2);
*/
printf("Thank" + " you."); // What I really want to do
}
How do I concatenate strings in a language like this?
You use just nothing:
puts ("Thank" " you.");
Concatenating strings is not that easy in C unfortunately, here's how to do it most succinctly:
char *text1 = "Thank";
char *text2 = " you";
char *text_concat = malloc(strlen(text1) + strlen(text2) + 1);
assert(text_concat);
text_concat = strcpy(text_concat, text1);
text_concat = strcat(text_concat, text2);
printf("%s\n", text_concat);
free(text_concat);
What I have understood from your question, hope the below solution will answer your question.
#include <stdio.h>
int main() {
char s1[100] = "Thank ", s2[] = "You";
int length, j;
// store length of s1 in the length variable
length = 0;
while (s1[length] != '\0') {
++length;
}
// concatenate s2 to s1
for (j = 0; s2[j] != '\0'; ++j, ++length) {
s1[length] = s2[j];
}
// terminating the s1 string
s1[length] = '\0';
printf("After concatenation: %s",s1);
return 0;
}
In C++, you can easily concatenate two string it by adding two string with a + operator.
#include <iostream>
using namespace std;
int main()
{
string s1, s2, result;
cout << "Enter string s1: ";
cin>>s1;
cout << "Enter string s2: ";
cin>>s2;
result = s1 + s2;
cout << "After concatenation: = "<< result;
return 0;
}
This is a concatenation, but is a constant or compile time concatenation, you can't concatenate strings like that, but in case you need to split a string constant in multiple parts is ok:
...
printf("Thank" " you."); // What I really want to do
...
For dynamic, runtime concatenation you need strcat like
strcat(text1, text2);
First you must assure that you have enough memory in target string, see this link http://www.cplusplus.com/reference/cstring/strcat/
Ok, that was the C way, but C++ has STL with std::string
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1 = "hello ", str2 = "world";
cout<< str1 + str2<< endl;
return 0;
}
It is not possible in C to do something like printf("Thank" + " you."); because C doesn't support Operator Overloading Unlike C++. You can refer Is it possible to overload operators in C?

Alternative for a loop in C++

I want to reverse a string without the use of a loop. My code with the loop looks like:
#include <iostream>
#include <string>
using namespace std;
string reverseString(string str) {
string changedString;
int strLength = int(str.length() - 1);
for(int i {strLength}; i >= 0; i--) {
changedString.push_back(str.at(i));
}
return changedString;
}
int main() {
string str;
cout << "Enter a string to reverse it:\n" << flush;
cin >> str;
cout << reverseString(str) << flush;
}
Now I need to write a function without the loop. Only the methods of String should be used. Can you help me solving this problem?
It is very simple to write such a function
std::string reverse( const std::string &s )
{
return { s.rbegin(), s.rend() };
}
Here is a demonstrative program
#include <iostream>
#include <string>
std::string reverse( const std::string &s )
{
return { s.rbegin(), s.rend() };
}
int main()
{
std::string s( "Hello World" );
std::cout << s << '\n';
std::cout << reverse( s ) << '\n';
return 0;
}
Its output is
Hello World
dlroW olleH
Well, you can do that using recursion. Here are some links if you aren't aware what recursion is : link1 and link2.
Technically it won't be a loop.
string reverseString(string str, int index, string ans) {
if (index == -1) return ans;
ans += str[index];
return reverseString(str, index - 1, ans);
}
Parameters for this function will be str as it was by default, index = size(str) - 1 and ans ans = "";
reverseString(str, size(str) - 1, "") for example.
If you want your function to take exactly one argument, then you can write wrapper function and the one I wrote will have different name - reverseStringWrapper for example and in reverseString there will be only one line - return reverseStringWrapper(str, size(str) - 1, "");
string reverseStringWrapper(string str, int index, string ans) {
if (index == -1) return ans;
ans += str[index];
return reverseString(str, index - 1, ans);
}
string reverseString(string str) {
return reverseStringWrapper(str, size(str) - 1, "");
}
How was this?
In c, You can use strrev() function to reverse the string(char*)
In c++, you can either use std::reverse() or StringBuilder.reverse()
method to reverse a string.
.
This way you can reverse the char array(char*).
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
// Function to reverse a given character array using std::reverse
void reverse(char *str)
{
std::reverse(str, str + strlen(str));
}
// main function
int main()
{
/* using C string */
char s[] = "Hello World";
reverse(s);
cout << "Reverse of the given string is : " << s;
return 0;
}
This way you can reverse the string.
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
// Function to reverse a given character array using std::reverse
void reverse(char* str)
{
std::reverse(str, str + strlen(str));
}
// main function
int main()
{
/* using C string */
// char s[] = "Techie Delight";
string s = "hello world";
int n = s.length();
// declaring character array
char char_array[n + 1];
// copying the contents of the
// string to char array
strcpy(char_array, s.c_str());
reverse(char_array);
s = char_array;
cout << "Reverse of the given string is : " << s;
return 0;
}
Hope this might Helps:)

Access violation writing location 0x0120FA68

So i'm trying to make a program for c++ that will split up text by spaces and I keep getting the error Access violation writing location 0x0120FA68. Here's the code:
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <list>
#include <vector>
int main(int argc, char* argv[])
{
std::vector<char*> testVector;
char* string1 = "test f";
char seperators[] = " ";
char* token1;
char *next_token1;
int counter = 0;
token1 = strtok_s(string1, seperators, &next_token1);
while (token1 != NULL)
{
if (token1 != NULL)
{
std::cout << "\n" << token1 << std::endl;
testVector.push_back(token1);
token1 = strtok_s(NULL, seperators, &next_token1);
counter++;
}
}
std::cout << testVector.at(0);
system("pause");
return 0;
}
The strtok() family of functions modify their input strings. You are calling it on a string literal, which some compilers store in memory that is not user writeable. You can fix this by using strcpy() to copy the string literal into a buffer that you are then free to modify.

Copy and reverse char* in the C++

I would like to copy reversed char* to the another char*. I miss one letter in the second line of the output.
I did:
#include <iostream>
using namespace std;
void cp(char *str2, char *str1){
char *pom1 = str1;
while(*pom1){
pom1++;
}
char* pom2 = str2;
while(*pom1 != *str1){
pom1--;
*pom2 = *pom1;
pom2++;
}
*pom2 = '\0';
}
int main()
{
char *str1 = "ppC", str2[10] = "Witaj";
cout << "Napis str2 "<< str2 << endl;
cp(str2,str1);
cout << "Napis str2 "<< str2 << endl;
cp(str2,"CJP");
cout << "Napis str2 "<< str2 << endl;
return 0;
}
and the output is:
Napis str2 Witaj
Napis str2 Cp
Napis str2 PJC
While it should be:
Napis str2 Witaj
Napis str2 Cpp
Napis str2 PJC
The bug is in this statement of the function
while(*pom1 != *str1){
There must be
while( pom1 != str1){
Take into account that string literals have type of constant arrays. So for example variable str1 has to be declared as
const char *str1 = "ppC";
Also the function should be declared as
void cp( char *str2, const char *str1 );
Also It will be useful to know that there is standard algorithm std::reverse_copy declared in header <algorithm>:)
There's reverse_copy in the stdlib
... and that it's used like:
template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
auto f = src, l = src + std::strlen(src);
assert(std::distance(f,l) < Ndest);
*(std::reverse_copy(f, l, dest)) = '\0';
}
So, see it Live On Coliru
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cassert>
template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
auto f = src, l = src + std::strlen(src);
assert(std::distance(f,l) < Ndest);
*(std::reverse_copy(f, l, dest)) = '\0';
}
#include <iostream>
int main()
{
char str1[] = "ppC";
char str2[10] = "Witaj";
std::cout << "Napis str2 "<< str2 << std::endl;
cp(str2, str1);
std::cout << "Napis str2 "<< str2 << std::endl;
cp(str2,"CJP");
std::cout << "Napis str2 "<< str2 << std::endl;
return 0;
}
Just use the Standard Library, std::reverse_copy() in this case:
std::reverse_copy( input , input + strlen( input ) , output );
copy paste solution
int len(const char *p) {
int c = 0;
while (*p != '\0')
{
c++;
p++;
}
return(c);
}
void cp(char *str2, const char *str1){
if(!(len(str2)<len(str1))){
const char *pom1 = str1;
while(*pom1){
pom1++;
}
char* pom2 = str2;
while( pom1 != str1){
pom1--;
*pom2 = *pom1;
pom2++;
}
*pom2 = '\0';
}
}

Parse delimited string

How can I get :
connect
100
username
example
from this string:
ngg://connect>100/username>example/
Using std::string::find with arguments "/" and ">" and std::string::substr with the found indexes.
This is a good start.
Adding an answer with strtok for the sake of diversity:
char str[] = "ngg://connect>100/username>example/";
char *s = strtok(str, ">/");
std::vector<std::string> tokens;
while (s = strtok(NULL, ">/"))
tokens.push_back(std::string(s));
This will split the string str into the desired tokens (discarding the first ngg:, like in the question).
Here's a working example of this code.
A possibility is boost::split():
#include <iostream>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
int main()
{
std::vector<std::string> tokens;
std::string s("ngg://connect>100/username>example/");
boost::split(tokens, s, boost::is_any_of("/>"));
// "connect" == tokens[2]
// "100" == tokens[3]
// "username" == tokens[4]
// "example" == tokens[5]
return 0;
}
ngg://connect>100/username>example/
If this format is fixed, then you can use std::sscanf as:
#include <iostream>
#include <cstdio>
int main()
{
char const *input = "ngg://connect>100/username>example/";
char const *input_format = "ngg://%[^>]>%d/%[^>]>%[^/]";
char connect[100], user[100], str[100]; //assuming max size is 100
int num;
if ( std::sscanf(input, input_format, connect, &num, user, str) != 4 )
{
std::cerr<<"error - number of tokens read must be equal to 4";
return 0;
}
std::cout << connect <<std::endl;
std::cout << num <<std::endl;
std::cout << user <<std::endl;
std::cout << str <<std::endl;
}
Output (online demo):
connect
100
username
example