التعبير: سلسلة ITERATAR
-
21-08-2019 - |
سؤال
أواجه صعوبة في استخدام std :: string :: Iterators في C ++. يجمع هذا الرمز بشكل جيد (لا يزال لا يحصل على الإخراج الصحيح ، ولكن هذا خطأي: TODO ، إصلاح الخوارزمية) في DEV-C ++ ، ولا أحصل على أخطاء في وقت التشغيل. الخطأ هو مع Visual Studio Express 2008 C ++ ، حيث أحصل على خطأ يشير إلى <xstring>: "التعبير: سلسلة Iterator غير قابلة للإزالة" ، وتشير إلى السطر 112 من ملف <xstring>.
يخبرني تصحيح أخطاءي أنني ربما أحاول التخلص من نهاية مدخلات الجملة ، لكن لا يمكنني رؤية أين. يمكن لأي شخص أن يلقي بعض الضوء؟
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it < sentence.end())
{
while (*it != ' ' && it != sentence.end())
{
nextWordLength++;
distanceFromWidth--;
it++;
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
it++;
}
return sentence;
}
المحلول
أولاً ، استخدم المشغل! = () على المتكررين ، وليس المشغل <():
while (it != sentence.end())
ثانياً ، هذا متخلف: while (*it != ' ' && it != sentence.end())
يمكنك القيام بشيء مع التكرار ، بدلاً من التحقق مما إذا كان التكرار صالحًا. بدلاً من ذلك ، يجب عليك التحقق مما إذا كان صحيحًا أولاً:
while (it != sentence.end() && *it != ' ')
ثالثًا ، يجب عليك استخدام ++ ITerator عبر ITerator ++ ، على الرغم من أن هذا لا يرتبط بالتعطل.
رابعًا ، هناك قضية رئيسية هنا:
*it = '\n';
بسبب الشيك السابق ، while (it != sentence.end()
, ، من الممكن الوصول إلى هذا التكرار أثناء التواجد في النهاية. سيكون الإصلاح هو القيام بذلك:
if (it != sentence.end() && nextWordLength > distanceFromWidth)
حتى الآن إذا وصلت إلى النهاية ، تتوقف.
بعد إصلاح العدد السابق ، الآن المشكلة الوحيدة هي:
//skip the space
++it;
هذا يفترض أن الشخصية التي تتخطى هي في الواقع مساحة. ولكن ماذا عن نهاية السلسلة؟ قم بتشغيل هذه الوظيفة بهذه السلسلة:
"a test string " // <- space at end
وسوف ينجح يتخطى المساحة ، ويضع التكرار في end()
, ، الحلقة تخرج والنجاح.
ومع ذلك ، بدون المساحة ، ستعطل ، لأنك وصلت إلى النهاية ، وتتخطى النهاية. للإصلاح ، أضف شيكًا:
//skip the space
if (it != sentence.end())
{
++it;
}
مما أدى إلى هذا الرمز النهائي:
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (it != sentence.end() && *it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
}
if (it != sentence.end() && nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
if (it != sentence.end())
{
++it;
}
}
return sentence;
}
قد تلاحظ أن هذا يبدو أنه يحتوي على الكثير من الشيكات الزائدة. يمكن إصلاح هذا:
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (*it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
// check if done
if (it == sentence.end())
{
return sentence;
}
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
++it;
}
return sentence;
}
نأمل أن يساعد ذلك!
نصائح أخرى
while (*it != ' ' && it != sentence.end())
تغيير الى
while (it != sentence.end() && *it != ' ')
لذلك لا يتم تقييم التعبير الثاني إذا كان الأول إذا كان خطأ.
if (nextWordLength > distanceFromWidth)
ربما يجب أن تتغير إلى
if (it == sentence.end())
break;
if (nextWordLength > distanceFromWidth)
من شبه المؤكد أن خطأك هو نتيجة:
*it = '\n';
لأنه في السابق بينما حلقة واحدة من ظروف التوقف الخاصة بك هي:
it != sentence.end()
إذا كان ذلك == sectence.end () ، فلن يطير *= ' n'
هناك المزيد من الأخطاء ، ولكن هذا هو الأخطاء التي تسبب مشكلتك الحالية.