Что такое код strtod strtol


Содержание

Функция strtol

Функция strtol() преобразует строковое представление числа, которое содержится в строке, адресуемой параметром-указателем start , в значение типа long int и возвращает полученный результат. Основание системы счисления, в которой представлено преобразуемое число, определяется параметром radix . Если значение radix равно нулю, то основание определяется так же, как и основание системы счисления при записи констант. Если значение radix не равно нулю, то оно должно быть целым числом от 2 до 36.

В версии С99 к параметрам start и end применен квалификатор restrict .

Функция strtol() работает следующим образом:

Сначала в строке, адресуемой параметром start , пропускаются пробелы, символы табуляции и пустой строки. Затем считывается число. Считывание заканчивается как только будет обнаружен символ, который не может быть частью длинного целого числа. К таким символам относятся пробелы, символы табуляции и пустой строки, знаки препинания и другие символы. Наконец, параметр end устанавливается так, чтобы указывать на «неиспользованный» остаток исходной строки, если таковой существует. Это означает, что, если функция strtol() вызывается с аргументом

она возвратит значение

а параметр end будет указывать на пробел, предшествующий слову

Если результат не может быть представлен как значение типа long int , функция strtol() возвращает либо значение LONG_MAX , либо значение LONG_MIN , а глобальная переменная errno устанавливается равной значению ERANGE , свидетельствующему об ошибке из-за выхода за границы представимых чисел. Если параметр start не указывает на число, никакого преобразования не выполняется и функция возвращает нуль.

Пример

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

Что такое код strtod strtol

long int strtol(const char *nptr, char **endptr, int base);
long long int strtoll(const char *nptr, char **endptr, int base);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

_XOPEN_SOURCE >= 600 || _BSD_SOURCE || _SVID_SOURCE || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
или cc -std=c99

ОПИСАНИЕ

Строка может начинаться с произвольного количества пробельных символов (определяемых при помощи isspace(3)), затем может быть указан знак «+» или «-». Если base равно 0 или 16, то строка может начинаться с приставки «0x», что означает использование шестнадцатеричной системы исчисления; иначе, если base равно нулю, то используется десятичная система счисления (кроме, когда последующий символ также равен «0»: в этом случае используется восьмеричная система исчисления).

Остаток строки преобразуется в число с типом long int. Этот процесс останавливается, если в строке встречается некорректный символ для указанной системе счисления. В системах счисления больших 10, символ «A» в верхнем или нижнем регистре означает 10, «B» означает 11 и так далее до «Z», означающего 35.

Если значение endptr не NULL, то strtol() записывает адрес первого некорректного символа в *endptr. Если в строке вообще нет цифр, то strtoul() сохраняет изначальное значение nptr в *endptr (и возвращает 0). В частности, если *nptr не равно ‘\0’, но **endptr равно ‘\0’ при возврате, то вся строка состоит из корректных символов.

Функция strtoll() работает так же, как и strtol(), но возвращает число с типом long long int.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

ОШИБКИ

Реализация может также устанавливать errno в EINVAL в случае, когда преобразование не было выполнено (не было встречено цифр и возвращён 0).

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes(7).

Интерфейс Атрибут Значение
strtol(), strtoll(), strtoq() безвредность в нитях безвредно (MT-Safe locale)

СООТВЕТСТВИЕ СТАНДАРТАМ

strtoll(): POSIX.1-2001, POSIX.1-2008, C99.

ЗАМЕЧАНИЯ

Согласно POSIX.1, в локалях отличных от «C» и «POSIX», эти функции могут преобразовывать другие, определяемые реализацией, строки с числами.

В BSD также есть функция

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

Описание функций языка Си

All | _ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

strtod – преобразование строки в число типа double.

#include
double strtod (const char *str, char **endstr);

str – указатель на строку для преобразования.
endstr – указатель на переменную, в которую будет помещен указатель на непреобразованный остаток строки или на начало строки str, если преобразование не удалось или вся строка преобразована.

При успешном завершении функции возвращается результат преобразования – число типа double, а по адресу указанному в переменной endstr записывается указатель на оставшуюся непреобразованную часть строки или указатель на начало строки, если вся строка была преобразована.

Если преобразование не может быть выполнено, то возвращается 0, а по адресу указанному в переменной endstr записывается указатель на начало строки str.

Если в результате преобразования получено слишком большое по абсолютной величине число, то будет возвращено плюс или минус HUGE_VAL в зависимости от знака числа и переменной errno будет присвоено значение [ERANGE]. Если получено слишком маленькое по абсолютной величине число, то будет возвращен 0 и переменной errno будет присвоено значение [ERANGE]. При этом по адресу указанному в переменной endstr записывается указатель на оставшуюся непреобразованную часть строки или указатель на начало строки, если вся строка была преобразована.

Функция преобразует строку (с числом с плавающей точкой) в число типа double. Число с плавающей точкой — форма представления действительных чисел, в которой число хранится в форме мантиссы и показателя степени, например 123.45*e6, где 123.45 – мантисса, 6 – порядок.

Преобразуемая строка должна иметь вид: [pr] [zn] [dс] [.] [dd] [e[znp]dp]

[pr] – пробел. В начале преобразуемой строки пробел необязателен. Если в одной строке содержится несколько чисел в символьном формате, то они должны быть разделены пробелами.

[zn] – знак мантиссы + или — , если знак отсутствует, то мантисса считается положительной.

[dс] – десятичные цифры целой части мантиссы, если данные цифры отсутствует, то целая часть мантиссы считается нулевой.

[.] – десятичная точка (разделитель целой и дробной части мантиссы), если данный знак отсутствует, то мантисса содержит только целую часть.

[dd] — десятичные цифры дробной части мантиссы, если данные числа отсутствуют, то мантисса содержит только целую часть.

[e] – символ e или E, если данный символ отсутствует, то число с плавабющей точкой не содержит порядок (содержит нулевой порядок).

[znp] – знак порядка + или — , если знак отсутствует, то порядок считается положительным.

[dp] – десятичные цифры порядка, если цифры отсутствуют порядок равен 0.

Наличие либо целой, либо дробной части числа мантиссы обязательно, порядок может полностью отсутствовать, но если он указан, обязательно перед порядком должен идти символ e или E. Пробелы внутри числа с плавающей точкой недопустимы.

Примеры записи числа с плавающей точкой: +123.45e6, +123.45E6, 123E-6, -123E6, -.45e6, +123.45 и т.д.

В одной преобразуемой строке может быть несколько чисел с плавающей точкой, в этом случае каждое число должно быть отдалено от другого пробелом.

В примере строка «+123.45e6 +123.45E6 0 123E-6 -123E6 -.45e6 +123.45» преобразуется в семь чисел типа double и результат выводится на консоль.

Вывод в консоль:

123450000.000000
123450000.000000
0.000000
0.000123
-123000000.000000
-450000.000000
123.450000

функция strtok

28.03.2011, 14:30

Использование STRTOK Разбить строку на слова, из слов составить список C++ Функция strtok
Задача Дана строка слов с разделителями, в данном примере слова с пробелами Нужно, используя.

Функция strtok()
Доброе время суток! Подскажите пожалуйста в чем проблема и как с ней бороться. Имеем такой.

функция strtok()
Объясните, пожалуйста, функцию strtok(). то что непонятно — заккоментила ps=strtok(str, » «);.

Функция strtok и занесение в массив
Пытаюсь с помощью этой функции разбить массив char на слова и каждое слово занести в отдельный.

Как работает функция strtok
Как работает функция strtok. #include «stdafx.h» #include #include .

28.03.2011, 14:54 2

Решение

28.03.2011, 15:05 [ТС] 3

а как именно ,можно подробно?и что такое такены? pch = strtok (str,» ,.-«); -это я понял а что дальше??

28.03.2011, 15:20 4

Решение

28.03.2011, 15:20
26.01.2012, 16:22 5
26.01.2012, 16:23 6
23.06.2013, 15:18 7
23.06.2013, 15:25 8
23.06.2013, 15:57 9

Я так понимаю, главный вопрос в том, как сформировать этот массив? Потому что вывод массива тривиален: в цикле для каждого элемента массива выводишь этот элемент.

Для формировании массива есть два подхода. Первый подразумевает, что максимально возможное число элементов массива заранее известно, и количество элементов массива при любых входных данных не может превышать это число. Тогда нужно просто объявить статический массив достаточного размера. При втором подходе объявляется динамический массив, размер которого увеличивается при необходимости.

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

Strtod

strtod (сокр. от string to double, «строку в число двойной точности») — функция языка Си, конвертирующая символ строки в число с плавающей запятой двойной точности. Определение функции имеет вид:

double strtod ( const char * str, char ** endptr ); [1]

Содержание

Обзор

Функция strtod разбирает строку Си str , представляя её содержимое в виде числа с плавающей точкой и возвращает её значение double . Если endptr — не нуль-указатель, то функция устанавливает значение, на которое указывает endptr , равным первому символу после числа.

Вначале функция отбрасывает все пробелы, пока не встретится первый непробельный символ. Затем, начиная с этого символа, считывает все символы, соответствующие синтаксису как у литералов с плавающей точкой, и интерпретирует их в виде числовых значений. Указатель на оставшуюся часть строки после последнего корректного символа сохраняется в объекте, на который указывает endptr .

Корректной последовательностью чисел с плавающей точкой для strtod считается последовательность, удовлетворяющая следующим условиям:

  • Знак положительного или отрицательного числа (необязательно)
  • Последовательность цифр, как вариант, может содержать десятичную точку
  • Дополнительная экспонентная часть, которая сама по себе состоит из символа ‘e’ или ‘E’, после которого следует дополнительный знак и последовательность цифр.

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

Параметры

  • Си-строка, начинающаяся с представления числа с плавающей запятой.
  • Ссылка на уже выделенный объект типа char* , чьё значение присваивается функцией следующему символу в str после числового значения. Этот параметр также может быть нуль-указателем, в случае когда он не используется.

Возвращаемое значение

В случае успеха функция возвращает преобразованное число с плавающей запятой как число с двойной точностью (то есть типа double ). Если корректное преобразование не может быть выполнено, то возвращается нулевое значение (0.0). Если корректное значение выходит за пределы представимых значений, то возвращается положительное или отрицательное значение HUGE_VAL («huge value», большое число), а глобальной переменной errno присваивается значение ERANGE (выход за пределы). Если корректное значение будет слишком мало, то возвращается ноль, а errno присваивается значение ERANGE .

Функция strtod входит в состав заголовочного файла stdlib.h стандартной ISO/IEC библиотеки языка Си.

См. также

Примечания

  1. ↑strtod — convert a string to a double-precision number. Архивировано 14 апреля 2012 года.

Ссылки

  • Справочник С/C++ для UNIX — Список функций — описание функции и примеры (рус.)
  • STRTOD(3C) — описание функции (рус.)

Что такое Wiki.sc Вики является главным информационным ресурсом в интернете. Она открыта для любого пользователя. Вики это библиотека, которая является общественной и многоязычной.

Основа этой страницы находится в Википедии. Текст доступен по лицензии CC BY-SA 3.0 Unported License.

Strtok_s Где Можно Посмотреть Сам Принцип Функции

abyss

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

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

у кого есть такая информация.

rrrFer

Потому что strtok — это стандартная функция, которая поддерживается всеми компиляторами Си/С++.
Поэтому описана она нормально и даже на страницах man про нее исчерпывающая информация.

strtok_s — поделка майкрософта, которая работает только в одном компиляторе (от майкрософта), поэтому про нее написано только на msdn.
Больше чем на сайте майкрософта (msdn), ссылку на который вы дали, информации не будет.

abyss

Потому что strtok — это стандартная функция, которая поддерживается всеми компиляторами Си/С++.
Поэтому описана она нормально и даже на страницах man про нее исчерпывающая информация.

strtok_s — поделка майкрософта, которая работает только в одном компиляторе (от майкрософта), поэтому про нее написано только на msdn.
Больше чем на сайте майкрософта (msdn), ссылку на который вы дали, информации не будет.

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

а почему компилятор говорит что strtok не безопасная функция или выдаёт ошибку?, пример приводить с ошибконе не буду не помню такого но был как то, а вот при использовании strtok, пишет что применяйте ей замену strtok_s

в любом случае спасибо за подробные разъяснения!!

rrrFer

Потому, что ты используешь поделки майкрософта. А им выгодно пересадить юзеров к своим унылым функциям (их много, все заканчиваются на _s). Потом юзеры не смогут нормально работать под линуксом, например.

Но а если серьезно, то да, функция не безопасна. И gcc тоже вроде бы о таких штуках сообщает.
Если предупреждения не нравятся — можно залезть в настройки студии и отключить.

Посмотри вот тут пример использования:

должно быть понятно, что это плохая, опасная функция. На поверхности лежит куча вариантов допустить ошибку.

Допустим
strtok(str, str + 99);
// я в строке с 99 символа разместил разделители и пытаюсь выделить слова в остальной строке.
понятно, что код бредовый 9примеры надуман и высосан из пальца), но сломается 99%, хотя. казалось бы..ничего незаконного нет.

По ссылке выше есть предупреждение еще:

abyss

Такого нет чтобы не нравилось, возникли вопросы из-за того, что компилятор сообщил предупреждение. Вот решил найти о чём это он начал писать. А оказалось ответ я самостоятельно мог бы и не найти, если бы вы в начале не написали объективно в чём дело. Верней возможно нашёл, после как набрался бы опыта возможно, только это было не скоро.

не совсем понятно про статическую переменную, к чему она относится?, предположение — это про NULL? или .

про этот цикл while (pch != NULL), да пример интересный, если туда поместить вызов другой функции если я понял правильно вашу мысль, но в каком таком случае это может понадобится, для меня это пока остаётся за гранью моего представления знаний вообще

можно другой вопрос не относящийся к данной теме больше к указателям:

rrrFer

статическая переменная — это переменная, перед объявлением которой стоит слово static.

Т.е. я инициализировал значение статической переменной 1 раз, а обращаюсь к ней потом, но уже не важно что я туда передаю, оно не сбрасывается (t++ просто увеличивает счетчик, чтобы было понятно что что-то работает).

Вот примерно такая же лабуда сидит внутри strtok. Если я вместо аргумента передаю NULL — то значение не обновляется. Ну примерно актой код в начале этой функции:

abyss

— пример понятен, предпологал подобное в вопросе про NULL, только не так точно, да это прям зараза какая та ))

Вот примерно такая же лабуда сидит внутри strtok. Если я вместо аргумента передаю NULL — то значение не обновляется. Ну примерно актой код в начале этой функции:

strtok(char *ptr) <
static *sptr = 0;
if (ptr != 0) sptr = ptr;
// .
>
Ну мне так кажется. А это плохо и внезапно.

rrrFer

abyss

Да логические ошибки искать долго .

А что касаемо примера с указателем, как же он передаётт значения, сразу лексемы а не токена?

abyss

этот вопрос был выше в примере:

rrrFer

указатель указывает на область памяти. В памяти хранится строка.
Ты можешь поместить указатель на второй, десятый, любой символ. При выводе будет выведена вся строка.

Строка в Си — это последовательность байт, завершающаяся нуль-терминатором. Т.е. не важно сколько там символов — будет выведена вся строка до тех пор пока не встретится нуль. так оно и работает. С чего вы решили что должен выводиться только 1 символ?

Ну я как бэ догадывался что студенты вообще не представляют как выглядит память, я советовал им посмотреть книжки для дошкольников (у меня такие были, с рисунками всякими в стиле детских раскрасок) по программированию (в союзе такие выпускались). Ну и на доске мелом рисовал. Как вам нарисовать — не знаю. Мела нет.

Добавлено: а че вам дался этот strtok? вы без него обойтись не можете?

abyss

Со своей стороны вижу, совершенно не правильно задал вопрос.
Постараюсь немного по другому:
-происходит вызов функции, на экран выводится слово.
— так вот и не очень понятно почему происходит вывод слова, а не одного символа.

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

если правильно понимаю, вывод всего слова происходит из-за функции, это как цикл, допустим while, там пока условие соблюдается он и происходит, «и ни дай Бог ты пролетишь в бесконечный цикл» ))
вот меня и парило как же этот указатель такое делает, а оказывается он ссылается на каждый символ пока не встретит условие завершения, в нашем случае это пробел.

на ваш взгляд мысль верна?

rrrFer

abyss
потому что strtok возвращает char* а не char.
Первое — строка, второе — символ.

Correct usage of strtol

The program below converts a string to long, but based on my understanding it also returns an error. I am relying on the fact that if strtol successfully converted string to long, then the second parameter to strtol should be equal to NULL. When I run the below application with 55, I get the following message.

How can I successfully detect errors from strtol? In my application, zero is a valid value.

4 Answers 4

You’re almost there. temp itself will not be null, but it will point to a null character if the whole string is converted, so you need to dereference it:

Note that names beginning with an underscore are reserved for the implementation; it is best to avoid using such names in your code. Hence, _val should be just val .

The full specification of error handling for strtol() and its relatives is complex, surprisingly complex, when you first run across it. One thing you’re doing absolutely right is using a function to invoke strtol() ; using it ‘raw’ in code is probably not correct.

Since the question is tagged with both C and C++, I will quote from the C2011 standard; you can find the appropriate wording in the C++ standard for yourself.

ISO/IEC 9899:2011 §7.22.1.4 The strtol , strtoll , strtoul and strtoull functions

long int strtol(const char * restrict nptr, char ** restrict endptr, int base);

¶2 [. ] First, they decompose the input string into three parts: an initial, possibly empty, sequence of white-space characters (as specified by the isspace function), a subject sequence resembling an integer represented in some radix determined by the value of base, and a final string of one or more unrecognized characters, including the terminating null character of the input string. [. ]

¶7 If the subject sequence is empty or does not have the expected form, no conversion is performed; the value of nptr is stored in the object pointed to by endptr , provided that endptr is not a null pointer.

Returns

¶8 The strtol , strtoll , strtoul , and strtoull functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value is outside the range of representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno .

Remember that no standard C library function ever sets errno to 0. Therefore, to be reliable, you must set errno to zero before calling strtol() .

So, your parseLong() function might look like:

Note that on error, this returns 0 or LONG_MIN or LONG_MAX, depending on what strtol() returned. If your calling code needs to know whether the conversion was successful or not, you need a different function interface — see below. Also, note that errors should be printed to stderr rather than stdout , and error messages should be terminated by a newline \n ; if they’re not, they aren’t guaranteed to appear in a timely fashion.

Now, in library code you probably do not want any printing, and your calling code might want to know whether the conversion was successful of not, so you might revise the interface too. In that case, you’d probably modify the function so it returns a success/failure indication:

which you could use like:

If you need to distinguish between ‘trailing junk’, ‘invalid numeric string’, ‘value too big’ and ‘value too small’ (and ‘no error’), you’d use an integer or enum instead of a boolean return code. If you want to allow trailing white space but no other characters, or if you don’t want to allow any leading white space, you have more work to do in the function. The code allows octal, decimal and hexadecimal; if you want strictly decimal, you need to change the 0 to 10 in the call to strtol() .

If your functions are to masquerade as part of the standard library, they should not set errno to 0 permanently, so you’d need to wrap the code to preserve errno :


Строки в python 3: методы, функции, форматирование

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

Из этого урока вы узнаете: Python предоставляет большую коллекцию операторов, функций и методов для работы со строками. Когда вы закончите изучение этой документации, узнаете, как получить доступ и извлечь часть строки, а также познакомитесь с методами, которые доступны для манипулирования и изменения строковых данных.

Ниже рассмотрим операторы, методы и функции, доступные для работы с текстом.

Строковые операторы

Вы уже видели операторы + и * в применении их к числовым значениям в уроке по операторам в Python . Эти два оператора применяются и к строкам.

Оператор сложения строк +

+ — оператор конкатенации строк. Он возвращает строку, состоящую из других строк, как показано здесь:

Оператор умножения строк *

* — оператор создает несколько копий строки. Если s это строка, а n целое число, любое из следующих выражений возвращает строку, состоящую из n объединенных копий s :

Вот примеры умножения строк:

Значение множителя n должно быть целым положительным числом. Оно может быть нулем или отрицательным, но этом случае результатом будет пустая строка:

Если вы создадите строковую переменную и превратите ее в пустую строку, с помощью ‘py’ * -6 , кто-нибудь будет справедливо считать вас немного глупым. Но это сработает.

Тест на знание python

Оператор принадлежности подстроки in

Python также предоставляет оператор принадлежности, который можно использоваться для манипуляций со строками. Оператор in возвращает True , если подстрока входит в строку, и False , если нет:

Есть также оператор not in , у которого обратная логика:

Встроенные функции строк в python

Python предоставляет множество функций, которые встроены в интерпретатор. Вот несколько, которые работают со строками:

Функция Описание
chr() Преобразует целое число в символ
ord() Преобразует символ в целое число
len() Возвращает длину строки
str() Изменяет тип объекта на string

Более подробно о них ниже.

Функция ord(c) возвращает числовое значение для заданного символа.

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

Самая простая схема в повседневном использовании называется ASCII . Она охватывает латинские символы, с которыми мы чаще работает. Для этих символов ord(c) возвращает значение ASCII для символа c :

ASCII прекрасен, но есть много других языков в мире, которые часто встречаются. Полный набор символов, которые потенциально могут быть представлены в коде, намного больше обычных латинских букв, цифр и символом.

Unicode — это современный стандарт, который пытается предоставить числовой код для всех возможных символов, на всех возможных языках, на каждой возможной платформе. Python 3 поддерживает Unicode, в том числе позволяет использовать символы Unicode в строках.

Функция ord() также возвращает числовые значения для символов Юникода:

Функция chr(n) возвращает символьное значение для данного целого числа.

chr() действует обратно ord() . Если задано числовое значение n , chr(n) возвращает строку, представляющую символ n :

chr() также обрабатывает символы Юникода:

Функция len(s) возвращает длину строки.

len(s) возвращает количество символов в строке s :

Функция str(obj) возвращает строковое представление объекта.

Практически любой объект в Python может быть представлен как строка. str(obj) возвращает строковое представление объекта obj :

Индексация строк

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

В Python строки являются упорядоченными последовательностями символьных данных и могут быть проиндексированы. Доступ к отдельным символам в строке можно получить, указав имя строки, за которым следует число в квадратных скобках [] .

Индексация строк начинается с нуля: у первого символа индекс 0 , следующего 1 и так далее. Индекс последнего символа в python — ‘‘длина строки минус один’’.

Например, схематическое представление индексов строки ‘foobar’ выглядит следующим образом:

Отдельные символы доступны по индексу следующим образом:

Попытка обращения по индексу большему чем len(s) — 1 , приводит к ошибке IndexError :

Индексы строк также могут быть указаны отрицательными числами. В этом случае индексирование начинается с конца строки: -1 относится к последнему символу, -2 к предпоследнему и так далее. Вот такая же диаграмма, показывающая как положительные, так и отрицательные индексы строки ‘foobar’ :

Вот несколько примеров отрицательного индексирования:

Попытка обращения по индексу меньшему чем -len(s) , приводит к ошибке IndexError :

Для любой непустой строки s , код s[len(s)-1] и s[-1] возвращают последний символ. Нет индекса, который применим к пустой строке.

Срезы строк

Python также допускает возможность извлечения подстроки из строки, известную как ‘‘string slice’’. Если s это строка, выражение формы s[m:n] возвращает часть s , начинающуюся с позиции m , и до позиции n , но не включая позицию:

Помните: индексы строк в python начинаются с нуля. Первый символ в строке имеет индекс 0 . Это относится и к срезу.

Опять же, второй индекс указывает символ, который не включен в результат. Символ ‘n’ в приведенном выше примере. Это может показаться немного не интуитивным, но дает результат: выражение s[m:n] вернет подстроку, которая является разницей n — m , в данном случае 5 — 2 = 3 .

Если пропустить первый индекс, срез начинается с начала строки. Таким образом, s[:m] = s[0:m] :

Аналогично, если опустить второй индекс s[n:] , срез длится от первого индекса до конца строки. Это хорошая, лаконичная альтернатива более громоздкой s[n:len(s)] :

Для любой строки s и любого целого n числа ( 0 ≤ n ≤ len(s) ), s[:n] + s[n:] будет s :

Пропуск обоих индексов возвращает исходную строку. Это не копия, это ссылка на исходную строку:

Если первый индекс в срезе больше или равен второму индексу, Python возвращает пустую строку. Это еще один не очевидный способ сгенерировать пустую строку, если вы его искали:

Отрицательные индексы можно использовать и со срезами. Вот пример кода Python:

Шаг для среза строки

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

Например , для строки ‘python’ срез 0:6:2 начинается с первого символа и заканчивается последним символом (всей строкой), каждый второй символ пропускается. Это показано на следующей схеме:

Иллюстративный код показан здесь:

Как и в случае с простым срезом, первый и второй индексы могут быть пропущены:

Вы также можете указать отрицательное значение шага, в этом случае Python идет с конца строки. Начальный/первый индекс должен быть больше конечного/второго индекса:

В приведенном выше примере, 5:0:-2 означает «начать с последнего символа и делать два шага назад, но не включая первый символ.”

Когда вы идете назад, если первый и второй индексы пропущены, значения по умолчанию применяются так: первый индекс — конец строки, а второй индекс — начало. Вот пример:

Это общая парадигма для разворота (reverse) строки:

Форматирование строки

В Python версии 3.6 был представлен новый способ форматирования строк. Эта функция официально названа литералом отформатированной строки, но обычно упоминается как f-string.

Возможности форматирования строк огромны и не будут подробно описана здесь.
Одной простой особенностью f-строк, которые вы можете начать использовать сразу, является интерполяция переменной. Вы можете указать имя переменной непосредственно в f-строковом литерале ( f’string’ ), и python заменит имя соответствующим значением.

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

Но это громоздко. Чтобы выполнить то же самое с помощью f-строки:

  • Напишите f или F перед кавычками строки. Это укажет python, что это f-строка вместо стандартной.
  • Укажите любые переменные для воспроизведения в фигурных скобках ( <> ).

Код с использованием f-string, приведенный ниже выглядит намного чище:

Любой из трех типов кавычек в python можно использовать для f-строки:

Изменение строк

Строки — один из типов данных, которые Python считает неизменяемыми, что означает невозможность их изменять. Как вы ниже увидите, python дает возможность изменять (заменять и перезаписывать) строки.

Такой синтаксис приведет к ошибке TypeError :

На самом деле нет особой необходимости изменять строки. Обычно вы можете легко сгенерировать копию исходной строки с необходимыми изменениями. Есть минимум 2 способа сделать это в python. Вот первый:

Есть встроенный метод string.replace(x, y) :

Читайте дальше о встроенных методах строк!

Встроенные методы строк в python

В руководстве по типам переменных в python вы узнали, что Python — это объектно-ориентированный язык. Каждый элемент данных в программе python является объектом.

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

Методы похожи на функции. Метод — специализированный тип вызываемой процедуры, тесно связанный с объектом. Как и функция, метод вызывается для выполнения отдельной задачи, но он вызывается только вместе с определенным объектом и знает о нем во время выполнения.

Синтаксис для вызова метода объекта выглядит следующим образом:

Вы узнаете намного больше об определении и вызове методов позже в статьях про объектно-ориентированное программирование. Сейчас цель усвоить часто используемые встроенные методы, которые есть в python для работы со строками.

В приведенных методах аргументы, указанные в квадратных скобках ( [] ), являются необязательными.

Изменение регистра строки

Методы этой группы выполняют преобразование регистра строки.

string.capitalize() приводит первую букву в верхний регистр, остальные в нижний.

s.capitalize() возвращает копию s с первым символом, преобразованным в верхний регистр, и остальными символами, преобразованными в нижний регистр:

Не алфавитные символы не изменяются:

string.lower() преобразует все буквенные символы в строчные.

s.lower() возвращает копию s со всеми буквенными символами, преобразованными в нижний регистр:

string.swapcase() меняет регистр буквенных символов на противоположный.

s.swapcase() возвращает копию s с заглавными буквенными символами, преобразованными в строчные и наоборот:

string.title() преобразует первые буквы всех слов в заглавные

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

Этот метод использует довольно простой алгоритм. Он не пытается различить важные и неважные слова и не обрабатывает апострофы, имена или аббревиатуры:

string.upper() преобразует все буквенные символы в заглавные.

s.upper() возвращает копию s со всеми буквенными символами в верхнем регистре:

Найти и заменить подстроку в строке

Эти методы предоставляют различные способы поиска в целевой строке указанной подстроки.

Каждый метод в этой группе поддерживает необязательные аргументы и аргументы. Они задают диапазон поиска: действие метода ограничено частью целевой строки, начинающейся в позиции символа и продолжающейся вплоть до позиции символа , но не включая его. Если указано, а нет, метод применяется к части строки от конца.

string.count([, [, ]]) подсчитывает количество вхождений подстроки в строку.

s.count() возвращает количество точных вхождений подстроки в s :

Количество вхождений изменится, если указать и :

string.endswith( [, [, ]]) определяет, заканчивается ли строка заданной подстрокой.

s.endswith( ) возвращает, True если s заканчивается указанным и False если нет:

Сравнение ограничено подстрокой, между и , если они указаны:

string.find([, [, ]]) ищет в строке заданную подстроку.

s.find() возвращает первый индекс в s который соответствует началу строки :

Этот метод возвращает, -1 если указанная подстрока не найдена:

Поиск в строке ограничивается подстрокой, между и , если они указаны:

string.index([, [, ]]) ищет в строке заданную подстроку.

Этот метод идентичен .find() , за исключением того, что он вызывает исключение ValueError , если не найден:

string.rfind([, [, ]]) ищет в строке заданную подстроку, начиная с конца.

s.rfind() возвращает индекс последнего вхождения подстроки в s , который соответствует началу :

Как и в .find() , если подстрока не найдена, возвращается -1 :

Поиск в строке ограничивается подстрокой, между и , если они указаны:

string.rindex([, [, ]]) ищет в строке заданную подстроку, начиная с конца.

Этот метод идентичен .rfind() , за исключением того, что он вызывает исключение ValueError , если не найден:

Сравнение ограничено подстрокой, между и , если они указаны:

Классификация строк

Методы в этой группе классифицируют строку на основе символов, которые она содержит.

string.isalnum() определяет, состоит ли строка из букв и цифр.

s.isalnum() возвращает True , если строка s не пустая, а все ее символы буквенно-цифровые (либо буква, либо цифра). В другом случае False :

string.isalpha() определяет, состоит ли строка только из букв.

s.isalpha() возвращает True , если строка s не пустая, а все ее символы буквенные. В другом случае False :

string.isdigit() определяет, состоит ли строка из цифр (проверка на число).

s.digit() возвращает True когда строка s не пустая и все ее символы являются цифрами, а в False если нет:

string.isidentifier() определяет, является ли строка допустимым идентификатором Python.

s.isidentifier() возвращает True , если s валидный идентификатор (название переменной, функции, класса и т.д.) python, а в False если нет:

Важно: .isidentifier() вернет True для строки, которая соответствует зарезервированному ключевому слову python, даже если его нельзя использовать:

Вы можете проверить, является ли строка ключевым словом Python, используя функцию iskeyword() , которая находится в модуле keyword . Один из возможных способов сделать это:

Если вы действительно хотите убедиться, что строку можно использовать как идентификатор python, вы должны проверить, что .isidentifier() = True и iskeyword() = False .

string.islower() определяет, являются ли буквенные символы строки строчными.

s.islower() возвращает True , если строка s не пустая, и все содержащиеся в нем буквенные символы строчные, а False если нет. Не алфавитные символы игнорируются:

string.isprintable() определяет, состоит ли строка только из печатаемых символов.

s.isprintable() возвращает, True если строка s пустая или все буквенные символы которые она содержит можно вывести на экран. Возвращает, False если s содержит хотя бы один специальный символ. Не алфавитные символы игнорируются:

Важно: Это единственный .is****() метод, который возвращает True , если s пустая строка. Все остальные возвращаются False .

string.isspace() определяет, состоит ли строка только из пробельных символов.

s.isspace() возвращает True , если s не пустая строка, и все символы являются пробельными, а False , если нет.

Наиболее часто встречающиеся пробельные символы — это пробел ‘ ‘ , табуляция ‘\t’ и новая строка ‘\n’ :

Тем не менее есть несколько символов ASCII, которые считаются пробелами. И если учитывать символы Юникода, их еще больше:

‘\f’ и ‘\r’ являются escape-последовательностями для символов ASCII; ‘\u2005’ это escape-последовательность для Unicode.

string.istitle() определяет, начинаются ли слова строки с заглавной буквы.

s.istitle() возвращает True когда s не пустая строка и первый алфавитный символ каждого слова в верхнем регистре, а все остальные буквенные символы в каждом слове строчные. Возвращает False , если нет:

string.isupper() определяет, являются ли буквенные символы строки заглавными.

s.isupper() возвращает True , если строка s не пустая, и все содержащиеся в ней буквенные символы являются заглавными, и в False , если нет. Не алфавитные символы игнорируются:

Выравнивание строк, отступы

Методы в этой группе влияют на вывод строки.

string.center( [, ]) выравнивает строку по центру.

s.center( ) возвращает строку, состоящую из s выровненной по ширине . По умолчанию отступ состоит из пробела ASCII:

Если указан необязательный аргумент , он используется как символ заполнения:

Если s больше или равна , строка возвращается без изменений:

string.expandtabs(tabsize=8) заменяет табуляции на пробелы

s.expandtabs() заменяет каждый символ табуляции ( ‘\t’ ) пробелами. По умолчанию табуляция заменяются на 8 пробелов:

tabsize необязательный параметр, задающий количество пробелов:

string.ljust( [, ]) выравнивание по левому краю строки в поле.

s.ljust( ) возвращает строку s , выравненную по левому краю в поле шириной . По умолчанию отступ состоит из пробела ASCII:

Если указан аргумент , он используется как символ заполнения:

Если s больше или равна , строка возвращается без изменений:

string.lstrip([ ]) обрезает пробельные символы слева

s.lstrip() возвращает копию s в которой все пробельные символы с левого края удалены:

Необязательный аргумент , определяет набор символов, которые будут удалены:

string.replace(

    , [, ]) заменяет вхождения подстроки в строке.

s.replace(

    , ) возвращает копию s где все вхождения подстроки
      , заменены на :

    Если указан необязательный аргумент , выполняется количество замен:

    string.rjust( [, ]) выравнивание по правому краю строки в поле.

    s.rjust( ) возвращает строку s , выравненную по правому краю в поле шириной . По умолчанию отступ состоит из пробела ASCII:

    Если указан аргумент , он используется как символ заполнения:

    Если s больше или равна , строка возвращается без изменений:

    string.rstrip([ ]) обрезает пробельные символы справа

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

    Необязательный аргумент , определяет набор символов, которые будут удалены:

    string.strip([ ]) удаляет символы с левого и правого края строки.

    s.strip() эквивалентно последовательному вызову s.lstrip() и s.rstrip() . Без аргумента метод удаляет пробелы в начале и в конце:

    Как в .lstrip() и .rstrip() , необязательный аргумент определяет набор символов, которые будут удалены:

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

    string.zfill( ) дополняет строку нулями слева.

    s.zfill( ) возвращает копию s дополненную ‘0’ слева для достижения длины строки указанной в :

    Если s содержит знак перед цифрами, он остается слева строки:


    Если s больше или равна , строка возвращается без изменений:

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

    Методы преобразование строки в список

    Методы в этой группе преобразовывают строку в другой тип данных и наоборот. Эти методы возвращают или принимают итерируемые объекты — термин Python для последовательного набора объектов.

    Многие из этих методов возвращают либо список, либо кортеж. Это два похожих типа данных, которые являются прототипами примеров итераций в python. Список заключен в квадратные скобки ( [] ), а кортеж заключен в простые ( () ).

    Теперь давайте посмотрим на последнюю группу строковых методов.

    string.join( ) объединяет список в строку.

    s.join( ) возвращает строку, которая является результатом конкатенации объекта с разделителем s .

    Обратите внимание, что .join() вызывается строка-разделитель s . должна быть последовательностью строковых объектов.

    Примеры кода помогут вникнуть. В первом примере разделителем s является строка ‘, ‘ , а список строк:

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

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

    Таким образом, результатом ‘:’.join(‘corge’) является строка, состоящая из каждого символа в ‘corge’ , разделенного символом ‘:’ .

    Этот пример завершается с ошибкой TypeError , потому что один из объектов в не является строкой:

    Это можно исправить так:

    Как вы скоро увидите, многие объекты в Python можно итерировать, и .join() особенно полезен для создания из них строк.

    string.partition( ) делит строку на основе разделителя.

    s.partition( ) отделяет от s подстроку длиной от начала до первого вхождения . Возвращаемое значение представляет собой кортеж из трех частей:

    • Часть s до
    • Разделитель
    • Часть s после

    Вот пара примеров .partition() в работе:

    Если не найден в s , возвращаемый кортеж содержит s и две пустые строки:

    s.rpartition( ) делит строку на основе разделителя, начиная с конца.

    s.rpartition( ) работает как s.partition( ) , за исключением того, что s делится при последнем вхождении вместо первого:

    string.rsplit(sep=None, maxsplit=-1) делит строку на список из подстрок.

    Без аргументов s.rsplit() делит s на подстроки, разделенные любой последовательностью пробелов, и возвращает список:

    Если указан, он используется в качестве разделителя:

    Если = None , строка разделяется пробелами, как если бы не был указан вообще.

    Когда явно указан в качестве разделителя s , последовательные повторы разделителя будут возвращены как пустые строки:

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

    Если указан необязательный параметр , выполняется максимальное количество разделений, начиная с правого края s :

    Значение по умолчанию для — -1 . Это значит, что все возможные разделения должны быть выполнены:

    string.split(sep=None, maxsplit=-1) делит строку на список из подстрок.

    s.split() ведет себя как s.rsplit() , за исключением того, что при указании , деление начинается с левого края s :

    Если не указано, между .rsplit() и .split() в python разницы нет.

    string.splitlines([ ]) делит текст на список строк.

    s.splitlines() делит s на строки и возвращает их в списке. Любой из следующих символов или последовательностей символов считается границей строки:

    Разделитель Значение
    \n Новая строка
    \r Возврат каретки
    \r\n Возврат каретки + перевод строки
    \v или же \x0b Таблицы строк
    \f или же \x0c Подача формы
    \x1c Разделитель файлов
    \x1d Разделитель групп
    \x1e Разделитель записей
    \x85 Следующая строка
    \u2028 Новая строка (Unicode)
    \u2029 Новый абзац (Unicode)

    Вот пример использования нескольких различных разделителей строк:

    Если в строке присутствуют последовательные символы границы строки, они появятся в списке результатов, как пустые строки:

    Если необязательный аргумент указан и его булевое значение True , то символы границы строк сохраняются в списке подстрок:

    Заключение

    В этом руководстве было подробно рассмотрено множество различных механизмов, которые Python предоставляет для работы со строками, включая операторы, встроенные функции, индексирование, срезы и встроенные методы.

    Python есть другие встроенные типы данных. В этих урока вы изучите два наиболее часто используемых:

    • Списки python
    • Кортежи (tuple)

    Как хранятся строки

    Эти три массива имеют одинаковую длину и одинаковое содержимое:

    Хранятся массивы b1, b2, b3 одинаково — каждый массив хранится единым куском в памяти, эти массивы одинаковой длины.

    Но следующие строки хранятся в памяти по-разному:

    sizeof(a) равен 6, sizeof(s) равен sizeof(void*) и размеру любого другого адреса, зависит от архитектуры.

    Кроме того, строковые константы могут в вашей ОС (например, Linux) хранится в read only области памяти. Т.е. их нельзя изменять, то есть код:

    Строку НЕЛЬЗЯ сравнивать ==

    Если мы напишем

    Массив b содержит такое же слово, на какое указывает переменная p. Но если мы будем сравнивать их ==, то получим ложь. Будет напечатано «НЕ равны», потому что оператор == сравнивает адреса. Получим ложь при сравнении адреса начала массива b и указателя p (разные адреса, p НЕ указывает в начало массива b, он указывает на строковую константу «world»)

    Сравнивать строки мы научимся дальше, когда будем рассказывать о стандартной функции языка С strcmp.

    Как напечатать строку

    Печатать строку можно printf по формату %s (string). Печатаются все символы от указанного адреса до ‘\0’. Сам символ ‘\0’ не печатается.

    Как прочитать строку

    Чтобы прочитать строку, память для нее должна уже быть выделена. Либо объявлен массив подходящей длины, либо выделена динамическая память. В примерах будем объявлять массивы нужной длины.

    scanf по формату %s

    Формат %s позволяет функции scanf читать набор символов. Выясним на практике, как он работает.

    Скомпилируем файл в исполняемый модуль a.out и будем его запускать (вторая строка — что вводим, последняя — что печатает программа):

    Оказывается, читается не вся строка, а «слово» до пробельного символа (пробела, табуляции, \n и так далее).

    Пробельные символы спереди пропускаются.

    Проблема: пользователь может ввести больше 100 символов и мы выйдем за границы массива char a[100]; Что делать? Использовать модификацию к форматеру %s, чтобы указать максимальное количество прочитанных символов.

    Так как у нас закончилась печать на букве z, после нее был поставлен символ ‘\0’.

    То есть при указанном ограничении в 3 символа записали 4 символа.

    Т.е. для массива char a[10] нужно писать scanf(«%9s», a);

    Что делать, если нужно прочитать не слово, а строку?

    fgets

    Строку можно прочитать стандартной функцией gets, но так НЕ НАДО ДЕЛАТЬ!

    Даже в help по этой функции пишут, что не нужно ее использовать.

    При компиляции мы получаем предупреждение, что не надо использовать gets.

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

    Что делать? Использовать похожую функцию char *fgets(char *s, int size, FILE *stream)

    Заметим, что записалось 5 символов ВМЕСТЕ с символом ‘\0’. Т.е. для массива char a[10] можно писать fgets(a, 10, stdin);

    Как завершить ввод?

    Допустим, мы читаем по словам (или по строкам) текст. Как сказать, что текст закончился?

    Чтобы закончить ввод текста с клавиатуры, введите ^D (Linux, Mac) или ^Z (Windows)

    Задача (про капитана Флинта)

    Капитан Флинт зарыл клад на Острове сокровищ. Он оставил описание, как найти клад. Описание состоит из строк вида: “North 5”, где первое слово – одно из “North”, “South”, “East”, “West”, а второе число – количество шагов, необходимое пройти в этом направлении.

    Напишите программу, которая по описанию пути к кладу определяет точные координаты клада, считая, что начало координат находится в начале пути, ось OX направлена на восток, ось OY – на север.

    Программа получает на вход последовательность строк указанного вида, завершающуюся строкой со словом “Treasure!”. Программа должна вывести два целых числа: координаты клада.

    (Примечание: мы будем признательны, если сможем указать автора задачи. Эта задача столько раз кочевала по разным контестам для школьников, что пора писать слова народные «задача классическая»).

    Направление и шаги мы будем читать так:

    Теперь нужно узнать — какое именно слово лежит в массиве sdir. Т.е. сравнить строку с образцом.

    Стандартные функции языка С

    Не забудьте для работы с этими функциями написать

    Рассмотрим наиболее используемые функции:

    strlen

    size_t strlen(const char *s);

    Возвращает количество символов в строке БЕЗ подсчета ‘\0’

    Попробуем написать такую же функцию mystrlen и проверить ее

    Как понять, что возвращать из mystrlen, i, или i-1, или i+1?

    Попробуем посчитать в уме длину строки «z». При i=0 учитываем z, i++ сделает i=1, потом проверка s[i]!=’\0′ даст ложь и мы выйдем из цикла. i=1. Вернуть нам надо тоже 1. Т.е return i.

    Проверяйте свой алгоритм мысленно на коротких примерах, строках длины 1, 0, максимум 3.

    Напишем эту функцию через указатели.

    Пусть указатель p сначала указывает на начало строки s, потом в цикле сдвигается на 1 символ p = p+1 или p++, пока его содержимое *p не станет равно ‘\0’ (концу строки).

    Как тогда вычислить длину строки? Пусть начало строки «abc» лежит по адресу 100 (s = 100). Тогда буква а лежит по адресу 100, b по адресу 101, c по адресу 102, \0 по адресу 103.

    Когда мы закончим цикл, p будет содержать адрес 103 (был бы 102, мы бы цикл продолжали, там буква с). Вернуть нужно число 3. В переменной p у нас число 103, в переменной s число 100. Значит возвращаем p — s.

    напоминаем, что тип size_t печатается по формату %zd

    Дополнительно: разберите что делает код:

    Делает ли эта функция то же самое, или есть ошибка?

    strcmp, strncmp — сравнение строк

    int strcmp(const char *s1, const char *s2);

    int strncmp(const char *s1, const char *s2, size_t n);

    Функция strcmp() сравнивает две строки: s1 и s2. Она возвращает целое число, которое меньше, больше нуля или равно ему, если s1 соответственно меньше, больше или равно s2.

    Функция strncmp() работает аналогичным образом, но сравнивает только первые n символов строки s1.

    Если нужно выяснить, равна строка s образцу, например «Treasure!», то пишем

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

    strcpy, strncpy — копирование строки

    char *strcpy(char *dest, const char *src);

    char *strncpy(char *dest, const char *src, size_t n);

    Функция strcpy() копирует строку, на которую указывает src (включая завершающий символ ‘\0’), в массив, на который указывает dest. Строки не могут перекрываться, и в результирующей строке dest должно быть достаточно места для копии.

    Функция strncpy работает аналогично, кроме того, что копируются только первые n байтов строки src. Таким образом, если в n байтах строки src нет нулевого байта, то строка результата не будет заканчиваться символом ‘\0’.

    Если длина src меньше, чем n, то остальное место в dest будет заполнено нулями.

    Функции strcpy() и strncpy() возвращают указатель на результирующую строку dest.

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

    Попробуем написать ее через указатели. Указатель s идет по строке src с начала до ‘\0’, сдвигаясь каждый раз на 1 символ. Указатель p идет по строке dest, сдвигаясь каждый раз на 1 символ.

    Попробуйте сами разобраться, почему эта функция работает точно так же, как и предыдущая:

    strcat, strncat — конкатенация (склейка строк)

    char *strcat(char *dest, const char *src);

    char *strncat(char *dest, const char *src, size_t n);

    Функция strcat() добавляет строку str к строке dest, перезаписывая символ ‘\0’ в конце dest и добавляя к строке символ окончания ‘\0’. Строки не могут перекрываться, а в строке dest должно хватать свободного места для размещения объединенных строк.

    Функция strncat() работает аналогичным образом, но добавляет к dest только первые n символов строки src (и дописывает в конец еще и ‘\0’).

    Функции strcat() и strncat() возвращают указатель на строку, получившуюся в результате объединения dest.

    Можно написать самим функцию mystrcat в 1 строку, используя функции strlen и strcpy.

    strchr, strrchr — поиск символа в строке

    char *strchr(const char *s, int c);

    char *strrchr(const char *s, int c);

    Функция strchr() возвращает указатель на местонахождение первого совпадения с символом c в строке s.

    Функция strrchr() возвращает указатель на местонахождение последнего совпадения с символом c в строке s.

    Функции strchr() и strrchr() возвращают указатель на совпадения с соответствующим символом, а если символ не найден, то возвращают NULL.

    strstr — поиск подстроки в строке

    char *strstr(const char *str, const char *substr);

    Функция strstr() ищет первое вхождение подстроки substr в строке str. Завершающий символ `\0′ не сравнивается.

    Возвращает указатель на начало подстроки, или NULL, если подстрока не найдена.

    Прочие функции списком

    strtok (TODO)

    Преобразование из числа в строку — sprintf

    Мы умеем печатать часы и минуты в виде 05:12 или 21:07. Как так же быстро переводить часы и минуты в строку по нужному формату?

    Используйте функцию sprintf, которая работает почти так же и имеет почти такие же параметры, что и printf, но первым аргументом нужно указать строку, куда будет sprintf писать (она НИЧЕГО не печатает, печатать надо отдельно).

    Преобразование из строки в число — scanf

    Как вы догадались, аналогичная функция есть и для scanf. Это sscanf

    Разберем строку «21:07» в переменные h и m (часы и минуты)

    Аналогично можно использовать эту функцию для разбора нецелых чисел. Кроме scanf есть специальные функции, преобразующие строку в число по произвольному базису с контролем ошибок.

    strtol, strtod, strtou — преобразование строки в число с контролем ошибок

    strtol, strtoll — перевод строки в длинное целое (long int)

    strtoul, strtoull — конвертирует строку в беззнаковое целое число (unsigned long integer)

    strtod, strtof, strtold — конвертируют строки ASCII в число с плавающей запятой

    Прототипы функций:

    • long int strtol(const char *nptr, char **endptr, int base);
    • long long int strtoll(const char *nptr, char **endptr, int base);
    • unsigned long int strtoul(const char *nptr, char **endptr, int base);
    • unsigned long long int strtoull(const char *nptr, char **endptr, int base);
    • double strtod(const char *nptr, char **endptr);
    • float strtof(const char *nptr, char **endptr);
    • long double strtold(const char *nptr, char **endptr);

    Функция strtol() конвертирует начальную часть строки nptr в длинное целое в соответствии с указанным base, которое должно находиться в диапазоне от 2-х до 36-х включительно или быть равным нулю.

    endptr может быть равным NULL и тогда на него не обращают внимание.

    Если endptr указан не NULL, то в него пишут указатель первого некорректного символа из nptr.

    Если в строке вообще нет цифр, то strtol() сохраняет начальное значение nptr в *endptr (и возвращает 0). В частности, если *nptr не равно ‘\0’, а **endptr равно ‘\0’ по возвращении, то вся строка состоит из корректных символов.

    А кто конвертирует строку в число функциями atoi, atol, atod, тот не контролирует ошибки и злобный еретик.

    Функции чтения, использующие динамическую память

    Если вы еще не знаете, что такое функции malloc, realloc, free, то пропустите этот раздел и вернитесь к нему после изучения работы с динамической памятью.

    getline — читаем строку, выделяя память динамически.

    Часто бывает, что мы заранее не знаем максимальный размер строки и не можем задать размер массива, чтобы хватило «с запасом». Читать в несколько подходов тоже неудобно.

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

    getline() считывает целую строку, сохраняя адрес буфера, содержащего текст, в *lineptr. Буфер завершается null и содержит символ новой строки, если был найден разделитель для новой строки. Если *lineptr равно NULL, то процедура getline() будет создавать буфер для содержимого строки, который затем должен быть высвобожден программой пользователя. Как альтернатива, перед вызовом getline(), *lineptr может содержать указатель на буфер, размещенный через malloc() с размером *n байтов. Если буфер недостаточно велик для размещения всей считанной строки, то getline() изменяет размер буфера с помощью realloc(), обновляя *lineptr и *n при необходимости. В любом случае при успехном вызове *lineptr и *n будут обновлены для отражения адреса буфера и его размера соответственно.

    getdelim() работает аналогично getline(), за исключением того, что разделитель строки, отличающийся от символа новой строки будет определен, как аргумент delimiter. Как и с getline(), символ-разделитель не добавляется, если на вводе не появилось знака разделения и уже достигнут конец файла.

    При нормальном завершении работы getline() и getdelim() возвращают номер считанных символов, включая символ разделителя, но не включая завершающий символ null. Это значение может использоваться для обработки встроенных символов null при чтении строки. Обе функции возвращают -1 при ошибках чтения строки (включая условие достижения конца файла).

    Функция изначально была расширением GNU и была внесена в стандарт POSIX.1-2008.

    scanf(«%ms», str)

    Аналогично память выделяется динамически при задании форматера чтения %ms. Указанная строка выделяется динамически и ее нужно потом освободить.

    Правильное использование strtol

    Программа ниже преобразует строку в длинную, но, основываясь на моем понимании, она также возвращает ошибку. Я полагаюсь на то, что если strtol успешно преобразовать строку в long, то второй параметр strtol должен быть равен NULL. Когда я запускаю приложение ниже с 55, я получаю следующее сообщение.

    Как я могу успешно обнаружить ошибки из strtol? В моем приложении нуль является допустимым значением.

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

    Обратите внимание, что имена, начинающиеся с символа подчеркивания, зарезервированы для реализации; лучше избегать использования таких имен в вашем коде. Следовательно, _val должен быть просто val .

    Полная спецификация обработки ошибок для strtol() и ее родственников сложна, на удивление сложная, когда вы сначала сталкиваетесь с ней. Единственное, что вы делаете абсолютно правильно, это использовать функцию для вызова strtol() ; использование его «raw» в коде, вероятно, неверно.

    Поскольку вопрос отмечен как C, так и С++, я приведу цитату из стандарта C2011; вы можете найти соответствующую формулировку в стандарте С++ для себя.

    ISO/IEC 9899: 2011 §7.22.1.4 Функции strtol , strtoll , strtoul и strtoull

    long int strtol(const char * restrict nptr, char ** restrict endptr, int base);

    ¶2 [. ] Во-первых, они разлагают входную строку на три части: начальную, возможно пустую, последовательность символы пробела (как указано в функции isspace), последовательность объектов напоминающий целое число, представленное в некотором радиусе, определяемое значением базы, и конечная строка одного или нескольких непризнанных символов, включая завершающий нуль символ входной строки. [. ]

    ¶7 Если последовательность объектов пуста или не имеет ожидаемой формы, преобразование не является выполнено; значение nptr сохраняется в объекте, на который указывает endptr , при условии, что что endptr не является нулевым указателем.

    Возврат

    ¶8 Функции strtol , strtoll , strtoul и strtoull возвращают преобразованные ценность, если таковая имеется. Если преобразование не может быть выполнено, возвращается ноль. Если правильное значение находится вне диапазона представляемых значений, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX или ULLONG_MAX (в соответствии с типом возврата и знак значения, если таковой имеется), а значение макроса ERANGE хранится в errno .

    Помните, что никакая стандартная функция библиотеки C никогда не устанавливает errno в 0. Поэтому, чтобы быть надежным, вы должны установить errno в ноль перед вызовом strtol() .

    Итак, ваша функция parseLong() может выглядеть так:

    Обратите внимание, что при ошибке это возвращает 0 или LONG_MIN или LONG_MAX, в зависимости от возвращаемого strtol() . Если ваш код вызова должен знать, было ли преобразование успешным или нет, вам нужен другой функциональный интерфейс — см. Ниже. Также обратите внимание, что ошибки следует печатать на stderr , а не на stdout , а сообщения об ошибках должны быть завершены с помощью новой строки \n ; Если это не так, они не гарантированно появятся своевременно.

    Теперь, в коде библиотеки, вы, вероятно, не хотите печати, и ваш код вызова может захотеть узнать, было ли преобразование успешным, так что вы также можете пересмотреть интерфейс. В этом случае вы, вероятно, измените функцию, чтобы она отображала индикацию успеха/отказа:

    который вы можете использовать следующим образом:

    Если вам нужно различать «trailing junk», «invalid numeric string», «value too large» и «value too small» (и «no error» ), вы должны использовать целое число или enum вместо логического кода возврата. Если вы хотите разрешить пробел в пробеле, но никаких других символов, или если вы не хотите разрешать какое-либо ведущее белое пространство, у вас есть больше работы в этой функции. Код позволяет восьмеричные, десятичные и шестнадцатеричные; если вы хотите строго десятичное, вам нужно изменить 0 на 10 при вызове strtol() .

    Если ваши функции маскируются как часть стандартной библиотеки, они не должны постоянно устанавливать errno на 0 , поэтому вам нужно будет обернуть код для сохранения errno :

    Илон Маск рекомендует:  Что такое код changeclipboardchain
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL