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
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?
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:)
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.
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';
}
}
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