在 C++ 中旋转单词并收到错误
Spinning words in C++ and recieving error
我正在尝试根据下面的提示创建一个程序,但我一直收到 Caught std::exception, what(): basic_string::at: __n (which is 0) >= this->size() (which is 0)
错误,虽然我在 C++ 方面很扎实,但我想时间会造成损失。我的代码在下面。基本上,首先我按 space 字符解析字符串并将它们保存在 vector<string>
中,然后我检查一个单词是否大于 5,如果是则反转它,如果不是则什么都不做。如果不是最后一个词,我会在末尾添加一个 space。 Bing 砰砰,提示完成,至少我是这么认为的。
std::string spinWords(const std::string &str)
{
std::vector<std::string> words;
std::string spinnedWord;
int count = 0;
for(unsigned int i = 0; i < str.length(); i++)
{
char currentChar = str.at(i);
if (currentChar == ' ')
{
count++;
continue;
}
else if((int)words.size() == count)
{
words.push_back(¤tChar);
}
else
{
words[count] += currentChar;
}
}
for(unsigned int i = 0; i < words.size(); i++)
{
if(words[i].size() >= 5)
{
for (unsigned int j = words[i].length() - 1; j >= 0; j--)
{
spinnedWord += words[j].at(i);
}
}
if(i + 1 != words.size())
{
spinnedWord += ' ';
}
}
return spinnedWord;
}// spinWords
Write a function that takes in a string of one or more words, and
returns the same string, but with all five or more letter words
reversed (Just like the name of this Kata). Strings passed in will
consist of only letters and spaces. Spaces will be included only when
more than one word is present.
Edit1:我已将 words[j].at(i);
更改为 words[i].at(j);
我已经将 words.push_back(¤tChar);
更改为 words.push_back(std::string(1, currentChar));
据我目前了解,当我向后推 ¤tChar
时,我导致了未定义的行为。我将研究如何在未来避免这种情况。但是之前的错误依然存在,所以问题仍然没有答案
words.push_back(¤tChar);
您正在尝试从指向单个字符的指针构造 std::string
。这会编译,因为有一个匹配的构造函数,但它需要一个 C 风格的字符串,而你指向单个字符的指针不是。
for (unsigned int j = words[i].length() - 1; j >= 0; j--)
{
spinnedWord += words[j].at(i);
}
您在这里交换了 j
和 i
。必须是 words[i].at(j)
。另外 j
在这里可能不应该是无符号的,因为循环条件 j >= 0
对于无符号整数总是成立的。
编辑:words.push_back(¤tChar)
行的 UB 问题也是有效的。修复它的方法是明确地从 char
构造一个字符串:
words.push_back(std::string(1, currentChar));
说实话我连你的代码都看不懂。例如变量 count
在程序中的作用。或者为什么你要使用像 std::vector
这样的额外容器,而所有这些都可以并且应该使用 std::string
类型的对象来完成,因为它拥有完成任务的所有资源。
容器std::vector
仅当分配是将字符串拆分为词和return类型std::vector<std::string>
对象中的词时才需要。但是你的任务完全不同。
注意单词之间一般可以有多个space。即使在任何情况下都不是这样,您也应该使用通用方法而不是依赖于单词之间只有一个 space.
您的函数没有意义,例如当原始字符串从 space 字符开始时。在这种情况下 count
将等于 1
由于这个 if 语句
if (currentChar == ' ')
{
count++;
continue;
}
但是vector的大小会等于0,所以words.size()
不等于count
那么就会执行else语句
else if((int)words.size() == count)
{
words.push_back(¤tChar);
}
else
{
words[count] += currentChar;
}
这会导致未定义的行为。
我可以建议以下解决方案。在下面的演示程序中,我没有使用标准算法std::reverse,因为我认为您必须通过自己的代码来反转单词。
给你。
#include <iostream>
#include <string>
#include <utility>
std::string spinWords( const std::string &s, std::string::size_type length = 5 )
{
std::string t( s );
const char *delim = " \t";
for ( std::string::size_type i = 0; i != t.size(); )
{
auto pos = t.find_first_not_of( delim, i );
if ( pos != std::string::npos )
{
i = t.find_first_of( delim, pos );
if ( i == std::string::npos ) i = t.size();
if ( length < i - pos )
{
auto n = i - pos;
for ( std::string::size_type j = 0; j < n / 2; j++ )
{
std::swap( t[pos + j], t[i - j - 1] );
}
}
}
else
{
i = t.size();
}
}
return t;
}
int main()
{
std::string s( "1 12 123 1234 12345 123456 1234567 123456789 1234567890" );
std::cout << s << '\n';
std::cout << spinWords( s ) << '\n';
return 0;
}
程序输出为
1 12 123 1234 12345 123456 1234567 123456789 1234567890
1 12 123 1234 12345 654321 7654321 987654321 0987654321
我正在尝试根据下面的提示创建一个程序,但我一直收到 Caught std::exception, what(): basic_string::at: __n (which is 0) >= this->size() (which is 0)
错误,虽然我在 C++ 方面很扎实,但我想时间会造成损失。我的代码在下面。基本上,首先我按 space 字符解析字符串并将它们保存在 vector<string>
中,然后我检查一个单词是否大于 5,如果是则反转它,如果不是则什么都不做。如果不是最后一个词,我会在末尾添加一个 space。 Bing 砰砰,提示完成,至少我是这么认为的。
std::string spinWords(const std::string &str)
{
std::vector<std::string> words;
std::string spinnedWord;
int count = 0;
for(unsigned int i = 0; i < str.length(); i++)
{
char currentChar = str.at(i);
if (currentChar == ' ')
{
count++;
continue;
}
else if((int)words.size() == count)
{
words.push_back(¤tChar);
}
else
{
words[count] += currentChar;
}
}
for(unsigned int i = 0; i < words.size(); i++)
{
if(words[i].size() >= 5)
{
for (unsigned int j = words[i].length() - 1; j >= 0; j--)
{
spinnedWord += words[j].at(i);
}
}
if(i + 1 != words.size())
{
spinnedWord += ' ';
}
}
return spinnedWord;
}// spinWords
Write a function that takes in a string of one or more words, and returns the same string, but with all five or more letter words reversed (Just like the name of this Kata). Strings passed in will consist of only letters and spaces. Spaces will be included only when more than one word is present.
Edit1:我已将 words[j].at(i);
更改为 words[i].at(j);
我已经将 words.push_back(¤tChar);
更改为 words.push_back(std::string(1, currentChar));
据我目前了解,当我向后推 ¤tChar
时,我导致了未定义的行为。我将研究如何在未来避免这种情况。但是之前的错误依然存在,所以问题仍然没有答案
words.push_back(¤tChar);
您正在尝试从指向单个字符的指针构造 std::string
。这会编译,因为有一个匹配的构造函数,但它需要一个 C 风格的字符串,而你指向单个字符的指针不是。
for (unsigned int j = words[i].length() - 1; j >= 0; j--)
{
spinnedWord += words[j].at(i);
}
您在这里交换了 j
和 i
。必须是 words[i].at(j)
。另外 j
在这里可能不应该是无符号的,因为循环条件 j >= 0
对于无符号整数总是成立的。
编辑:words.push_back(¤tChar)
行的 UB 问题也是有效的。修复它的方法是明确地从 char
构造一个字符串:
words.push_back(std::string(1, currentChar));
说实话我连你的代码都看不懂。例如变量 count
在程序中的作用。或者为什么你要使用像 std::vector
这样的额外容器,而所有这些都可以并且应该使用 std::string
类型的对象来完成,因为它拥有完成任务的所有资源。
容器std::vector
仅当分配是将字符串拆分为词和return类型std::vector<std::string>
对象中的词时才需要。但是你的任务完全不同。
注意单词之间一般可以有多个space。即使在任何情况下都不是这样,您也应该使用通用方法而不是依赖于单词之间只有一个 space.
您的函数没有意义,例如当原始字符串从 space 字符开始时。在这种情况下 count
将等于 1
由于这个 if 语句
if (currentChar == ' ')
{
count++;
continue;
}
但是vector的大小会等于0,所以words.size()
不等于count
那么就会执行else语句
else if((int)words.size() == count)
{
words.push_back(¤tChar);
}
else
{
words[count] += currentChar;
}
这会导致未定义的行为。
我可以建议以下解决方案。在下面的演示程序中,我没有使用标准算法std::reverse,因为我认为您必须通过自己的代码来反转单词。
给你。
#include <iostream>
#include <string>
#include <utility>
std::string spinWords( const std::string &s, std::string::size_type length = 5 )
{
std::string t( s );
const char *delim = " \t";
for ( std::string::size_type i = 0; i != t.size(); )
{
auto pos = t.find_first_not_of( delim, i );
if ( pos != std::string::npos )
{
i = t.find_first_of( delim, pos );
if ( i == std::string::npos ) i = t.size();
if ( length < i - pos )
{
auto n = i - pos;
for ( std::string::size_type j = 0; j < n / 2; j++ )
{
std::swap( t[pos + j], t[i - j - 1] );
}
}
}
else
{
i = t.size();
}
}
return t;
}
int main()
{
std::string s( "1 12 123 1234 12345 123456 1234567 123456789 1234567890" );
std::cout << s << '\n';
std::cout << spinWords( s ) << '\n';
return 0;
}
程序输出为
1 12 123 1234 12345 123456 1234567 123456789 1234567890
1 12 123 1234 12345 654321 7654321 987654321 0987654321