我试图制作一个以特定方式修改单词的程序: 它应首先检查单词的结尾,然后继续修改它们。我不会详细解释它,因为它在英语中没有多大意义。 我写了以下内容:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Por favor, introduzca los gentilicios separados por la tecla enter, para finalizar, escriba OK" << '\n';
string name[10];
string place[10];
for (int i(0); (i < 10); i++)
{
getline(cin, name[i]);
if (name[i] == "OK") //Error here
break;
}
for (int i(0); (i < 10); i++)
{
place[i] = name[i];
if (name[i][name[i].length() - 1] == 'c')
{
if (name[i][name[i].length()] == 'a' || (name[i][name[i].length()] == 'o') || (name[i][name[i].length()] == 'u'))
place[i][place[i].length() - 1] = 'q';
place[i][place[i].length()] = 'u';
place[i] = place[i] + "istan";
}
else if (name[i][name[i].length()] == 'a' || name[i][name[i].length()] == 'e' || name[i][name[i].length()] == 'i' || name[i][name[i].length()] == 'o' || name[i][name[i].length()] == 'u')
{
place[i][place[i].length()] = 'i';
place[i] = place[i] + "stan";
}
if (name[i][name[i].length()] == 's')
place[i] = place[i] + "tan";
else {
place[i] = place[i] + "istan";
}
place[i][0] = toupper(place[i][0]);
}
for (int i(0); (i < 10); i++)
{
cout << place[i] << '\n';
}
return 0;
}
现在我收到错误&#34;字符串下标超出范围&#34; 。我想知道错误到底在哪里。我知道它在我写#34; OK&#34;,在#34; 18&#34;线时提示。
答案 0 :(得分:1)
条件i <= sizeof(name)
。 sizeof(name)
以 bytes 返回数组的大小,不其中的元素数。即使它返回了元素数量,<=
也是错误的并且会导致越界访问(应该是<
)。
要循环遍历数组中的所有元素,可以使用基于范围的for循环:
for(auto& n : name)
{
getline(cin, n);
if (n == "OK")
break;
}
或者以正确的方式使用C风格的for循环:
for (int i(0); i < sizeof(name)/sizeof(name[0]; i++)
{
…
}
答案 1 :(得分:0)
下面:
for (int i(0); (i <= sizeof(name)); i++)
sizeof(name)是数组的字节大小,因为它是std :: string的数组实际上没有意义。如果你想迭代10个项目,那么就这么说(注意这里的小于或等于也是错误的):
for (int i = 0; i < 10; i++)
在这里:
getline(cin, name[i]);
无论何时执行输入,都必须检查输入函数的返回值并处理任何错误:
if( ! getline(cin, name[i]) ) {
// handle error somehow
}
在这里:
string * p;
你不想要处理指向字符串的指针。如果要访问字符串的内容,可以在字符串上使用operator []或其他字符串成员函数。
答案 2 :(得分:0)
std::string
与cstrings不同。你可以使用std::string*
抓住其中的一部分。当你这样做
*(p+ (name[i].length()-2))
您实际上是说将p
中存储的地址提前name[i].length()-2
金额并访问该字符串。如果超过name
数组的末尾,那么这是未定义的行为。如果不是,您仍有std::string
无法与char
进行比较。如果要检查字符串是否以"ca"
结尾,则可以使用
if (name[i].substr(name[i].size() - 2) == "ca")
答案 3 :(得分:0)
你最后一个循环是做一些非常时髦的事情。没有必要走那么远。你可以这样做:
if (name[i][name[i].length - 2] == 'c')
将下一个到最后一个字符与c进行比较。还有一个非常相似的测试来比较最后一个和。
为了澄清为什么你做的不行,你首先得到p
作为指向当前元素的字符串的指针。然后你做一些指针算术p + (name[i].length - 2)
,它仍然会产生一个指向字符串的指针。最后,你取消引用它,产生一个字符串。哪个你不能比较char。此外,指针指向内存中的某个任意地址,因此取消引用会产生一个字符串,其中包含非常糟糕的数据。有人可能会说,这很随意。如果您尝试使用它,则会破坏您的程序
您似乎正在使用字符串,就像使用类似C的字符串char*
一样。两者并不相同,即使它们代表相同的概念。 C ++字符串通常有一个size字段,里面有一个char*
指针,还有一堆其他逻辑可以使用 char -m。
答案 4 :(得分:0)
因为您没有与字符串中的特定字符进行比较,您正在与字符串进行比较。
考虑以下代码:
*(p + (name[i].length() - 2))
这会计算为字符串,因为您正在使用 p (字符串*)并将char连接到它。这意味着它的仍然是一个字符串(即使它是一个单字符串),因此等式的另一面将无法与它相比。
这里你需要的是:
if (name[i][name[i].length() - 2] == 'c')
由于 name [i] 已经是一个字符串,我们可以使用上面的代码从中获取 char 。这个 返回char,因此它具有可比性。这也允许你删除整个字符串*位,因为它不需要。
答案 5 :(得分:0)
首先,(i <= sizeof(name))
是错误的,它应该是i < sizeof(name) / sizeof(*name)
。 sizeof(array)
以字节为单位返回array
的大小,您需要将array
元素的大小除以实际获取数组的最大元素数。如果您发现那么复杂,请使用std::vector
:
vector<string> name(10); //a vector of size 10
for (size_t i = 0; i < name.size(); i++) //name.size(), simple
其次,您需要跟踪name
数组中的字符串数。或者你需要检查name[i] == "OK"
是否打破第二个循环(类似于第一个循环)。 <{1}}无效后name[i]
。
第三,不要使用"OK"
。如果您想要*(p+ (name[i].length()-2))
的倒数第二个字符,可以将其写为name[i]
或name[i][name[i].size()-2]
或name[i].end()[-2]
如果您想检查单词是否以“ca”结尾,那么您可以使用substr
:
end(name[i])[-2]