c ++在我的程序中遇到奇怪的崩溃

时间:2017-04-20 06:51:44

标签: c++ arrays char

#include <iostream>


using namespace std;

int main()
{
    int a = 0, skrb = 0, j = 0;
    char b, simboliai[2000];
    char zodis[50][20]; 
    char check[1][20] = {'f'};
    cout << "Prasome irasykite sakini: ";
    cin.getline(simboliai,sizeof(simboliai));
//----------------- Zodziu skaidymas ----------------------------------------------------------------------------------------------------------
    a = 0;
    for (int i = 0; i > -1; i++)
    {
        if ((simboliai[i] == 's' && simboliai[i++] == ' ') || (simboliai[i] == 's' && simboliai[i++] == '\n'))
        {
            check[0][a] = 't';
        }
        if (simboliai[i] == ' ')
        {
            a++;
        }
        else
        {
            zodis[i][a] = simboliai[i];
        }
        if (simboliai[i] == '\n')
        {
            break;
        }
    }
    a = 0;
    while (1)
    {
        if (simboliai[a] == '.' || simboliai[a] == ',' || simboliai[a] == '!' || simboliai[a] == '?')
        {
            skrb++;
        }
        a++;
        if (simboliai[a] == '\n')
        {
            break;
        }
    }
    a = 0;
    cout << "Jus ivedete tokius zodius kurie baigiasi raide 's'" << endl;
    while(1)
    {
        if (zodis[j][a] == 'Ì')
        {
            cout << '\n';
            a++;
        }
        if (check[0][a] == 't')
        {
            cout << zodis[j][a];
        }
        if (zodis[0][a] == 'Ì')
        {
            break;
        }
    }
    cout << "Pas jus yra (.','!'?) simboliu: " << skrb << endl;
    cin.ignore();
    cin.get();
}

基本上这个程序可以工作,但部分只是破坏了一切。它不会逐个放置字符。当我调试时,它显示程序已将符号放在其位置,但之后有Ì。 所以它看起来就像这样 输入:单词 zodis [0] [0]像zodis [1] [0]那样变成了粉末,然后它就会破碎。提前谢谢。

2 个答案:

答案 0 :(得分:0)

for (int i = 0; i > -1; i++)
{
   ...
}

是主要问题。可能还有其他人,但我不能过分关注他们。

i的值将为0,1,2等。
所有这些都大于-1 循环将继续,直到值i达到INT_MAX。 (不确定当i递增时会发生什么)。

无论如何,这大于数组simboliai的大小。您的程序将访问超出有效限制的数组simboliai并导致未定义的行为。

我认为你需要的是:

size_t len = strlen(simboliai);
for (size_t i = 0; i < len; i++)
{
   ...
}

其他问题

  1. 有些错误是因为假设simboliai中有换行符。这个假设是不正确的。 std::istream::getline读取并丢弃换行符。

  2. 如果Google翻译是正确的,zodis应该包含单词列表。当你迭代simboliai的字符时,你需要三个计数器。

    1. 一个用于迭代simboliai
    2. 的字符
    3. 一个跟踪数字的人。
    4. 一个用于跟踪当前单词中的字符数。
    5. 您的for循环没有这样做。

    6. 当您尝试访问数组的内容时,您需要始终编写防御性代码并确保永远不会使用越界索引访问数组。在上一个while循环中,您没有这样做。

    7. 在上一个while循环中,您只在第一个a块中递增if。如果if语句的条件求值为false,则a永远不会增加,并且会陷入无限循环。

    8. 在最后一个循环中,您使用j作为索引,但其值在函数开头初始化为0,并且永远不会更新。目前尚不清楚最后一个while循环的意图是什么。因此,我无法说出它是否是一个错误,但听起来可能就是这样。

    9. 这是您发布的代码的清理版本,但仍有一些未知数。

      #include <iostream>
      #include <cstring>
      
      using namespace std;
      
      int main()
      {
         int a = 0, skrb = 0, j = 0;
         char b, simboliai[2000];
         char zodis[50][20]; 
         char check[1][20] = {'f'};
         cout << "Prasome irasykite sakini: ";
         cin.getline(simboliai,sizeof(simboliai));
         //----------------- Zodziu skaidymas ----------------------------------------------------------------------------------------------------------
         int word_counter = 0;
         a = 0;
         size_t len = std::strlen(simboliai);
         for (size_t i = 0; i < len; i++)
         {
            if ((simboliai[i] == 's' && simboliai[i+1] == ' ') || (simboliai[i] == 's' && simboliai[i+1] == '\0'))
            {
               check[0][a] = 't';
            }
            if (simboliai[i] == ' ')
            {
               zodis[word_counter][a] = '\0';
               a = 0;
               ++word_counter;
            }
            else
            {
               zodis[word_counter][a] = simboliai[i];
               ++a;
            }
         }
      
         a = 0;
         while ( simboliai[a] != '\0' )
         {
            if (simboliai[a] == '.' || simboliai[a] == ',' || simboliai[a] == '!' || simboliai[a] == '?')
            {
               skrb++;
            }
            a++;
         }
      
         a = 0;
         cout << "Jus ivedete tokius zodius kurie baigiasi raide 's'" << endl;
         while( j < 50 && a < 20 )
         {
            if (zodis[j][a] == 'Ì')
            {
               cout << '\n';
            }
            if (check[0][a] == 't')
            {
               cout << zodis[j][a];
            }
            if (zodis[0][a] == 'Ì')
            {
               break;
            }
            a++;
         }
         cout << "Pas jus yra (.','!'?) simboliu: " << skrb << endl;
         cin.ignore();
         cin.get();
      }
      

答案 1 :(得分:0)

如果你说for循环不会将字符1放1,那就是你的“simboliai [i ++] =='''逻辑。当当前字符为's'时,整数'i'在每个循环中递增两次,这意味着如果simboliai [i] ='s',它将从i = 2增加到i = 4。请使用i + 1进行检查。