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.
Related
this is my code
the error is Segmentation fault,and i can't understand why
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char* szword[100];
int i = 0;
do
{
cin >> szword[i];
cout << szword[i];
i++;
}while(strcmp(szword[i - 1], "done"));
cout << i + 1;
return 0;
}
For starters neither declaration from headers <cstdio> and <string> is used in your program. So you should remove these directives
#include <cstdio>
#include <string>
You declared an initialized array with the element type char *. Thus this statement
cin >> szword[i];
invokes undefined behavior because the pointer szword[i] has indeterminate value.
Moreover this call even if the argument of the operator will be correct
cin >> szword[i];
can fail. You should check whether it was successful. And I think there is no great sense to output the string "done".
Also in this statement
cout << i + 1;
you are outputting a value that is greater than the number of inputted strings.
If to use character arrays then your program could look the following way
#include <iostream>
#include <cstring>
int main()
{
const size_t N = 100;
char szword[N][N];
size_t i = 0;
while ( std::cin.getline( szword[i], sizeof( szword[i] ) ) &&
std::strcmp( szword[i], "done" ) != 0 )
{
std::cout << szword[i++] << '\n';
}
std::cout << i << '\n';
return 0;
}
The program output might look like
Hello
World
2
This below code works fine, if you want to use char *, for C++ string you can use the C++ version
C Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char *tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(strcmp(tmp, "done"));
cout << i + 1;
return 0;
}
C++ Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
string tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(tmp != "done"));
cout << i + 1;
return 0;
}
I want to remove a character ('#') from a string,
I tried to check if the string has '#' with the find function, which it does, then erase this with the erase function.
For some reason I get a run time error that says I have no memory.
Error: std::out_of_range at memory location 0x003BF3B4
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
std::string str = "Hello World#";
if (str.find('#')) {
str.erase('#');
}
return 0;
}
The excepted output is: "Hello World"
Try something like this:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), '#'), str.end());
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string s = "Hello World#";
char c = '#';
/* Removing character c from s */
s.erase(std::remove(s.begin(), s.end(), c), s.end());
std::cout << "\nString after removing the character "
<< c << " : " << s;
}
If you want to delete all '#' from the string:
std::string str = "Hello World#";
std::size_t pos = str.find('#');
while(pos != std::string::npos)
{
str.erase(pos, 1); //<- edited here
pos = str.find('#');
}
cout << str;
I want compare if both sequence are equals and i'm using the following code but comparation always return false.
=========================================================================
// testecompare.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
char currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
strcat(currentDir, "\\l0gs.txt");
return string(currentDir);
}
string ReadFileContent() {
string STRING;
string aux;
ifstream infile;
infile.open(getCurrentDirectoryOnWindows());
while (!infile.eof())
{
getline(infile, STRING);
return STRING;
}
infile.close();
return "";
}
int _tmain(int argc, _TCHAR* argv[])
{
char str[MAXCHAR] = "";
sprintf(str, "0x0%X", "1D203E5");
cout << str << endl;
cout << "File content: " << ReadFileContent() << endl;
// if i have the string "0x01D203E5" in my txt file
if (_stricmp(str,ReadFileContent().c_str()) == 0) {
cout << "Contents are equals!\n";
}
system("pause");
return 0;
}
How make this comparation correctly?
Thank you very much.
An easy trick for comparing instances of different types is to convert them to a common type then compare.
So for example:
std::string content(ReadFileContent());
std::string from_array(str)
if (from_array == content)
{
}
Edit 1: Working example
The code works.
Here is a working program:
#include <iostream>
#include <string>
int main()
{
static const char text[] = "Hello";
std::string text_as_string(text);
std::string expected_str("Hello");
if (text_as_string == expected_str)
{
std::cout << "Strings are equal: " << text_as_string << "\n";
}
else
{
std::cout << "Strings are not equal.\n";
}
return 0;
}
$ g++ -o main.exe main.cpp
$ ./main.exe
Strings are equal: Hello
Remember, the above code samples are compare entire or whole strings, not substrings. If you want to search for a key string within a larger string, that requires different functions.
I'm trying to push some const char* into a vector, but the vector remains unpopulated after performing the operations I would presume to fill it.
Here's my attempt, where dict is my command-line argument.
test.cc
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
ifstream dict;
size_t dict_size;
dict.open(argv[1]); // Dictionary
vector<const char*> dictionary;
string line;
getline(dict, line);
while(!dict.fail()) {
dictionary.push_back(line.c_str());
getline(dict, line);
}
dict_size = dictionary.size();
for(int i = 0; i < dict_size; i++)
cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}
dict
Hello
World
Foo
Bar
After compiling this, I get the following output:
dictionary[0] is
dictionary[1] is
dictionary[2] is
dictionary[3] is
However, if I change the dictionary's type to vector and push back line instead of line.c_str(), I get the expected output:
dictionary[0] is Hello
dictionary[1] is World
dictionary[2] is Foo
dictionary[3] is Bar
I'm not terribly familiar with C style strings, so maybe it has something to do with null termination?
You are storing dangling pointers.
std::string::c_str() isn't a pointer to some permanent copy of data — just think, that would be leaked!
Store the std::strings instead.
Your code invokes undefined behavior, because after you do
dictionary.push_back(line.c_str());
On the next line that pointer may get deleted:
getline(dict, line); // line now is a different string
You are pushing into the dictionary pointers that point to the same address and at the last iteration it fills the memory area with an empty string. If you don't care about memory leakage you can try like this:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
ifstream dict;
size_t dict_size;
dict.open(argv[1]); // Dictionary
vector<char *> dictionary;
while(!dict.fail()) {
string * line = new string();
getline(dict, *line);
if(line->length()>0)
{
dictionary.push_back((char *)line->c_str());
}
}
dict_size = dictionary.size();
for(int i = 0; i < dict_size; i++)
cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}
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