Строковый анализатор

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

Почему код выдает "мусор"
Должен работать так:
Например пишешь 12/23/34
Должен выдать
12
23
34
Только не нужно писать свой код, я хочу понять в чем ошибка

Код: Выделить всё

      #include "stdafx.h"
      #include <conio.h>
      using namespace std;
      class StringParser {
      private:
         int pos;
         char* input_str;
         char* delimiters;
      public:
         int more()   {
         return input_str[pos]!='\0';
                 }
                 StringParser(char* inp, char* delim){
         input_str = inp; delimiters = delim; pos = 0;
                         }
         char* get(){
         int j = 0;
         char* new_str;
         new_str = new char[100];
                 while (! strchr(delimiters, input_str[pos])){
                         new_str[j] = input_str[pos];
             pos++; 
             j++;
             new_str[j]='\0';
                 }
                 while (strchr(delimiters, input_str[pos]))
         pos++;
         return new_str;
         }
      };
      int main() {
         char input_str[100];
         char* ch;      
         cout << "Enter input line: "; 
         cin.getline(input_str, 99);
         StringParser parser(input_str, "/,");
                 while (parser.more()){
                 ch = parser.get();
         cout << ch << endl;
                 delete[]ch;
                 }
         return 0;
      } 
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А дебагером воспользоваться не пробовал? :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

Romeo писал(а):А дебагером воспользоваться не пробовал? :)
Немного переделал код

Код: Выделить всё

      #include "stdafx.h"
      #include <conio.h>
      using namespace std;
      class StringParser {
      private:
         int pos;
         char* input_str;
         char* delimiters;
      public:
         int more()   {
         return input_str[pos]!='\0';
                 }
                 StringParser(char* inp, char* delim){
         input_str = inp; delimiters = delim; pos = 0;
                         }
                 char* get(){
         int j = 0;
         char* new_str;
         new_str = new char[100];
                 while (! strchr(delimiters, input_str[pos])){
                         new_str[j] = input_str[pos];
             pos++; 
             j++;
                 }
                 new_str[j]='\0';
                 while (strchr(delimiters, input_str[pos]))
         pos++;
                 return new_str;
         }
      };
      int main() {
         char input_str[100];
         char* ch;      
         cout << "Enter input line: "; 
         cin.getline(input_str, 99);
         int len=strlen(input_str);
         input_str[len+1]='\0';
         StringParser parser(input_str, "/,");
                 while (parser.more()){
                 ch = parser.get();
         cout << ch << endl;
                 delete[]ch;
                 }
         return 0;
      } 
Все равно не работает
А что за дебагер, не слышал про него
Извините что поздно отвечаю, проблемы с интернетом
azrael
Сообщения: 89
Зарегистрирован: 31 май 2009, 15:30
Контактная информация:

Проблема вот здесь:

Код: Выделить всё

while (strchr(delimiters, input_str[pos]))
         pos++;
Вы не проверяете, что достигли конца строки. До этого программа работает правильно и выводит подстроки по очереди, однако после последнего программа не останавливается на \0, а продолжает искать разделители, пока не залезет в чужую память и не выдаст access violation.
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

ПАсиба !!!!!!!!
Вообще, проверку на '\0' получается надо и здесь делать

Код: Выделить всё

while (! strchr(delimiters, input_str[pos])){
   new_str[j] = input_str[pos];
   pos++;
   j++;
}
new_str[j]='\0';
просто прокатывает то, в new_str[pos] копируется '\0', а потом всякий мусор, пока не встретит разделитель, просто этот мусор не отображается , потому что стоит '\0'
Если здесь не делать проверку на '\0', есть вероятность что new_str[pos] попытается скопировать "запрещенную" память
Правильно ?
azrael
Сообщения: 89
Зарегистрирован: 31 май 2009, 15:30
Контактная информация:

Угу, если введете строку без разделителей, то, скорее всего, так и будет.
Поэтому предлагаю написать все проще, используя функцию strtok. По ссылке есть пример, который делает все что вам надо: http://www.cplusplus.com/reference/clib ... ng/strtok/
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

Да мне просто надо было разобраться с этим примером, потому что я делаю по книге и дальше этот код будет дополняться я правда код немного переделал, потому что как там написано я не понял
Аватара пользователя
rrrFer
Сообщения: 237
Зарегистрирован: 07 сен 2008, 14:15
Контактная информация:

Код: Выделить всё

#include <conio.h>
#include <iostream>
using namespace std;

class StringParser{
	 int pos;
	 char* input_str;
	 char* delimiters;
public:
	int more(){
		return input_str[pos]!=0;
	}

	StringParser(char* inp, char* delim){
		input_str = inp; delimiters = delim; pos = 0;
	}

	char* get(){
		int j = 0;
		char* new_str;
		new_str = new char[100];
		while (! strchr(delimiters, input_str[pos])){
			new_str[j] = input_str[pos];
			pos++;
			j++;
			new_str[j]='\0';
		}
		while (input_str[pos]&&strchr(delimiters, input_str[pos]))
			pos++;
		return new_str;
	}
};
int main() {
	char input_str[100];
	char* ch;      
	cout << "Enter input line: ";
	cin.getline(input_str, 99);
	StringParser parser(input_str, "/,");
	while (parser.more()){
		ch = parser.get();
		cout << ch << endl;
		delete[]ch;
	}
	cin.get();
	return 0;
}
while (input_str[pos]&&strchr(delimiters, input_str[pos]))
pos++;
вот тут вы перепрыгивали через символ конца строки и в ней появлялся мусор, поэтому
int more(){
return input_str[pos]!=0;
}
начинала работать неверно
Приглашаю на свой блог о программировании: pro-prof.com
Ответить