Как упоминалось Ларсом Нощинским, вам нужно исправить выход Out-File
. Вы можете установить DefaultParameter Out-File, используя следующие команды.
$PSDefaultParameterValues['Out-File:Encoding'] = 'ASCII'
$PSDefaultParameterValues['Out-File:Width'] = '2147483647'
После настройки параметров по умолчанию вы можете использовать >
для экспорта файла патча.
После добавив эти две строки в файл моего профиля, все работает так, как ожидалось.
λ git stash show -p > test3
C:\Users\..\Source\.. [master +1 ~0 -0 !]
λ git apply test3
C:\Users\..\Source\.. [master +1 ~2 -0 !]
Если это имеет значение вот другой способ извлечь маркеры из входной строки, полагаясь только на стандартные средства библиотеки. Это - пример питания и элегантности позади дизайна STL.
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
int main() {
using namespace std;
string sentence = "And I feel fine...";
istringstream iss(sentence);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
ostream_iterator<string>(cout, "\n"));
}
Вместо того, чтобы копировать извлеченные маркеры в поток вывода, можно было вставить их в контейнер, с помощью того же дженерика copy
алгоритм.
vector<string> tokens;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(tokens));
... или создают vector
непосредственно:
vector<string> tokens{istream_iterator<string>{iss},
istream_iterator<string>{}};
Для смехотворно большого и вероятно избыточная версия, попробуйте много из за циклы.
string stringlist[10];
int count = 0;
for (int i = 0; i < sequence.length(); i++)
{
if (sequence[i] == ' ')
{
stringlist[count] = sequence.substr(0, i);
sequence.erase(0, i+1);
i = 0;
count++;
}
else if (i == sequence.length()-1) // Last word
{
stringlist[count] = sequence.substr(0, i+1);
}
}
Это не симпатично, но в общем и целом (Запрещающий пунктуацию и убивание других ошибок), это работает!
Мне нравится следующее, потому что это помещает результаты в вектор, поддерживает строку как delim и дает контроль над хранением пустых значений. Но, это не смотрит как хорошее тогда.
#include <ostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
vector<string> split(const string& s, const string& delim, const bool keep_empty = true) {
vector<string> result;
if (delim.empty()) {
result.push_back(s);
return result;
}
string::const_iterator substart = s.begin(), subend;
while (true) {
subend = search(substart, s.end(), delim.begin(), delim.end());
string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(temp);
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}
int main() {
const vector<string> words = split("So close no matter how far", " ");
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
}
, Конечно, Повышение имеет split()
, который работает частично как этот. И, если 'пробелом', Вы действительно подразумеваете, что любой тип пробела, с помощью разделения Повышения с is_any_of()
работает отлично.
STL уже не имеет такой метод в наличии.
Однако можно или использовать C strtok()
функция при помощи std::string::c_str()
участник, или можно записать собственное. Вот пример кода, который я нашел после быстрого поиска Google ( "строковое разделение STL" ):
void Tokenize(const string& str,
vector<string>& tokens,
const string& delimiters = " ")
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
Взятый от: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
, Если у Вас есть вопросы о примере кода, оставьте комментарий, и я объясню.
И просто потому что это не реализует typedef
названный итератором или перегружается <<
, оператор не означает, что это - плохой код. Я использую функции C вполне часто. Например, printf
и scanf
и быстрее, чем [1 115] std::cin
и std::cout
(значительно), fopen
, синтаксис является намного более дружественным для двоичных типов, и они также имеют тенденцию производить меньший EXEs.
не становятся проданными на этом "Элегантность по производительности" соглашение.
Это подобно Stack вопрос о Переполнении , Как я маркирую строку в C++? .
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int argc, char** argv)
{
string text = "token test\tstring";
char_separator<char> sep(" \t");
tokenizer<char_separator<char>> tokens(text, sep);
for (const string& t : tokens)
{
cout << t << "." << endl;
}
}
Это - мой любимый способ выполнить итерации через строку. Можно сделать то, что Вы хотите на слово.
string line = "a line of text to iterate through";
string word;
istringstream iss(line, istringstream::in);
while( iss >> word )
{
// Do something on `word` here...
}
Я использую это для разделения строки разделителем. Первое помещает результаты в предварительно созданный вектор, вторые возвраты новый вектор.
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
*(result++) = item;
}
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
<час> Примечание, что это решение не пропускает пустые маркеры, таким образом, следующее найдет 4 объекта, один из которых пуст:
std::vector<std::string> x = split("one:two::three", ':');
Используя std::stringstream
, поскольку Вы имеете превосходные работы, и делаете точно, что Вы хотели. Если Вы просто ищете различный способ сделать вещи, хотя, можно использовать std::find()
/ std::find_first_of()
и std::string::substr()
.
Вот пример:
#include <iostream>
#include <string>
int main()
{
std::string s("Somewhere down the road");
std::string::size_type prev_pos = 0, pos = 0;
while( (pos = s.find(' ', pos)) != std::string::npos )
{
std::string substring( s.substr(prev_pos, pos-prev_pos) );
std::cout << substring << '\n';
prev_pos = ++pos;
}
std::string substring( s.substr(prev_pos, pos-prev_pos) ); // Last word
std::cout << substring << '\n';
return 0;
}
Возможное решение с помощью Повышения могло бы быть:
#include <boost/algorithm/string.hpp>
std::vector<std::string> strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));
Этот подход мог бы быть еще быстрее, чем эти stringstream
подход. И так как это - универсальная шаблонная функция, она может использоваться для разделения других типов строк (wchar, и т.д. или UTF-8) использующий все виды разделителей.
Посмотрите документация для деталей.
В общем, не рекомендуется смешивать универсальные шаблоны и массивы в Java, лучше использовать ArrayList.
Если вам необходимо использовать массив, лучший способ справиться с этим - поставить создание массива (ваш пример 2 или 3) отдельным методом и аннотируйте его с помощью @SuppressWarnings ("unchecked").
Также с помощью идеальных типов параметров вы можете удалить все копии строк и списков для дополнительного увеличения скорости.Кроме того, он не возвращает (крайне неэффективно) результат, а передает токены в качестве ссылки, что также позволяет вам для создания токенов с помощью нескольких вызовов, если вы того пожелаете.
Наконец, он позволяет указать, следует ли вырезать пустые токены из результатов с помощью последнего необязательного параметра.
Все, что ему нужно, это std :: string
... остальные необязательны. Он не использует потоки или библиотеку ускорения, но достаточно гибок, чтобы принимать некоторые из этих внешних типов естественным образом.
Наконец, он позволяет указать, следует ли вырезать пустые токены из результатов с помощью последнего необязательного параметра.
Все, что ему нужно, это std :: string
... остальные необязательны. Он не использует потоки или библиотеку ускорения, но достаточно гибок, чтобы принимать некоторые из этих внешних типов естественным образом.
Наконец, он позволяет указать, следует ли вырезать пустые токены из результатов с помощью последнего необязательного параметра.
Все, что ему нужно, это std :: string
... остальные необязательны. Он не использует потоки или библиотеку ускорения, но достаточно гибок, чтобы принимать некоторые из этих внешних типов естественным образом.
Вот еще один способ...
void split_string(string text,vector<string>& words)
{
int i=0;
char ch;
string word;
while(ch=text[i++])
{
if (isspace(ch))
{
if (!word.empty())
{
words.push_back(word);
}
word = "";
}
else
{
word += ch;
}
}
if (!word.empty())
{
words.push_back(word);
}
}
Еще один гибкий и быстрый способ
template<typename Operator>
void tokenize(Operator& op, const char* input, const char* delimiters) {
const char* s = input;
const char* e = s;
while (*e != 0) {
e = s;
while (*e != 0 && strchr(delimiters, *e) == 0) ++e;
if (e - s > 0) {
op(s, e - s);
}
s = e + 1;
}
}
Использовать его с вектором строк (Edit: Since someone pointed not to inherit STL classes... hrmf ;) ) :
template<class ContainerType>
class Appender {
public:
Appender(ContainerType& container) : container_(container) {;}
void operator() (const char* s, unsigned length) {
container_.push_back(std::string(s,length));
}
private:
ContainerType& container_;
};
std::vector<std::string> strVector;
Appender v(strVector);
tokenize(v, "A number of words to be tokenized", " \t");
Вот и все! И это только один из способов использования токенизатора, например, как просто считать слова:
class WordCounter {
public:
WordCounter() : noOfWords(0) {}
void operator() (const char*, unsigned) {
++noOfWords;
}
unsigned noOfWords;
};
WordCounter wc;
tokenize(wc, "A number of words to be counted", " \t");
ASSERT( wc.noOfWords == 7 );
Ограничено воображением ;)
Существует функция с именем strtok
.
#include<string>
using namespace std;
vector<string> split(char* str,const char* delim)
{
char* saveptr;
char* token = strtok_r(str,delim,&saveptr);
vector<string> result;
while(token != NULL)
{
result.push_back(token);
token = strtok_r(NULL,delim,&saveptr);
}
return result;
}
Я использую этот простак, потому что мы получили наш класс String "специальный" (т.е. не стандартный):
void splitString(const String &s, const String &delim, std::vector<String> &result) {
const int l = delim.length();
int f = 0;
int i = s.indexOf(delim,f);
while (i>=0) {
String token( i-f > 0 ? s.substring(f,i-f) : "");
result.push_back(token);
f=i+l;
i = s.indexOf(delim,f);
}
String token = s.substring(f);
result.push_back(token);
}