I am trying to tokenize a database dump separated by commas. I only need to read the first word, which will tell me if this is the line I need and then tokenize the line and save each separated string in a vector.
I have had trouble keeping all of the datatypes in order. I use a method of getline:
string line;
vector<string> tokens;
// Iterate through each line of the file
while( getline( file, line ) )
{
// Here is where i want to tokenize. strtok however uses a character array and not a string.
}
The thing is, I only want to continue reading and tokenize a line if the first word is what I am after. Here is a sample of a line from the file:
example,1,200,200,220,10,550,550,550,0,100,0,-84,255
So, if I am after the string example, it goes ahead and tokenizes the rest of the line for my use and then stops reading from the file.
Should I be using strtok, stringstream or something else?
Thank you!
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void do(ifstream& file) {
string line;
string prefix = "example,";
// Get all lines from the file
while (getline(file,line).good()) {
// Compare the beginning for your prefix
if (line.compare(0, prefix.size(), prefix) == 0) {
// Homemade tokenization
vector<string> tokens;
int oldpos = 0;
int pos;
while ((pos = line.find(',', oldpos)) != string::npos) {
tokens.push_back(line.substr(oldpos, pos-oldpos));
oldpos = pos + 1;
}
tokens.push_back(line.substr(oldpos)); // don't forget the last bit
// And here you are!
}
}
}
How do I tokenize a string in C++?
http://www.daniweb.com/software-development/cpp/threads/27905
Hope this helps, though I am not proficient C/C++ programmer. For the record it would be nice if you could specify in the tags or in post language you are using.
Tokenizer.h
#ifndef TOKENIZER_H
#define TOKENIZER_H
#include <string>
#include <vector>
#include <sstream>
class Tokenizer
{
public:
Tokenizer();
~Tokenizer();
void Tokenize(std::string& str, std::vector<std::string>& tokens);
};
#endif /* TOKENIZER_H */
Tokenizer.cpp
#include "Tokenizer.h"
using namespace std;
string seps(string& s) {
if (!s.size()) return "";
stringstream ss;
ss << s[0];
for (int i = 1; i < s.size(); i++)
ss << '|' << s[i];
return ss.str();
}
void tok(string& str, vector<string>& tokens, const string& delimiters = ",")
{
seps(str);
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
Tokenizer::Tokenizer()
{
}
void Tokenizer::Tokenize(string& str, vector<string>& tokens)
{
tok(seps(str), tokens);
}
Tokenizer::~Tokenizer()
{
}
To tokenize a string
#include "Tokenizer.h"
#include <string>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
// Required variables for later below
vector<string> t;
string s = "This is one string,This is another,And this is another one aswell.";
// What you need to include:
Tokenizer tokenizer;
tokenizer.Tokenize(s, t); // s = a string to tokenize, t = vector to store tokens
// Below is just to show the tokens in the vector<string> (c++11+)
for (auto c : t)
cout << c << endl;
system("pause");
return 0;
}
Related
I was trying to make a program write 8 words to a line after a user enter their sentence.Its only printing words that have been typed in and i don't have a clue how to make it type 8 words to a line.
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using namespace std;
vector<string> sentence;
string sente = "";
void print(string, string);
template<typename T>
void print(vector<T>& v, string)
{
cout << "Enter your sentence " << endl;
getline(cin, sente);
sentence.push_back(sente);
for (auto const elem: sentence)
{
cout << elem;
}
}
int main()
{
print(sentence,sente);
}
Using global variables is generally not a good practice.
Also you don't need a extra vector for your use case.
Take a look at the following code, where you can smartly make use of istringstream for your use case:
#include <iostream>
#include <string>
#include <sstream>
void print()
{
std::string sente;
std::cout << "Enter your sentence " << std::endl;
getline(std::cin, sente);
// Used to split string around spaces.
std::istringstream ss(sente);
int wordCountPerLine = 0;
int requiredWordsPerLine = 8;
// Traverse through all words
do {
// Read a word
std::string word;
ss >> word;
// Print the read word
std::cout << word << " ";
wordCountPerLine++;
if(wordCountPerLine % requiredWordsPerLine == 0){
std::cout<<std::endl;
wordCountPerLine = 0;
}
// While there is more to read
} while (ss);
}
int main()
{
print();
}
Feel free to ask any doubts.
In my source file when I define my object s, Visual Studios says Identifier "stack" is undefined. I'm pretty sure I've separated the headers correctly but I don't know why I'm getting this error. Also side note when I put everything together in one source file and compile it, it just exits immediately without any reason. Thanks for the help in advance.
This is the source file
// pa3.cpp : Defines the entry point for the console application.
//
#include "stack.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
//#include <ctype.h>
using namespace std;
int main()
{
//int count;
stack s; //assign s object to stack
string input;
cout << "Please enter the name of the input file: \n";
//cin >> input;
getline(cin, input);
ifstream file(input);
string readline;
//ifstream file(input);
while (getline(file, readline)) //take first line of file and assign to readline
{
s.push(readline); //send it off to push
s.retrieveUPPER();
//file.close();
system("pause");
}
return 0;
}
This is the stack.h file
//#pragma once
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
//#include <ctype.h>
using namespace std;
class stack
{
public:
int count;
void push(string);
//void pop();
void check(string);
void retrieveUPPER();
private:
static string firstline[1];
static string diskeywords[3];
static char upperword[100];
static char lowerword[100];
static char operatorsarr[100];
static char delimitersarr[100];
};
This is the stack.cpp
#include "stack.h"
#include "stdafx.h"
#include <iostream>
string stack::firstline[1] = { 0 };
string stack::diskeywords[3];
char stack::upperword[100];
char stack::lowerword[100];
char stack::operatorsarr[100];
char stack::delimitersarr[100];
void stack::retrieveUPPER()
{
for (int i = 0; i < 100; i++)
{
cout << upperword[i] << "\n";
}
}
void stack::push(string readline)
{
firstline[0] = readline;
count++;
check(readline);
}
void stack::check(string readline)
{
int length;
char letter;
int leftperenthe = 0;
int rightperenthe = 0;
//int capital;
//int wordFOR;
//int wordBEGIN;
//char keywords[3][8] = { "FOR", "BEGIN", "END" };
char operators[] = "+-=*/;";
char delimiters[] = { ',',';' };
length = readline.length();
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 5; j++)
{
letter = readline[i];
if (isupper(letter)) //if capital letter
{
upperword[i] = letter;
}
else if (islower(letter)) //if lowercase letter
{
lowerword[i] = letter;
}
else if (letter == operators[j]) //if encounters a operator
{
operatorsarr[i] = letter;
}
else if (letter == delimiters[j]) //if encounters a delimiter
{
delimitersarr[i] = letter;
}
else if (letter = ' ') //if encounters a space
{
lowerword[i] = ' ';
operatorsarr[i] = ' ';
delimitersarr[i] = ' ';
}
else if (letter = '(') //if left perenthesis
{
leftperenthe++;
}
else if (letter = ')') //if right perenthesis
{
rightperenthe++;
}
}
}
}
I also had a similar situation:
#include<iostream>
#include<stack.h>
#include<vector>
using namespace std;
int main();
std::vector<int>stickPan (std::vector<int>arr)
{
stack<int>s;
...
}
I used VScode, used mingw-w64, and added paths for * .h files to .json files, but it didn't work.
Errors are reported:
identifier "stack" is undefined.
type name is not allowed.
identifier "s" is undefined
i have created my own shell in linux. it works fine with commmands. Now I want to add pipes in it. i want to implement multiple piping in it. Can some one guide me how to do do? I havent used Linux. Iam new to it.
I have seen many source codes and sites but i am still not clear about the idea of executing commands having multiple pipes!
This is code i have implemented so far!
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <cstring>
#include <sys/types.h>
using namespace std;
int main ()
{
while (true){
char * input;
string insert;
char * token;
char * parsed[9];
int count=0;
char * cmd1[6];
char * cmd2[6];
cout<<"My Shell $";
getline(cin,insert); // take input from user
input= new char [insert.size()+1];
strcpy(input, insert.c_str());
for (int i=0; i<9; i++)
parsed[i]=NULL;
token=strtok(input, " ");
while (token!=NULL) // parse the input
{
parsed[count] = new char[strlen(token) + 1];
strcpy(parsed[count++],token);
token=strtok(NULL, " ");
}
delete input;
delete token;
int j= count-1;
int pipe_position[4]={0};
int counter=0;
for (int i=0; i<j; i++) // finding position of pipe
{
if ((strcmp(parsed[i],"|"))==0)
pipe_position[counter++]=i;
}
bool pipe_exists=false;
if (pipe_position[0]!=0)
pipe_exists=true;
if(pipe_exists==false) // if there isnt any pipe in the command
{
pid_t mypid=fork();
if (mypid==0)
{
execlp (parsed[0],parsed[0],parsed[1],parsed[2],parsed[3],parsed[4], parsed[5],parsed[6],parsed[7],parsed[8],(char*) NULL);
}
else if (mypid>0)
{
wait(NULL);
for(int i=0; i<9; i++)
delete[]parsed[i];
}
}
} //end of while
}
I have a function in C++ that have a value in std::string type and would like to convert it to String^.
void(String ^outValue)
{
std::string str("Hello World");
outValue = str;
}
From MSDN:
#include <string>
#include <iostream>
using namespace System;
using namespace std;
int main() {
string str = "test";
String^ newSystemString = gcnew String(str.c_str());
}
http://msdn.microsoft.com/en-us/library/ms235219.aspx
Googling reveals marshal_as (untested):
// marshal_as_test.cpp
// compile with: /clr
#include <stdlib.h>
#include <string>
#include <msclr\marshal_cppstd.h>
using namespace System;
using namespace msclr::interop;
int main() {
std::string message = "Test String to Marshal";
String^ result;
result = marshal_as<String^>( message );
return 0;
}
Also see Overview of Marshaling.
As far as I got it, at least the marshal_as approach (not sure about gcnew String) will lead to non ASCII UTF-8 characters in the std::string to be broken.
Based on what I've found on https://bytes.com/topic/c-sharp/answers/725734-utf-8-std-string-system-string I've build this solution which seems to work for me at least with German diacritics:
System::String^ StdStringToUTF16(std::string s)
{
cli::array<System::Byte>^ a = gcnew cli::array<System::Byte>(s.length());
int i = s.length();
while (i-- > 0)
{
a[i] = s[i];
}
return System::Text::Encoding::UTF8->GetString(a);
}
The question is in the title. Need help figuring out why my code compiles but doesn't work as intended. Thanks!
//This example demonstrates how to do vector<string> to vectro<int> conversion using a function.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
vector<int>* convertStringVectorToIntVector (vector<string> *vectorOfStrings)
{
vector<int> *vectorOfIntegers = new vector<int>;
int x;
for (int i=0; i<vectorOfStrings->size(); i++)
{
stringstream str(vectorOfStrings->at(i));
str >> x;
vectorOfIntegers->push_back(x);
}
return vectorOfIntegers;
}
int main(int argc, char* argv[]) {
//Initialize test vector to use for conversion
vector<string> *vectorOfStringTypes = new vector<string>();
vectorOfStringTypes->push_back("1");
vectorOfStringTypes->push_back("10");
vectorOfStringTypes->push_back("100");
delete vectorOfStringTypes;
//Initialize target vector to store conversion result
vector<int> *vectorOfIntTypes;
vectorOfIntTypes = convertStringVectorToIntVector(vectorOfStringTypes);
//Test if conversion is successful and the new vector is open for manipulation
int sum = 0;
for (int i=0; i<vectorOfIntTypes->size(); i++)
{
sum+=vectorOfIntTypes->at(i);
cout<<sum<<endl;
}
delete vectorOfIntTypes;
cin.get();
return 0;
}
The code above has only one problem: You are deleting your vectorOfStringTypes before you pass it to your conversion function.
Move the line delete vectorOfStringTypes; to after you have called your convert function and the program works as intended.