Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: [c++] есть ошибка но нет решения  (Прочитано 2434 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
[c++] есть ошибка но нет решения
« : 16 Октября 2010, 20:26:16 »
Добрый вечер. Осмелюсь снова потревожить сообщество ))

имеется вот такой вот код:

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

int SimbolEntersCount()
{
    unsigned int i;
    char s[] = "012 34 567 89 ABCDEF";

    char re;
    cout << "xxx" << endl;
    char temp[4] = {10, 13, 32, 0};
    bool p = 0;
    for (i=1;i<sizeof(s);++i)
        {   int i_;
        cout << " i = " << i << endl;


            for (i_ = 0; i_<3; ++i_)
                {
                    cout << " i = " << i << "\ti_ = "<< i_<< endl;

                    if (p==1){break;};
                    if (s[i]!=temp[i_])
                    {
                        strcat (&re, &s[i]);
                        p=1;
                        cout << " "<< re <<endl;
                    };
                };
                p=0;


        };
    return re;
};

int main(){int a = SimbolEntersCount();}

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

kisly@kisly-desktop:~/c++/temp_2/bin/Debug$ gdb ./temp_2
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/kisly/c++/temp_2/bin/Debug/temp_2...done.
(gdb) run
Starting program: /home/kisly/c++/temp_2/bin/Debug/temp_2
xxx
 i = 1
 i = 1 i_ = 0

Program received signal SIGSEGV, Segmentation fault.
0x002dbf67 in strcat () from /lib/tls/i686/cmov/libc.so.6

(gdb) bt
#0  0x002dbf67 in strcat () from /lib/tls/i686/cmov/libc.so.6
#1  0x080489b4 in SimbolEntersCount () at /home/kisly/c++/temp_2/main.cpp:29
#2  0x32314645 in ?? ()
#3  0x20343320 in ?? ()
#4  0x20373635 in ?? ()
#5  0x41203938 in ?? ()
#6  0x45444342 in ?? ()
#7  0x20323146 in ?? ()
#8  0x35203433 in ?? ()
#9  0x38203736 in ?? ()
... ... ...

насколько я понимаю происходит выход за рамки массива. так ? как это исправить ? спрашиваю т.к. уже не первый день думаю на этим.

В теории код должен копировать сл. код ( строки вывода на экран и там и там не имеют значения, они для контроля ):
  begin
  s:= '012 34 567 89 ABCDEF';
    Result := '';
    writeln(s, ' ', Length(s));
    for i := 1 to Length(s) do
    begin writeln('i = ',i);
      if not(s[i] in [' ',#10,#13]) then
        Result:=Result+s[i];
        writeln(Result);

    end;
end.
       

Вопросы:
1. как заставить работать программу ?
2. есть ли в с++ аналог делфийского IN  ? чтобы не делать таких вавилонов
3. что означает символ & (амперсанд \ символьное and) ? на другом форуме мне посоветовали его поставить, чтобы компилирование вообще состаялось ((
4. Почему в char temp[4] = {10, 13, 32, 0}; при знесении не 4х, а 5 элементов массива компилятор грязно ругается ? ведь зарезервировал я 5 элементов (0,1,2,3,4) ?
« Последнее редактирование: 16 Октября 2010, 20:53:45 от kisly »

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #1 : 16 Октября 2010, 21:23:50 »
Вопросы:
1. как заставить работать программу ?
2. есть ли в с++ аналог делфийского IN  ? чтобы не делать таких вавилонов
3. что означает символ & (амперсанд \ символьное and) ? на другом форуме мне посоветовали его поставить, чтобы компилирование вообще состаялось ((
4. Почему в char temp[4] = {10, 13, 32, 0}; при знесении не 4х, а 5 элементов массива компилятор грязно ругается ? ведь зарезервировал я 5 элементов (0,1,2,3,4) ?

Вообще это не С++ это C, с использованием cout ;)

1. написать правильно
2. смотри в сторону STL, ЕМНИП там есть функции, которые могут облегчить жизнь
3. & ? Если ты про  strcat (&re, &s[i]); то это - взятие адреса
4. зарезервировано как раз 4 (сколько попросил), нумеруемые с 0 до 3-х, потому и ругается

По совокупности — читать книжки. Если читаешь по-английски, можно начать с чего-нибудь типа "Thinking in C++", Bruce Eckel

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
Re: [c++] есть ошибка но нет решения
« Ответ #2 : 16 Октября 2010, 22:13:12 »
ммм.. понятно. "будем искать.."(c)
жаль только, что на англицком я не читаю.

посмотрим что ним скажет Гугл-квадратная Земля..

// афигеть я 10 минут потратил на то чтобы узнать что такое ЕМНИП ))
а по существу я в шоке.. ничего узнаваемого. нужно читать.. может есть что-то на русском ?

Оффлайн -=Иван=-

  • Участник
  • *
  • Сообщений: 134
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #3 : 16 Октября 2010, 23:25:09 »
ммм.. понятно. "будем искать.."(c)
жаль только, что на англицком я не читаю.

посмотрим что ним скажет Гугл-квадратная Земля..

// афигеть я 10 минут потратил на то чтобы узнать что такое ЕМНИП ))
а по существу я в шоке.. ничего узнаваемого. нужно читать.. может есть что-то на русском ?
По си если пожалуй Керниган и Ритчи - Программирование на C тока новое издание а не первое оно уже устарело
Текстовый редактор vi имеет два режима работы: в первом он пищит, а во втором — всё портит.

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #4 : 17 Октября 2010, 01:05:08 »
В теории код должен копировать сл. код ( строки вывода на экран и там и там не имеют значения, они для контроля ):
  begin
  s:= '012 34 567 89 ABCDEF';
    Result := '';
    writeln(s, ' ', Length(s));
    for i := 1 to Length(s) do
    begin writeln('i = ',i);
      if not(s[i] in [' ',#10,#13]) then
        Result:=Result+s[i];
        writeln(Result);

    end;
end.

Всё-таки, а что в теории должен делать этот код? Судя по названию Си-эквивалента должен считать количество переносов строк (причём судя по #10,#13, переносов, как их знает виндоуз), а судя по реализации он тупо объединяет все строки в одну длинную строку.

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
Re: [c++] есть ошибка но нет решения
« Ответ #5 : 17 Октября 2010, 01:10:11 »
клд должен проверять строку на наличие трех запрещенных символов (пробел, переход на новую строку, и переход в начало строки). и выдавать должен строку без этих символов.
например с пробелами:
012 34 567 89 ABCDEF

должен выдать:
0123456789ABCDEF

Пользователь решил продолжить мысль 17 Октября 2010, 01:22:53:
Цитировать
int SimbolEntersCount()
{
    unsigned int i;
    char s[] = "012 34 567 89 ABCDEF";

    char re;
    cout << re << endl;
    char temp[3] = {10, 13, 32};
    char si;
    for (i=0;i<sizeof(s)-1;++i)
        {
            cout << " i = " << i << endl;
            if (s!=temp[0])
                {
                    if (s!=temp[1])
                        {
                            if (s!=temp[2])
                                {   si = s;
                                strcat (&re, &si);  }; // вот этот элемент кочевряжется !!!!!
                        };
                };
            cout << "re= " << re << endl;
        };
    return (int)re;
};

Пользователь решил продолжить мысль 17 Октября 2010, 01:25:22:
это я попил кофейку, удалил предыдущее и  переписал

Пользователь решил продолжить мысль 17 Октября 2010, 01:27:24:
PS не я так обзывал функцию ))

Пользователь решил продолжить мысль 17 Октября 2010, 01:38:56:
Везде нужно внимание.. Нашел часть ошибки
« Последнее редактирование: 17 Октября 2010, 01:38:56 от kisly »

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #6 : 17 Октября 2010, 02:09:23 »
клд должен проверять строку на наличие трех запрещенных символов (пробел, переход на новую строку, и переход в начало строки). и выдавать должен строку без этих символов.
например с пробелами:
012 34 567 89 ABCDEF

должен выдать:
0123456789ABCDEF

Что-то типа вот такого:
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

struct is_to_be_removed
{
    bool operator()(char c)
    {
        const string to_remove = "\r\a ";
        size_t beg = to_remove.find_first_of(c);
        return (beg != string::npos);
    }
};

int main()
{
    string in = "012 34 567 89 ABCDEF";
    cout << in << endl;
    cout << "xxx" << endl;
    in.erase(remove_if(in.begin(), in.end(), is_to_be_removed()), in.end());
    cout << in << endl;
    return 0;
}

Функтор is_to_be_removed можно сделать более умным (задавать параметры что-же отсеивать при его создании, например).

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
Re: [c++] есть ошибка но нет решения
« Ответ #7 : 17 Октября 2010, 02:16:45 »
Это классно, но я еще не созрел. Ну жно сначала стандартные с/с++ запомнить ))

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #8 : 17 Октября 2010, 02:21:21 »
Это классно, но я еще не созрел. Ну жно сначала стандартные с/с++ запомнить ))
Это и есть стандартный C++, используется стандартный метод класса string и стандартный алгоритм remove_if с самописной функцией-предикатом.

По поводу исходника выше: под строку, в которую что-то копируешь, нужно память бы выделить, а то у тебя там сейчас входит один символ всего ;)

Пользователь решил продолжить мысль 17 Октября 2010, 02:40:40:
Вот нарисовал, простое копирование с проверкой на ненужные символы, Си-стайл, рисовалось на коленке, нужно допиливать:
#include <string.h>
#include <stdio.h>

int is_forbidden(char c)
{
    char forbidden[3] = {10, 13, 32};
    int i = 0;
    int found = 0;
    for (i = 0; i<strlen(forbidden); ++i)
    {
        if( c == forbidden[i])
        {
            found = 1;
            break;
        }   
    }
    return found;
}

int SimbolEntersCount()
{
    unsigned int i;
    char s[] = "012 34 567 89 ABCDEF";
    char re[128]; /* Внимание! 128 будет мало для реальных данных */
    int j = 0;
    printf("xxx\n");
    for (i=0;i<sizeof(s);++i)
    {
        if (!is_forbidden(s[i]) )
        {
            re[j] = s[i];
            j++;
        }
    }
    printf("%s\n", re);
    return 0;
};

int main(){int a = SimbolEntersCount();}
« Последнее редактирование: 17 Октября 2010, 02:40:40 от Kwah »

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
Re: [c++] есть ошибка но нет решения
« Ответ #9 : 17 Октября 2010, 14:14:13 »
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

int SimbolEntersCount()
{
    unsigned int i;
    char s[] = "012 34 567 89 ABCDEF";

    char re[21] ={0};
    cout << re << endl;
    char temp[3] = {10, 13, 32};
    char si[10];
    for (i=0;i<sizeof(s)-1;++i)
        {
            cout << " i = " << i << endl;
            if (s[i]!=temp[0])
                {
                    if (s[i]!=temp[1])
                        {
                            if (s[i]!=temp[2])
                                {   si[0] = s[i];
                                cout<<si<<endl;
                                strcat (&re[0], &si[0]);
                                };
                        };
                };
            cout << "re= " << re << endl;
        };
    return (int)re;
};

так  ?

Оффлайн mkarasik

  • Участник
  • *
  • Сообщений: 163
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #10 : 17 Октября 2010, 16:53:14 »
Ну выход за пределы массива ты нашел
sizeof(s) - 1
Апдейт небольшой. в принципе можно и не отнимать 1, тогда тупо конец строки '\0' скопируется.

Теперь осталось понять что ты делаешь. Вот это, постоянно копирует всю строку.
strcat (&re[0], &si[0]);
Тебе нужно держать два индекса один для массива re другой для массива s (i уже есть), и копировать символы по одному

re[j++] = s[i];
при этом индех массива re должен продвигаться только если елемент был валидный типа как вверху.

И не слушай никого, пока не научишься руками (по одному карактеру в цикле) строки обрабатывать нефиг тебе в C++ лезть, в его классы.

А то понавырастало, мля,  программистов, которым уже и 4-х ядерных процессоров мало. Понаворотят 3 десятка классов вокруг одного флага и считают это тру OOB С++.
Никого не хотел обидеть, но не нужно человеку STL пихать, если он еще по массиву ходить не умеет.

« Последнее редактирование: 17 Октября 2010, 16:56:23 от mkarasik »

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
Re: [c++] есть ошибка но нет решения
« Ответ #11 : 17 Октября 2010, 18:04:43 »
Цитировать
Апдейт небольшой. в принципе можно и не отнимать 1, тогда тупо конец строки '\0' скопируется.
и в делфи первый элемент строки нумеруется с "1", а не с "0".

и еще. допустим функция возвращает re

char SimbolEntersCount()
    {бла бла бла;
             return re; // /home/kisly/c++/temp_2/main.cpp|33|error: invalid conversion from ‘char*’ to ‘char’|
    };

как вернуть значене всей строки ? один элемент то возвращается.. а вот строка
« Последнее редактирование: 17 Октября 2010, 18:12:40 от kisly »

Оффлайн ierofant

  • Любитель
  • *
  • Сообщений: 52
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #12 : 17 Октября 2010, 18:37:52 »
Если уж вы пишете на c++, то и используйте std::string и возвращайте её сколько душе угодно.

Оффлайн mkarasik

  • Участник
  • *
  • Сообщений: 163
    • Просмотр профиля
Re: [c++] есть ошибка но нет решения
« Ответ #13 : 17 Октября 2010, 19:40:21 »
Цитировать
и в делфи первый элемент строки нумеруется с "1", а не с "0".


Это к чему? Речь о C++ если я правильно читать умею.

Цитировать
как вернуть значене всей строки ? один элемент то возвращается.. а вот строка

Возвращать массив re нельзя, потому что он находиться на стеке и после выхода из функции его существование абсолютно непредсказуемое. Если нужно вернуть строку то нужно возвращать char*. При этом они должны находиться в сегменте данных или быть аллокированными из кучи. Про возвращение классов не пишу, это отдельная история.

Куча

char * SimbolEntersCount()
...
re = new ...
...
return re;
..

или из сегмента данных

Цитировать
char * SimbolEntersCount()
...
static char re[128];
...
return re;

Оба способа кривоваты. Почему лень писать.

Оффлайн iamkisly

  • Автор темы
  • Любитель
  • *
  • Сообщений: 93
  • это я в 10 лет назад
    • Просмотр профиля
    • Электроника как хобби
Re: [c++] есть ошибка но нет решения
« Ответ #14 : 17 Октября 2010, 20:04:04 »
Цитировать
и в делфи первый элемент строки нумеруется с "1", а не с "0".


Это к чему? Речь о C++ если я правильно читать умею.

к тому,что переписываю код с делфи.

 

Страница сгенерирована за 0.023 секунд. Запросов: 21.