S length c что это
Перейти к содержимому

S length c что это

  • автор:

Строки в C++

В этой статье мы поговорим о классе string, который включен в стандартную библиотеку языка программирования C++. Одновременно с этим рассмотрим основы работы со строками: изучим конструкторы, арифметические операторы и некоторые методы.

В языке программирования C++ существует специальный класс string, обеспечивающий удобство работы со строковыми данными. Для его применения нет необходимости выполнять хитрые манипуляции — достаточно просто подключить соответствующий заголовочный файл string.

Если вспомнить тот же Си, то там существует заголовочный файл стандартной библиотеки, который называется string.h. Он содержит функции, необходимые для работы с памятью и нуль-терминированными строками. На практике функции, объявленные в string.h, применяются довольно широко, так как являются частью стандартной библиотеки, в результате чего стабильно работают на любых платформах, которые поддерживают язык программирования Си.

Но вернемся к С++. На практике вы можете не просто объявлять строки, но и одновременно с этим присваивать им значения:

Строки в C++

В нашем случае S1 будет являться пустой, а S2 — состоять из пяти символов.

Идем дальше. К отдельным символам вы можете обращаться по индексу, как к элементам массива. К примеру, S[0] позволит обратиться к первому строчному элементу (как и в массиве, нумерация начинается с нуля).

Если же надо узнать длину строки length, вы можете воспользоваться методом size(). К примеру, последний символ строки S можно выразить как S[S.size() — 1] .

Конструкторы

При работе со строковыми данными возможно применение ряда конструкторов:

Строки в C++

Вызов конструкторов может быть явным, как в примере ниже:

Строки в C++

То есть мы осуществили вызов конструктора string в целях создания строчки, которая включает в себя 10 символов ‘z’.

Вызов бывает и неявным, что происходит в процессе объявления, когда указываются дополнительные параметры. Это может выглядеть следующим образом:

Строки в C++

Ввод-вывод

Вывод строчных значений осуществляется так же, как и числовых:

Если же надо выполнить считывание, используют операцию «>>» для объекта cin:

Результатом вышеуказанной операции станет считывание строчки из непробельных символов, то есть пробелы и концы строк будут пропущены. Это довольно удобно, если надо разбить текст на слова либо в целях считывания данных до конца файла посредством while (cin >> S) .

Есть возможность выполнять считывание и до появления символа конца строки — тут уже пригодится функция getline. А вот сам символ конца считывается уже из входного потока, правда, непосредственно к строке его добавление не происходит:

Арифметические операторы

Работая со строковыми данными, мы можем выполнять ряд арифметических операций, среди них:

  • = — для присваивания значения;
  • += — для добавления в конец какого-нибудь другого элемента (к примеру, числа) либо даже другой строки;
  • + — оператор конкатенации двух строк/строки и символа;
  • ==, != — для посимвольного сравнения;
  • , = — для лексикографического сравнения.

Таким образом, мы можем выполнить копирование содержимого одной строки в другую посредством операции S1 = S2 , далее выполнить их сравнение на равенство посредством S1 == S2 , потом сравнить в лексикографическом порядке ( S1 < S2 ) либо или выполнить конкатенацию (сложение) в виде S = S1 + S2 .

Методы

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

size

Возвращает длину строки. Значение, которое таким образом возвращается, имеет беззнаковый тип (как и во всех других случаях, если функция возвращает значение, которое равняется длине строке либо индексу элемента, такие значения являются беззнаковыми). Именно поэтому следует предельно внимательно выполнять вычитание из значения, которое возвращается посредством size(). К примеру, будет ошибкой записать цикл, перебирающий все строчные элементы, кроме последнего, типа for (int i = 0; i < S.size() - 1; ++i) .

Также длину строки можно возвратить с помощью метода length().

resize

S.resize(n) позволит изменить длину строки, причем новая длина станет равняться n. Важно понимать, что длина строки ведь может как увеличиться, так и уменьшится. Вызвав метод в виде S.resize(n, c), когда c — символ, вы получите ситуацию, при которой при увеличении строковой длины добавляемые элементы станут равняться c.

clear

S.clear() очистит строчку, в результате чего она станет пустой.

empty

S.empty() возвратит true, когда строчка будет пустой и false, когда непустой.

push_back

S.push_back(c) добавит в конец символ c. Этот метод вызывается с одним параметром, имеющим тип данных char.

append

Добавит в конец несколько символов, другую строчку либо ее фрагмент. Тут существует множество способов вызова:

  • S.append(n, c)— добавляется n одинаковых элементов, которые равны с. У n здесь целочисленный тип, а у c — char;
  • S.append(T) — добавляется содержимое T-строки. Причем T может быть как С-строчкой, так и объектом класса string;
  • S.append(T, pos, count) — добавляются символы T-строки, начиная с символа, имеющего индекс pos. Добавление происходит в количестве count.

Хотите знать про C++ больше? Получить нужные навыки вы сможете на курсах в Otus.

Функции str.size() и str.length() — в чем их разница?

Author24 — интернет-сервис помощи студентам

В чем их разница? Почитал, что вроде бы разницы нет никакой, тогда зачем создавать 2 одинаковые функции?

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Equal(str.begin(), str.end(), str.rbegin()
#include <iostream> #include <string> using namespace std; string str; int main()

Функция: по заданной строке Str сформулировать новую строку, состоящую только из цифр, входящих в Str
Написать и протестировать функцию,которая по заданной строке Str формулирует новую строку,состоящую.

как создать функцию или программу, чтобы str состояла из цифр,а также давалась новой строке str
как создать функцию или программу, чтобы str состояла из цифр,а также давалась новой строке str

Форумчанин

Эксперт CЭксперт С++

8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453

length() — понятие длины, это предикатива чисто строк.
size() — метод, который определяет длину у контейнеров STL. string делали похожей на контейнеры по интерфейсу для удобства работы.
Разницы в реализации у функций нет

31 / 28 / 18
Регистрация: 13.01.2014
Сообщений: 63

MrGluck, все равно не пойму зачем 2 варианта? когда мы используем строки типа string мы можем пользоваться и тем и тем. для вызова той или иной функции ничего дополнительного не требуется кроме

#include

Форумчанин

Эксперт CЭксперт С++

8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453

потому что для кого то размер строки == её длина
для кого то привычнее думать «шаблонами (в значении штампами)» STL.

S length c что это

Напишите программу, которая объединяет и распечатывает две строки, введенные с терминала. Для ввода строк используйте функцию gets(), а для их объединения strcat(). В другом варианте используйте sprintf(result%s%s«,s1,s2);

2.21.

Модифицируйте предыдущую программу таким образом, чтобы она выдавала длину (число символов) объединенной строки. Используйте функцию strlen(). Приведем несколько версий реализации strlen:

/* При помощи индексации массива */ int strlen(s) char s[]; < int length = 0; for(; s[length] != '\0'; length++); return (length); >/* При помощи продвижения указателя */ int strlen(s) char *s; < int length; for(length=0; *s; length++, s++); return length; >/* При помощи разности указателей */ int strlen(register char *s) < register char *p = s; while(*p) p++; /* ищет конец строки */ return (p - s); >

Разность двух указателей на один и тот же тип — целое число:

если TYPE *p1, *p2; то p2 - p1 = целое число штук TYPE лежащих между p2 и p1 если p2 = p1 + n то p2 - p1 = n 

Эта разность может быть и отрицательной если p2 < p1, то есть p2 указывает на более левый элемент массива.

2.22.

Напишите оператор Си, который обрубает строку s до длины n букв.

if( strlen(s) > n ) s[n] = '\0';

Первое сравнение вообще говоря излишне. Оно написано лишь на тот случай, если строка s короче, чем n букв и хранится в массиве, который также короче n, т.е. не имеет nого элемента (поэтому в него нельзя производить запись признака конца).

2.23.

Напишите функции преобразования строки, содержащей изображение целого числа, в само это число. В двух разных вариантах аргумент-адрес должен указывать на первый байт строки; на последний байт. Ответ:

#define isdigit(c) ('0' atoi(s) register char *s; < register int res=0, neg=0; for(;;s++)< switch(*s)< case ' ': case '\t': continue; case '-': neg++; case '+': s++; >break; > while(isdigit(*s)) res = res * 10 + *s++ - '0'; return( neg ? -res : res ); > int backatoi(s) register char *s; < int res=0, pow=1; while(isdigit(*s))< res += (*s-- - '0') * pow; pow *= 10; >if(*s == '-') res = -res; return res; >
2.24.

Можно ли для занесения в массив s строки «hello» написать

char s[6]; s = "hello"; или char s[6], d[] = "hello"; s = d;

Ответ: нет. Массивы в Си нельзя присваивать целиком. Для пересылки массива байт надо использовать функцию strcpy(s,d). Здесь же мы пытаемся изменить адрес s (имя массива — это адрес начала памяти, выделенной для хранения массива), сделав его равным адресу безымянной строки «hello» (или массива d во втором случае). Этот адрес является константой и не может быть изменен!

Заметим однако, что описание массива с инициализацией вполне допустимо:

char s[6] = "hello";
char s[6] = < 'h', 'e', 'l', 'l', 'o', '\0' >;
char s[] = "hello";
char s[] = < "hello" >;

В этом случае компилятор резервирует память для хранения массива и расписывает ее байтами начального значения. Обратите внимание, что строка в двойных кавычках (если ее рассматривать как массив букв) имеет длину на единицу больше, чем написано букв в строке, поскольку в конце массива находится символ ‘\0‘ — признак конца, добавленный компилятором. Если бы мы написали

char s[5] = "hello";

то компилятор сообщил бы об ошибке, поскольку длины массива (5) недостаточно, чтобы разместить 6 байт. В третьей строке примера написано s[], чтобы компилятор сам посчитал необходимую длину массива.

Наконец, возможна ситуация, когда массив больше, чем хранящаяся в нем строка. Тогда «лишнее» место содержит какой-то мусор (в static-памяти изначально — байты \0).

char s[12] = "hello"; содержит: h e l l o \0 ? ? ? ? ? ?

В программах текстовой обработки под «длиной строки» обычно понимают количество букв в строке НЕ считая закрывающий байт ‘\0‘. Именно такую длину считает стандартная функция strlen(s). Поэтому следует различать такие понятия как «(текущая) длина строки» и «длина массива, в котором хранится строка«: sizeof(s). Для написанного выше примера эти значения равны соответственно 5 и 12.

Следует также отличать массивы от указателей:

char *sp = "bye bye"; sp = "hello";

будет вполне законно, поскольку в данном случае sp — не имя массива (т.е. константа, равная адресу начала массива), а указатель (переменная, хранящая адрес некоторой области памяти). Поскольку указатель — это переменная, то ее значение изменять можно: в данном случае sp сначала содержала адрес безымянного массива, в котором находится «bye bye»; затем мы занесли в sp адрес безымянного массива, хранящего строку «hello». Здесь не происходит копирования массива, а происходит просто присваивание переменной sp нового значения адреса.

Предостережем от возможной неприятности:

char d[5]; char s[] = "abcdefgh"; strcpy(d, s);

Длины массива d просто не хватит для хранения такой длинной строки. Поскольку это ничем не контролируется (ни компилятором, ни самой strcpy, ни вами явным образом), то при копировании строки «избыточные» байты запишутся после массива d поверх других данных, которые будут испорчены. Это приведет к непредсказуемым эффектам.

Некоторые возможности для контроля за длиной строк-аргументов вам дают функции

strncpy(d,s,len); strncat(d,s,len); strncmp(s1,s2,len).

Они пересылают (сравнивают) не более, чем len первых символов строки s (строк s1, s2). Посмотрите в документацию! Напишите функцию strncmp (сравнение строк по первым len символам), посмотрев на функцию strncpy:

char *strncpy(dst, src, n) register char *dst, *src; register int n; < char *save; for(save=dst; --n >= 0; ) if( !(*dst++ = *src++))< while(--n >= 0) *dst++ = '\0'; return save; > return save; >
int strncmp(register char *s1, register char *s2, register int n) < if(s1 == s2) return(0); while(--n >= 0 && *s1 == *s2++) if(*s1++ == '\0') return(0); return((n < 0)? 0: (*s1 - *--s2)); >
2.25.

В чем ошибка?

#include stdio.h> /* для putchar */ char s[] = "We don't need no education"; main()< while(*s) putchar(*s++); >

Ответ: здесь s — константа, к ней неприменима операция ++. Надо написать

char *s = "We don't need no education";

сделав s указателем на безымянный маccив. Указатель уже можно изменять.

2.26.

Какие из приведенных конструкций обозначают одно и то же?

char a[] = ""; /* пустая строка */ char b[] = "\0"; char c = '\0'; char z[] = "ab"; char aa[] = < '\0' >; char bb[] = < '\0', '\0' >; char xx[] = < 'a', 'b' >; char zz[] = < 'a', 'b', '\0' >; char *ptr = "ab";
2.27.

Найдите ошибки в описании символьной строки:

main() < char mas[] = ; /* "sort" ? */ printf("%s\n", mas); >

Ответ: строка должна кончаться ‘\0’ (в нашем случае printf не обнаружив символа конца строки будет выдавать и байты, находящиеся в памяти после массива mas, т.е. мусор); инициализированный массив не может быть автоматическим — требуется static:

main() < static char mas[] = ; >

Заметим, что
main()

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

2.28.

В чем ошибка? Программа собирается из двух файлов: a.c и b.c командой

cc a.c b.c -o ab a.c b.c -------------------------------------------------- int n = 2; extern int n; char s[] = "012345678"; extern char *s; main() < f()< f(); s[n] = '+'; printf("%s\n", s ); >>

Ответ: дело в том, что типы (char *) — указатель, и char[] — массив, означают одно и то же только при объявлении формального параметра функции:

f(char *arg) <. >f(char arg[])

это будет локальная переменная, содержащая указатель на char (т.е. адрес некоторого байта в памяти). Внутри функции мы можем изменять эту переменную, например arg++. Далее, и (char *) и char[] одинаково используются, например, оба эти типа можно индексировать: arg[i]. Но вне функций они объявляют разные объекты! Так char *p; это скалярная переменная, хранящая адрес (указатель):

-------- ------ p:| *--|----->| '0' | char -------- | '1' | char .

тогда как char a[20]; это адрес начала массива (а вовсе не переменная):

------ a:| '0' | char | '1' | char .

В нашем примере в файле b.c мы объявили внешний массив s как переменную. В результате компилятор будет интерпретировать начало массива s как переменную, содержащую указатель на char.

------ s:| '0' | \ это будет воспринято как | '1' | / адрес других данных. | '2' | .

И индексироваться будет уже ЭТОТ адрес! Результат — обращение по несуществующему адресу. То, что написано у нас, эквивалентно

char s[] = "012345678"; char **ss = s; /* s - как бы "массив указателей" */ /* первые байты s интерпретируются как указатель: */ char *p = ss[0]; p[2] = '+';

Мы же должны были объявить в b.c

extern char s[]; /* размер указывать не требуется */

Вот еще один аналогичный пример, который пояснит вам, что происходит (а заодно покажет порядок байтов в long). Пример выполнялся на IBM PC 80386, на которой

sizeof(char *) = sizeof(long) = 4 a.c b.c -------------------------------------------------- char s[20] = ; extern char *s; main() < f()< /*печать указателя как long */ f(); printf( "%08lX\n", s ); >>

печатается 04030201.

2.29.

Что напечатает программа?

static char str1[ ] = "abc"; static char str2[4]; strcpy( str2, str1 ); /* можно ли написать str2 = str1; ? */ printf( str1 == str2 ? "равно":"не равно" );

Как надо правильно сравнивать строки? Что на самом деле сравнивается в данном примере?

Ответ: сравниваются адреса массивов, хранящих строки. Так

char str1[2]; char str2[2]; main()< printf( str1 < str2 ? ""); >

печатает , а если написать

char str2[2]; char str1[2];

то напечатается >.

2.30.

Напишите программу, спрашивающую ваше имя до тех пор, пока вы его правильно не введете. Для сравнения строк используйте функцию strcmp() (ее реализация есть в главе «Мобильность»).

2.31.

Какие значения возвращает функция strcmp() в следующей программе?

#include main() < printf("%d\n", strcmp("abc", "abc")); /* 0 */ printf("%d\n", strcmp("ab" , "abc")); /* -99 */ printf("%d\n", strcmp("abd", "abc")); /* 1 */ printf("%d\n", strcmp("abc", "abd")); /* -1 */ printf("%d\n", strcmp("abc", "abe")); /* -2 */ >
2.32.

В качестве итога предыдущих задач: помните, что в Си строки (а не адреса) надо сравнивать как

if( strcmp("abc", "bcd") < 0) . ; if( strcmp("abc", "bcd") == 0) . ; вместо if( "abc" < "bcd" ) . ; if( "abc" == "bcd" ) . ;

и присваивать как

char d[80], s[80]; strcpy( d, s ); вместо d = s;
2.33.

Напишите программу, которая сортирует по алфавиту и печатает следующие ключевые слова языка Си:

int char double long for while if
2.34.

Вопрос не совсем про строки, скорее про цикл: чем плоха конструкция?

char s[] = "You're a smart boy, now shut up."; int i, len; for(i=0; i < strlen(s); i++) putchar(s[i]);

Ответ: в соответствии с семантикой Си цикл развернется примерно в

i=0; LOOP: if( !(i < strlen(s))) goto ENDLOOP; putchar(s[i]); i++; goto LOOP; ENDLOOP: ;

Заметьте, что хотя длина строки s не меняется, strlen(s) вычисляется на КАЖДОЙ итерации цикла, совершая лишнюю работу! Борьба с этим такова:

for(i=0, len=strlen(s); i < len; i++ ) putchar(s[i]);
for(i=0, len=strlen(s); len > 0; i++, --len ) putchar(s[i]);

Аналогично, в цикле

while( i < strlen(s)). ;

функция тоже будет вычисляться при каждой проверке условия! Это, конечно, относится к любой функции, используемой в условии, а не только к strlen. (Но, разумеется, случай когда функция возвращает признак "надо ли продолжать цикл" - совсем другое дело: такая функция обязана вычисляться каждый раз).

2.35.

Что напечатает следующая программа?
#include main()

2.36.

Что напечатает следующая программа?

main() < static char name[] = "Константин"; char *pt; pt = name + strlen(name); while(--pt >= name) puts(pt); >
2.37.

Что напечатает следующая программа?
char str1[] = "abcdef"; char str2[] = "xyz"; main()

str=xyzdef a=def str=xxyzef a=zef
2.38.

Что печатает программа?

char *s; for(s = "Ситроен"; *s; s+= 2) < putchar(s[0]); if(!s[1]) break; >putchar('\n');
2.39.

Что напечатает программа? Рассмотрите продвижение указателя s, указателей элементов массива strs[]. Разберитесь с порядком выполнения операций. В каких случаях ++ изменяет указатель, а в каких - букву в строке? Нарисуйте себе картинку, изображающую состояние указателей - она поможет вам распутать эти спагетти. Уделите разбору этого примера достаточное время!

#include /* определение NULL */ /* Латинский алфавит: abcdefghijklmnopqrstuvwxyz */ char *strs[] = < "abcd","ABCD","0fpx","159", "hello","-gop","A1479",NULL >; main()
Печатается:

#1 0 b bcd strs[0]="bcd" #2 1 A ABCD strs[1]="ABCD" #3 2 A 0fpx strs[2]="px" #4 2 1 1fpx strs[3]="69" #5 2 1 2fpx strs[4]="hello" #6 2 g gpx strs[5]="iop" #7 3 p 159 px strs[6]="89" #8 4 6 hello 69 #9 5 h hop #10 6 i A1479 #11 6 B 1479 1479 B1479 #12 6 2 479 479 #13 6 7 89 89

Учтите, что конструкция

char *strs[1] = < "hello" >;

означает, что в strs[0] содержится указатель на начальный байт безымянного массива, содержащего строку "hello". Этот указатель можно изменять! Попробуйте составить еще подобные примеры из *, ++, ().

© Copyright А. Богатырев, 1992-95
Си в UNIX

S length c что это

Length (функция)
Навигация

Язык:
Русский
English

Возвращает динамическую длину строки.

Объявление

Function Length(S : String) : Integer;

Режим

Windows, Real, Protected

Смотри также

Пример

Язык:
Русский
English

begin
ReadLn (S) ;
WriteLn ( '"' , S , '"' ) ;
WriteLn ( 'Длина = ' , Length (S)) ;
end .

Код для вставки: :: :: :: ГОСТ ::

Поделиться: //

Для форумов:
Для блогов:
Для Википедии:

-

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *