Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/76: Рейтинг темы: голосов - 76, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 09.03.2020
Сообщений: 25
1

Найти длину строки, без использования функции strlen()

02.04.2020, 13:50. Показов 15561. Ответов 115
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Написать функцию, которая получает строку и возвращает длину строки. Без использования функции strlen ()
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.04.2020, 13:50
Ответы с готовыми решениями:

Узнать длину строки не щитая функции strlen
Как узнать длину строки не щитая функции strlen?

Написать программу, которая определяет длину строки - strlen (число символов без завершающего нуль-символа)
Написать программу с помощью символьных строк и функции обработки строк. Библиотечные функции...

Функция strlen возвращает неверную длину строки
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int main () {...

Подскажите функцию, которая возвращает длину строки (string), strlen не подходит.
Подскажите функцию, которая возвращает длину строки (string), strlen не подходит!!!!!!

115
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 20:00 81
Author24 — интернет-сервис помощи студентам
TheCalligrapher, IGPIGP, смекетил. Сие код символа?
Почитал пару статей в интернете об итераторах. Получается, что итератор, это не указатель, а некая абстракция, позволяющая получить доступ к любому элемента контейнера, в свою очередь, хранящего любые данные одного типа.

Добавлено через 6 минут
И, как я понял, в разименованном виде представляет доступ к первому элементу массива, т.е. в данном случае, к коду символа строки. Соответственно, .end() в разименованном виде хранит ноль.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.04.2020, 20:03 82
Цитата Сообщение от Argus19 Посмотреть сообщение
позволяющая получить доступ к любому элемента контейнера
слово "любому" - лишнее.

Цитата Сообщение от Argus19 Посмотреть сообщение
в свою очередь, хранящего любые данные одного типа.
словосочетание "одного типа" - лишнее.

Цитата Сообщение от Argus19 Посмотреть сообщение
в разименованном виде представляет доступ к первому элементу массива
слово "к первому" - лишнее.

Добавлено через 48 секунд
Цитата Сообщение от Argus19 Посмотреть сообщение
Соответственно, .end() в разименованном виде
разыменовывание end-iterator`a - UB
0
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 20:07 83
Цитата Сообщение от hoggy Посмотреть сообщение
словосочетание "одного типа" - лишнее.
Надо понимать, что в любой контейнер можно поместить любые данные?
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,066
03.04.2020, 20:08 84
Цитата Сообщение от Argus19 Посмотреть сообщение
Соответственно, .end() в разименованном виде хранит ноль.
Если бы разрешалось разыменовывать end() - то да, вы бы там увидели ноль. Но формально end() разыменовывать не разрешается.

И существование этого нуля там под end() - особенность именно std::string. В других контейнерах end() указывает на "пустоту". Никакого нуля там ожидать не приходится.
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.04.2020, 20:09 85
Цитата Сообщение от Argus19 Посмотреть сообщение
Соответственно, .end() в разименованном виде хранит ноль.

Не надо его разыменовывать. Отделите терминатора от контейнеров. Он же амбал и всё там поломает) Перечитайте. Абстракция хвостового терминатора полезна в смысле поддержки оператора сравнения на равенство (в общем случае). Но это просто метка. Он не указывает на физический объект в обычной реализации. И ещё его можно приравнять. end() к iterator a cend() к const_iterator.
Как итераторы поодерживыают константность в отличие от указателей это отдельная песня)
Argus19, тема может охватить весь С++)
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.04.2020, 20:16 86
Цитата Сообщение от Argus19 Посмотреть сообщение
Надо понимать, что в любой контейнер можно поместить любые данные?
надо понимать, что это зависит от самого контейнера.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Но формально end() разыменовывать не разрешается.
формально - не запрещается.
0
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 20:28 87
Цитата Сообщение от IGPIGP Посмотреть сообщение
А что в строке было-то?
Проверил. "-61" = "C2" = "В", т.е. первому символу строки.
Извините, что не успеваю ответить сразу.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.04.2020, 20:36 88
Argus19,
Цитата Сообщение от IGPIGP Посмотреть сообщение
хвостового терминатора полезна
итератора. Пардон)
Argus19, си-строка это контекст нашего отношения к конкретному инстансу (экземпляру) указателя на char. Мы должны заранее знать о том, что это строка и следовательно в ней записан терминатор.
Но физически это же блок памяти содержащий массив символов. Наличие терминатора позволяет этому массиву "знать" свой размер в отличие от массива где присутствие такого символа не гарантировано.
Это и делает с-строку эдаким недо-контейнером. Но не за счёт наличия контекста объекта развитого типа (класса или структуры), а путём метаописателя введённого в последовательность данных. И на уровне типа мы не видим разницы между указателем на блок памяти, и указателем на строку. Это наше знание о конкретном указателе char.
Если говорить о указателях, вообще, то мы даже не знаем на один элемент или на блок из нескольких элементов он указывает, если это неизвестно заранее. Но это другая песня.
Когда-нибудь (может быть) вы узнаете что классы можно укладывать в строки и это делается в том или ином формате какого либо метаязыка. Как тут уже было замечено, - на основе соглашения. А
соглашение есть продукт при полном непротивлении сторон
Политика кнута и пряника в данном случае - основа для добровольно-принудительного примирения с реальностью. Так например Кнут создал (для пряников) язык XML (который и используют частенько для сериализации).
В каком-то смысле строки это верх обобщения. Именно они и не горят, как говорил один из главных героев (о которых всуе не говорят) популярного романа известного писателя.
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,066
03.04.2020, 20:40 89
Цитата Сообщение от IGPIGP Посмотреть сообщение
Он не указывает на физический объект
Совершенно не верно.

Ноль в конце std::string доступен только через два механизма: operator [] и c_str()/data(). При этом operator [] возвращает ссылку, то есть lvalue. Таким образом даже на абстрактно-формальном уровне этот ноль - обязательно именно физический объект, без вариантов.

Цитата Сообщение от IGPIGP Посмотреть сообщение
в обычной реализации.
Ну а это уже совсем какая-то чушь. Все "обычные реализации" с самого начала времен просто хранили внутри std::string обычную сишную нуль-терминированную строку. Даже тогда, когда этому не было предпосылок. И тот ноль, который вы видели в этих std::string - это был тот самый ноль в конце этой сишной строки. Т.е. конкретный физический объект.
0
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 20:40 90
Сложновато. Но со временем, станет проще.
Как я понимаю, ТС нас бросил.
Вот последний вариант кода с разными вариантами подсчёта длины строки без использования strlen():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <string>
using namespace std;
//Функции подсчёта символов в строках
/*в VS 2010 (которая опирается на стандарты С++98/03) использовать код,
который смотрит за конец строки std::string без использования 
константной версии operator[], запрещено. Именно этот запрет проверяет
assert внутри неконстантной версии operator[] (который перехватывается
средой в качестве SEH-исключения).*/
unsigned int count(const string str){
    unsigned int i = 0;
    while(str[i] != 0){
        i++;}
    return i;
}
 
unsigned int counter(const string &str){
    unsigned int i = 0;
    while(str[i] != 0){
        i++;}
    return i;
}
 
size_t StringLen(const char  *s)
{
    size_t ln = 0;
    while (s[ln])
        ++ln;
    return ln;
}
 
size_t len(const string &S){
    return S.end() - S.begin();
}
 
size_t leng(const char* S){
    return strchr(S,0) - S;
}
 
size_t lengh(const string &S){      //Если нельзя использовать strlen (), 
    return S.size();                //то size() - можно
}
/*есть тонкость, понимание которой потом поможет при знакомстве с итераторами.
Итерирование с открытой границей - итерирование не до конца, а аж за конец. 
Терминатор это часть структуры C-строка, но мы не считаем его значащим символом
и поэтому длина его не учитывает. То есть, он находится за концом строки.
А итерация на нём и заканчивается. А пост-инкремент догоняет (он неумолим)
и прибавляет ещё единицу - (в результате финальной проверки условия цикла возникает
лишний инкремент значения p.) . Остальное логично. Если бы он последний раз 
не инкрементировался то указывал бы за последний символ и разница давала бы точно то,
что нужно. Если разрушить понт с while без тела
 то в теле можно проверить а потом или break или инкрементировать дальше 
 (тут же в теле). Тогда в условии придётся оставить true или 1.*/ 
size_t StringLeng(const char  *s)
{
    const char  *p=s ;      //указателю присваивается значение указателя на первый символ строки.
    while (*p++) ;          //цикл идёт пока указатель не достигнет конца строки   
    return p-s-1;           //от указателя на конец строки отнимаем указатель на начало переданной строки и лишнюю итерацию
}
 
size_t StringLen1(const char  *s)
{
    const char  *p=s ;
        while(*p){ ++p; };
    return p-s;             //длина в элементах типа char
}
 
int main()
{
      setlocale (LC_ALL, "rus");
    string str = "На берёзе выросли 2 яблока и 3 груши";
    string str1 = "Сидел на ёлке дятел, досиделся - спятил.";
    string str3 = "По глади озера скользили три воробья и ворона.";
    string str4 = "Мряка и Бряка расдрусили пусик.";
    string str5 = "Отплякиваясь от сурых пляк, каждый хамсик шмыряет на глын по 5 гнусиков.";
    string str6 = "Клюша наклюсюкал 256 парфусиков.";
    string str7 = "Плюша наплюфукал в три раза больше парфусиков.";
    string str8 = "Вышел ёжик из тумана, вынул ножик из кармана.";
    cout << str << endl;
      cout << "Количество символов в строке : " << count (str) << endl;
     cout << str1 << endl;  
      cout << "Количество символов в строке : " << StringLen(str1.c_str()) << endl;
     cout << str3 << endl;
      cout << "Количество символов в строке : " << counter (str3) << endl;
     cout << str4 << endl;
      cout << "Количество символов в строке : " << StringLeng (str4.c_str()) << endl;
     cout << str5 << endl;
      cout << "Количество символов в строке : " << len (str5) << endl;
     cout << str6 << endl;
      cout << "Количество символов в строке : " << leng (str6.c_str()) << endl;
     cout << str7 << endl;
      cout << "Количество символов в строке : " << StringLen1(str7.c_str()) << endl;
     cout << str8 << endl;
      cout << "Количество символов в строке : " << lengh (str8.c_str()) << endl;
      system("pause");
return 0;
}
Последние комментарии включать в код не рискнул, чтобы не было "короткого замыкания мозга".
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,066
03.04.2020, 20:45 91
Цитата Сообщение от Argus19 Посмотреть сообщение
C++
1
while(str[i] != 0){
Непонятно, почему во всех остальных вариантах вы используете "сокращенную" форму записи, а здесь вдруг сидит явное сравнение с нулем. Тогда уже просто

C++
1
while(str[i]){
Для единообразия.

Хотя я бы посоветовал наоборот - везде писать сравнения явно, кроме выраженно булевских значений.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.04.2020, 20:55 92
Я опечатался написав терминатор но потом извинился:
Цитата Сообщение от IGPIGP Посмотреть сообщение
итератора. Пардон)
хотя в контексте (оператор сравнения на равенство и пр.) здоровому человек ясно что это не о символе '\0'.
И подробнее.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Он не указывает на физический объект
Совершенно не верно.
Ноль в конце std::string доступен только через два механизма: operator [] и c_str()/data(). При этом operator [] возвращает ссылку, то есть lvalue. Таким образом даже на абстрактно-формальном уровне этот ноль - обязательно именно физический объект, без вариантов.
TheCalligrapher, не желание читать и категоричность делает диалог с вами удовольствием ниже среднего. Вот смотрите.
1. Вы цитируете
Цитата Сообщение от IGPIGP Посмотреть сообщение
Он не указывает на физический объект
Приходится тратить кучу времени на поиск огрызка вырванного из контекста.
2. Фраза в полном виде:
Цитата Сообщение от IGPIGP Посмотреть сообщение
Абстракция хвостового терминатора полезна в смысле поддержки оператора сравнения на равенство (в общем случае). Но это просто метка. Он не указывает на физический объект в обычной реализации.
Она о итераторе на хвост - end() в контенерах (контейнерах, - вообще, не только о строках)
И она не о нуле терминаторе. В корне, - как вы говорите.
Цитата Сообщение от IGPIGP Посмотреть сообщение
обычной реализации
и вердикт
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ну а это уже совсем какая-то чушь.
узнаваем до боли.
А фраза целиком:
Цитата Сообщение от IGPIGP Посмотреть сообщение
Абстракция хвостового терминатора полезна в смысле поддержки оператора сравнения на равенство (в общем случае). Но это просто метка. Он не указывает на физический объект в обычной реализации.
о итераторе контейнера вообще. И говорится в ней о том, что обычные реализации контейнеров не предоставляют объекта под итератор end(). И зто не чушь. Вы сами говорите:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
сли бы разрешалось разыменовывать end() - то да, вы бы там увидели ноль. Но формально end() разыменовывать не разрешается.
Я сыт по горло нашим с вами диалогом. Устал и пойду пожалуй. В этой теме я кое что сделал, но ей опять кирдык.
Редкая птица долетит до середины
этого топика. Что снижает его полезность. Жаль.
0
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 21:43 93
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
вы используете "сокращенную" форму записи
возня в течение нескольких дней. Не до "причёсывания". Надеюсь, ТС удивит преподавателя вариантами способов.
Цитата Сообщение от IGPIGP Посмотреть сообщение
В этой теме я кое что сделал
Достаточно много. Если бы книги так писали.
Я поставил VS2010, т.к. нашёл книгу А.Хортона именно по ней. Начал читать и быстро "скис".
В ветке о VB есть "важное", в которой размещены статьи и ссылки на записи в блоге. Может вам сделать запись в блоге и разместить на неё ссылку в "важном"?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
03.04.2020, 21:52 94
Argus19, вся хорошая литература есть здесь: Литература C++
Что-то лучше, чем там уже представлено, найти крайне сложно.
1
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 21:59 95
Цитата Сообщение от DrOffset Посмотреть сообщение
Что-то лучше, чем там уже представлено, найти крайне сложно
Разъяснение некоторых вопросов никогда не помешает.
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
03.04.2020, 22:01 96
Цитата Сообщение от Argus19 Посмотреть сообщение
Разъяснение некоторых вопросов никогда не помешает.
Вопрос должен базироваться на знании Для этого нужны книги.
Если человек пишет "объясните мне - я ничего не знаю", то ему нечего ответить. Репетиторством (особенно бесплатно) тут мало кто готов заниматься.
0
IGPIGP
03.04.2020, 22:03
  #97

Не по теме:

Цитата Сообщение от Argus19 Посмотреть сообщение
Если бы книги так писали.
Спасибо)

0
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 22:11 98
Цитата Сообщение от DrOffset Посмотреть сообщение
Для этого нужны книги.
Изложение и подход зависит от автора.
Например, мне понадобилось сделать микросайт, чтобы выводить на страничку показания приборов почти в реальном времени. Накачал литературы и убедился, что у всех авторов скачанных книг одна идея: интернет-магазин. Плюнул и пошёл по форумам.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.04.2020, 22:25 99
Цитата Сообщение от Argus19 Посмотреть сообщение
Плюнул и пошёл по форумам.
есть два типа людей:
первые читают книги, учатся, и потом успешно делают микросайты и прочий стафф.
вторые плюют, и ходят по форумам.
0
533 / 375 / 76
Регистрация: 24.09.2017
Сообщений: 2,108
Записей в блоге: 13
03.04.2020, 22:48 100
Цитата Сообщение от hoggy Посмотреть сообщение
вторые плюют, и ходят по форумам.
Согласен.
В моём варианте оказалось достаточно одной строки HTML, которой не было в книгах. И одной строки VB 6.0, которую дали под большим секретом при условии её неразглашения и, которая впоследствии нашлась в англоязычной части Microsoft, почему-то не переведённой на русский язык. Ни в одной книге по VB этой строки нет, т.к. с прекращением его поддержки, и книг не стало.
Как говорится, каждому - своё.
0
03.04.2020, 22:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.04.2020, 22:48
Помогаю со студенческими работами здесь

При попытке вычислить длину строки стандартной функцией strlen возникает ошибка
Есть код, в котором объявлена volatile-переменная c_buf, представляющая собой массив символов: ...

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

Удаление символов из строки без использования стандартной функции delete
Как удалить символы из строки без использования стандартной функции delete? конкретно моя задача:...

Найти максимальную длину строки в текстовом файле и распечатать все строки файла, имеющие такую длину
Найти максимальную длину строки в текстовом файле и распечатать все строки файла, имеющие такую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru