Некоторые проблемы с использованием указателей для ввода строки - PullRequest
1 голос
/ 17 февраля 2010

Я новичок, и мне нужно задать вопрос .. Я написал этот небольшой код, который принимает строку от пользователя и печатает ее ... очень просто.

#include <iostream>

using namespace std;

int main()
{
   int i;
   char *p = new char[1];

   for(i = 0 ; *(p+i) ; i++) 
     *(p+i) = getchar();

   *(p+i) = 0;

   for(i = 0 ; *(p+i) ; i++) 
     putchar(*(p+i));

   return 0;
}

когда я введу любую строку, например, например, "переполнение стека" ... она выведет "sta" и удалит оставшуюся часть строки Я знаю, что это легко решить, но так как я только начал, я не могу понять, что здесь не так. Заранее спасибо.

Ответы [ 5 ]

5 голосов
/ 17 февраля 2010

Есть несколько проблем с этим кодом.Во-первых, у вас переполнение буфера, поскольку char *p = new char[1] выделяет для хранения только один символ.Это превышено, когда i > 0.Затем ваш первый цикл будет продолжаться до тех пор, пока не достигнет точки в нераспределенной памяти (неопределенное поведение), которая имеет значение ноль.Это просто случается после третьего значения в вашем случае.Вы, вероятно, хотели что-то вроде *(p+i-1) == 0, чтобы дать «последний прочитанный символ соответствует некоторому условию».Наконец, вы выделяете память с помощью new[] и неправильно освобождаете ее с помощью delete[].

. Попробуйте использовать std::cin и std::string для более безопасного и правильного кода:

#include <iostream>
#include <string>

int main(int, char**) {
   std::string s;

   std::cout << "Enter a string: ";
   std::cin >> s;

   std::cout << s << std::endl;
}
1 голос
/ 17 февраля 2010

Вот код, который, похоже, работает. Я уверен, что есть лучшие (и больше C ++ - иш) способы сделать это ...

#include <iostream>
using namespace std;

#define MAXLEN 80

int main()
{
    int i=0;
    char c;

    char *p = new char[MAXLEN + 1];  // 1 char will not be sufficient

    do  // Doing this with a for loop would be unreadable
    {
         c = getchar();
         *(p+i) = c;
         i++;
    } while( c != '\n' && i < MAXLEN ); // Check for a newline. How do you enter the zero with a keyboard?
    *(p+i) = 0; // Ensure that the last character is zero

    for(i = 0 ; *(p+i) ; i++) putchar(*(p+i));  // This is OK but difficult to read

    delete [] p;  // Don't forget this

    return 0;
 }
0 голосов
/ 17 февраля 2010

Если вы читаете в память, убедитесь, что вы выделяете достаточно. new char[1] создает массив только из одного символа, но вы читаете больше этого. Простым временным решением было бы просто выделить больше, скажем, new char[255].

Другие примечания:

  • вы никогда не удаляете выделенную память: delete[] p;
  • Вы должны проверить, читаете ли вы столько символов, сколько может вместить ваш буфер: for(..;.. && i<bufferSize;..)
  • условие в первом цикле всегда проверяет следующий символ, а не то, что вы только что прочитали
  • *(p+i) эквивалентно p[i], что более читабельно
  • зачем читать и писать только один символ за раз?
  • почему бы не использовать iostreams (std::in, std::out) и std::string при использовании C ++?
0 голосов
/ 17 февраля 2010

Вы выделяете место только для одного персонажа, но пытаетесь добавить в него много символов.

Это домашнее задание? если так, пожалуйста, пометьте его как таковой. Вам разрешено использовать STL?

Если это так, тогда используйте std :: vector вместо нового символа [1];

РЕДАКТИРОВАТЬ: сделать это без каких-либо неудобных битов или STL

  const int MAX = 100;
  char *p=new char[MAX];
  for(i = 0 ; *(p+i) && i < MAX ; i++) 
      *(p+i) = getchar();

вероятно, некоторые по одному - оставлено как упражнение

0 голосов
/ 17 февраля 2010

То, что ваша программа что-то делает, - просто удача; что мешает *(p+i) быть \0 для начала? Странно, что вы используете getchar() и putchar() в программе на C ++. Какова история этой программы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...