Java lang string как разбить string arduino
Перейти к содержимому

Java lang string как разбить string arduino

  • автор:

Java lang string как разбить string arduino

Здравствуйте! Вопрос по ардуино.
Подскажите пожалуйста как разбить строку(String) в массив символов?
Так чтобы из строки

String str "one"

получился массив(предполагаю что char, но можно и int) в котором каждый символ из строки вставал в свою ячейку массива. В конце у массива должно быть примерно такое содержимое «o, n, e».
Помогите пожалуйста!
Весь интернет облазил и ничего не нашёл!
Заранее спасибо!

Последний раз редактировалось [Timur]; 25.05.2020 в 17:24 .
Пользователь
Регистрация: 03.06.2019
Сообщений: 48

Ура. Не знаю как выражать эмоции! У меня получилось! Ответ был прямо под носом!

У моего любимого блогера alex gyver’a есть вот эта статья которую я прочитал в первую очередь
https://alexgyver.ru/lessons/strings/
и тут я и нашёл ответ! Он в разделе «Инструменты для String», он здесь первый «charAt()», а точнее не это, а то что в описании «Аналог – myString[index];»

Я попробовал и ЭТО СРАБОТАЛО! Да, да к строке можно обратится также как и к массиву!
Напишите своё мнение о этом способе и если он вам помог то напишите!

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разбить строку на двумерный массив Pashka_Noob Общие вопросы по Java, Java SE, Kotlin 6 31.07.2017 18:33
Пользователь вводит строку,закодированную кодом из таблицы ASCII. Необходимо вывести строку посимвольно. anasttb Паскаль, Turbo Pascal, PascalABC.NET 1 28.02.2017 17:20
C++ Перевести строку, в которой записано длинное целое, посимвольно в int массив. Alendorff Помощь студентам 7 10.06.2012 14:25
Разбить строку на массив строк с помо*щью символа-разделителя PotatoCaptain Общие вопросы C/C++ 14 14.12.2011 17:59
разбить строку Ceprey Общие вопросы C/C++ 10 24.12.2009 20:47

3.7. Java примеры – Разбиение строки на слова и символы в массив и по разделителю

Следующий пример показывает как разделить строку в Java по разделителю с помощью метода split() и вывести подстроку.

public class Example < public static void main(String args[]) < System.out.println("Пример 1:"); String str = "разделить-строку-по-разделителю"; String[] subStr; String delimeter = "-"; // Разделитель subStr = str.split(delimeter); // Разделения строки str с помощью метода split() // Вывод результата на экран for(int i = 0; i < subStr.length; i++) < System.out.println(subStr[i]); >// Ещё один пример разделения System.out.println("\nПример 2:"); str = "разделить.строку.по разделителю"; delimeter = "\\."; // Разделитель subStr = str.split(delimeter); // Вывод результата на экран for(int i = 0; i < subStr.length; i++) < System.out.println(subStr[i]); >// Ещё один пример разделения с использованием порога System.out.println("\nПример 3:"); str = "разделить!строку!по!разделителю"; delimeter = "!"; // Разделитель subStr = str.split(delimeter, 3); // Разбить строку str с порогом равным 3, который означает, как много подстрок, должно быть возвращено. // Вывод результата на экран for(int i = 0; i < subStr.length; i++) < System.out.println(subStr[i]); >> > 

Результат

Получим следующий результат:

Пример 1: разделить строку по разделителю Пример 2: разделить строку по разделителю Пример 3: разделить строку по!разделителю 

Решение 2: разбить строку на слова

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

public class Example < public static void main(String args[]) < String str = "разбить строку на слова"; String[] words = str.split("\\s"); // Разбиение строки на слова с помощью разграничителя (пробел) // Вывод на экран for(String subStr:words) < System.out.println(subStr); >> > 

Результат

Получим следующий результат:

разбить строку на слова 

Решение 3: разбить строку на символы в массив

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

public class Example < public static void main(String args[]) < String str = "ProgLang"; char[] strToArray = str.toCharArray(); // Преобразуем строку str в массив символов (char) // Вывод массива на экран for(int i = 0; i < strToArray.length; i++) < System.out.print(strToArray[i] + " "); // Для наглядности вставим пробел между индексами >> > 

Результат

Получим следующий результат:

P r o g L a n g 

Оглавление

  • 1. Java примеры – Использование кода на практике
  • 2. Java примеры – Окружающая среда
  • 2.1. Java примеры – Скомпилировать файл
  • 2.2. Java примеры – Установить путь к нескольким классам
  • 2.3. Java примеры – Отладка java-файла
  • 2.4. Java примеры – Установить путь к классу
  • 2.5. Java примеры – Просмотреть текущий путь класса
  • 2.6. Java примеры – Установить назначение файла класса
  • 2.7. Java примеры – Запустить скомпилированный java-файл класса
  • 2.8. Java примеры – Узнать версию Java
  • 2.9. Java примеры – Установить путь к классу в .jar-файле или .zip-файле
  • 3. Java примеры – Строки
  • 3.1. Java примеры – Сравнить две строки
  • 3.2. Java примеры – Найти последнее вхождение подстроки внутри подстроки
  • 3.3. Java примеры – Удалить нужный символ из строки
  • 3.4. Java примеры – Заменить символ в строке
  • 3.5. Java примеры – Вывод в обратном порядке
  • 3.6. Java примеры – Нахождение символа или слова в строке
  • 3.7. Java примеры – Разбиение строки на слова и символы
  • 3.8. Java примеры – Преобразование строки в верхний регистр
  • 3.9. Java примеры – Найти слово в строке
  • 3.10. Java примеры – Сравнить производительность создания строки
  • 3.11. Java примеры – Оптимизировать создание строк
  • 3.12. Java примеры – Форматирование строк
  • 3.13. Java примеры – Конкатенация строк
  • 3.14. Java примеры – Определить код Юникода символа в строке
  • 3.15. Java примеры – Буферизация строк
  • 4. Java примеры – Массивы
  • 4.1. Java примеры – Сортировка массива и поиск элемента
  • 4.2. Java примеры – Метод сортировки массива, вставить элемент в массив
  • 4.3. Java примеры – Размер двумерного массива
  • 4.4. Java примеры – Обратный порядок массива, переворачиваем массив
  • 4.5. Java примеры – Как выводить массивы и двумерные массивы в консоль
  • 4.6. Java примеры – Найти максимальный и минимальный элемент массива
  • 4.7. Java примеры – Соединить два массива в один
  • 4.8. Java примеры – Как заполнить массив числами
  • 4.9. Java примеры – Увеличить массив после инициализации
  • 4.10. Java примеры – Сравнение двух массивов
  • 4.11. Java примеры – Удаление элемента из массива
  • 4.12. Java примеры – Удаление массива из другого массива
  • 4.13. Java примеры – Одинаковые элементы массивов
  • 4.14. Java примеры – Поиск в массиве
  • 4.15. Java примеры – Равенство двух массивов
  • 4.16. Java примеры – Сравнить массивы
  • 5. Java примеры – Дата и время
  • 5.1. Java примеры – Форматирование времени в формате AM-PM
  • 5.2. Java примеры – Получение названия и номера текущего месяца
  • 5.3. Java примеры – Получить текущее время в часах и минутах
  • 5.4. Java примеры – Вывести текущее время и дату
  • 5.5. Java примеры – Вывести текущее время в 24-часовом формате
  • 5.6. Java примеры – Получить текущий месяц
  • 5.7. Java примеры – Получить текущие секунды
  • 5.8. Java примеры – Получить короткое название месяца
  • 5.9. Java примеры – Получить день недели
  • 5.10. Java примеры – Добавление времени к дате
  • 5.11. Java примеры – Отображение времени в формате другой страны
  • 5.12. Java примеры – Отображение времени на разных языках
  • 5.13. Java примеры – Прокрутить часы и месяцы
  • 5.14. Java примеры – Получить номер недели и месяц в году
  • 5.15. Java примеры – Форматы текущей даты
  • 6. Java примеры – Методы
  • 6.1. Java примеры – Перезагрузка методов
  • 6.2. Java примеры – Вывод массива с использованием метода
  • 6.3. Java примеры – Решение Ханойской башни
  • 6.4. Java примеры – Последовательность чисел Фибоначчи
  • 6.5. Java примеры – Вычисление факториала числа
  • 6.6. Java примеры – Переопределение метода
  • 6.7. Java примеры – Вывод массива с использованием метода
  • 6.8. Java примеры – Использование оператора break
  • 6.9. Java примеры – Использование оператора continue
  • 6.10. Java примеры – Использование метки в методе
  • 6.11. Java примеры – Использование операторов enum и switch
  • 6.12. Java примеры – Использование конструктора enum

Разделение строки Arduino

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

18 мая 2018 в 17:53

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

char pLoginPass[]; char* pLogin; char* pPassword; pLogin = pLoginPass; pPassword = pLogin; while( *pPassword != ':' ) ++pPassword; *pPassword = 0; ++pPassword; // Чунга-чанга. 

Отслеживать
ответ дан 18 мая 2018 в 21:59
Vanyamba Electronics Vanyamba Electronics
2,693 13 13 золотых знаков 19 19 серебряных знаков 26 26 бронзовых знаков

Насколько я знаю, язык программирования Arduino — C++. Нагуглил код по этой же проблеме:

string str("Строка, которую нужно разбить."); string separ("разделитель"); string::size_type pos = str.find(separ); // Позиция первого символа строки-разделителя. string::size_type pos = str.find(separ); // Позиция первого символа строки-разделителя. string first = str.substr(0, pos); // Строка до разделителя. string second = str.substr(pos+separ.length()); // Строка после разделителя. 

Отслеживать
ответ дан 18 мая 2018 в 19:58
AndreiNekrasOn AndreiNekrasOn
45 1 1 серебряный знак 7 7 бронзовых знаков
Спасибо, пригодиться.
19 мая 2018 в 16:31

  • парсер
  • ide
  • arduino
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.2.1.4133

Разбиваем строку на подстроки по разделяющим символам своими руками

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

Для разработки использовался компилятор gcc. Код писался под стандарт C99. Он несовместим с С90 из-за наличия объявлений с присваиванием (вида var a = val; а не var a;), а также объявлений в конце функций. Используемые флаги компилятора:

-Wall -Werror -pedantic -std=c99

Вообще говоря, сама задача разбиения строк на подстроки, каждая из которых отделена в исходной строке определённым символом, является довольно распространённой. Очень часто необходимо извлечь из строки слова, разделённые пробелами. Конечно, в стандартной библиотеке языка Си уже есть функция strtok (заголовочный файл ), но она имеет свои побочные эффекты, перечисленные ниже.

  1. Функция модифицирует исходную строку, разбивая её на лексемы. Она возвращает указатель на саму лексему, или NULL, в случае, когда нет больше лексем. Подробнее о ней можно прочитать здесь.
  2. Так как функция модифицирует строку, то при передачи ей строчного литерала, будет получено SEGV, поскольку память для таких литеральных строк выделяется в сегменте кода, доступного только для чтения.
  3. Для последующих вызовов, функции необходимо передавать нулевой указатель (литерал NULL), чтобы она могла продолжить сканирование с последней распознанной лексемы (предыдущего вызова).
  4. Она не учитывает экранирование символов разделителей.

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

  1. Не менять оригинальную строку, в которой ищутся лексемы.
  2. Для каждой найденной лексемы создавать новую строку.
  3. Сохранять свою текущую позицию, а именно — указатель на подстроку, которая ещё не разбиралась.
  4. Иметь однородную последовательность вызовов.
  5. Иметь возможность экранировать символы разделители, при сложных лексемах.
  6. Иметь возможность работать со строковыми литералами (константами).

Основные шаги при разделении строк

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

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

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

Разработка функции

Приступим к разработке. Для начала определим заголовочный файл «str_utils.h», содержащий все прототипы необходимых функций. Реализации функций положим в файл «str_utils.c«.

Начнём с функции нахождения символов в строке. Библиотечная функция strchr могла бы решить эту задачу. Но проблема в том, что она не допускает в качестве аргумента строки, в которой надо искать символ, значения NULL. При попытке компилировать с флагами -Wall -Werror , файл с таким аргументом не скомпилируется. Хотя, такую ситуацию можно было бы обработать, вернув NULL. Поэтому был определён свой вариант данной функции с именем contains_symbol. Её прототип выглядит следующим образом:

size_t contains_symbol(char *symbols, char symbol);

Её реализация определена следующим образом (файл «str_utils.c»):

size_t contains_symbol(char *symbols, char symbol) < size_t pos = 1; if(symbols == NULL) return 0; while(*symbols != '\0')< if(*symbols++ == symbol) return pos; pos++; >return 0; >

Данная функция возвращает позицию символа в строке, увеличенную на единицу. Она не учитывает нулевой символ. Если символ не был найден или ей передали NULL,, функция вернёт 0. Её удобно использовать в цикле while, при проверке текущего символа строки на его наличие в другой строке.

Для инкапсуляции работы с памятью был определён отдельный заголовочный файл «mem.h», содержащий следующие прототипы:

void *alloc_mem(size_t nbytes); void *calloc_mem(size_t nelems, size_t elem_size); #define alloc_str(x) ((char *) alloc_mem(x + 1))

Соответствующие функции реализованы в отдельном файле «mem.c»:

#include #include void *alloc_mem(size_t nbytes) < char *buf = (char *)malloc(nbytes); if(buf != NULL)< memset(buf, '\0', nbytes); return buf; >exit(-1); > void *calloc_mem(size_t nelems, size_t elem_size) < void *buf = calloc(nelems, elem_size); if(buf != NULL)< return buf; >exit(-1); >

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

Функция обрезки разделителей строки trim_separators выглядит следующим образом:

/* trims symbols from separators at src string */ /* returns new trimmed string */ char *trim_separators(char *src, char *separators);
char *trim_separators(char *src, char *separators) < if(src == NULL || separators == NULL) return NULL; char *sp = src; while(contains_symbol(separators, *sp)) sp++; /* if it contains only symbols from separators =>NULL */ if(sp - s == strlen(s)) return NULL; char *sp2 = s + strlen(s) - 1; /* last char at src */ while(contains_symbol(separators, *sp2)) sp2--; /* if it contains only symbols from separators => NULL */ if(sp2 < s) return NULL; size_t sz = 0; if(sp2 - sp == 0 && *sp == '\0') return NULL; /* zero byte is not a character */ else if(sp2 - sp == 0)< sz = 1; >else < sz = (sp2 - sp) + 1; >char *res = alloc_mem(sz); memcpy(res, sp, sz);/* copy all chars except last zero byte */ return res; >

В начале мы проверяем на NULL аргументы функции. Если они нулевые, то возвращаем NULL.

Далее, через указатель sp, проходим строку слева направо, пока мы встречаем символы из строки separators. Если мы прошли всю строку, значит она целиком и полностью состоит из сепараторов, следовательно надо удалить все символы, или же просто вернуть NULL.

char *sp = src; while(contains_symbol(separators, *sp)) sp++; /* if it contains only symbols from separators => NULL */ if(sp - s == strlen(s)) return NULL;

Аналогично, далее через указатель sp2, проходим строку справа налево, проверяя, находится ли текущий символ в массиве separators. Если это не так, то мы прерываем цикл, а указатели будут содержать ссылку на первые символы, не являющимися разделителями. Если мы опять прошли всю строку, значит снова придётся удалять всю строку, следовательно, возвращаем NULL.

char *sp2 = s + strlen(s) - 1; /* last char at src */ while(contains_symbol(separators, *sp2)) sp2--; /* if it contains only symbols from separators => NULL */ if(sp2 < s) return NULL;

Наконец, вычисляем длину строки. Если указатели ссылаются на одно и то же место, то в строке был лишь один символ, не являющийся разделителем, а потому размер результата будет равным 1 байту (один лишний байт для нулевого символа учтён в макросе alloc_str). Если же этот единственный символ является нулевым (маркером конца), то возвращаем NULL. Иначе берём разницу между адресами указателями, прибавляем к ней единицу, и получаем длину новой строки. Затем мы просто выделяем память для новой строки и копируем в неё строку, начинающуюся с указателя sp.

Теперь, объединим работу выше написанных функции, в единую функцию get_token().

Код функции get_token дан ниже:

char *get_token(char *src, char *delims, char **next) < if(src == NULL || delims == NULL) return NULL; char *delims_p = delims; /* the end of lexem (points to symbol that follows right after lexem */ char *src_p = trim_separators(src, delims); /* the begining of the lexem */ char *lex_begin = src_p; if(src_p == NULL)< *next = NULL; return NULL; >/* flag that indicates reaching of delimeter */ int flag = 0; while(*src_p != '\0') < flag = 0; while(*delims_p != '\0')< if(*delims_p == *src_p)< flag = 1; break; >delims_p++; > if(flag == 1) break; delims_p = delims; src_p++; > /* now src_p points to the symbol right after lexem */ /* compute lexem size and reset pointers (from trimmed to the original src) */ char *offset; size_t tok_size; offset = (src + strspn(src, delims)); tok_size = (src_p - lex_begin); free(lex_begin); lex_begin = offset; src_p = offset + tok_size; if(*src_p == '\0') *next = NULL; else *next = src_p; /* result token */ char *res = alloc_str(tok_size); memcpy(res, lex_begin, tok_size); return res; >

В ней используется функция обрезки trim_separators(). Функция обрезки возвращает новую строку, и далее сканирование ведётся по ней. В цикле лишь проверяется, не равен ли текущий символ какому-либо символу разделителю из массива символов delims, и если равен, то выйти из цикла. Указатель src_p проходит по сканируемой строке. После цикла он будет указывать на символ, следующий за лексемой (конец лексемы). А начало лексемы сохраняется в указателе lex_begin, который изначально указывает на начало обрезанной, сканируемой строки. После обнаружения границ лексемы, вычисляется её размер (её число символом), а затем сканируемая строка удаляется из динамической кучи. Затем указатели переустанавливаются на позиции в оригинальной строке (первый аргумент функции get_token()), а часть строки, которая ещё не была разобрана, присваивается в качестве содержимого двойному указателю next. Обратите внимание, что next является ссылкой на другой указатель (в данном случае, на указатель строки). Двойной указатель позволяет менять значение переменной типа char *, записывая новый адрес в next. Для первого вызова данной функции, next должен хранить адрес переменной указателя, которая указывает на строку и хранит адрес первой ячейки строки. Однако, при работе с двойным указателем возможна серьёзная и незаметная ошибка, если в качестве начального значения next передать адрес переменной, которая непосредственно указывает на строку, а не адрес переменной копии, которая содержит копию адреса строки. В следующем разделе подробно описана данная ситуация, и показан пример работы данной функции.

Пример работы get_token()

Ниже дан простой рабочий пример функции get_token(). Оригинальная строка с лексемами хранится в указателе test, копия адреса строки (копия переменной test) хранится в переменной copytest. Указатель tok хранит текущую распознанную лексему, а next - сканируемую часть строки. Данная программа разделяет строку test по пробелу и символу табуляции на подстроки, и выводит их. Также она выводит саму строку test до и после работы функции. Как можно убедиться по выводу, оригинальная строка не меняется.

#include #include #include #include "mem.h" #include "str_utils.h" int main(int argc, char **argv) < char *test = " They have a cat.\n \0"; char *copytest = test; char **next = ©test; /* has side effect on copytest */ char *tok = NULL; printf("src:%s\n", test); printf("copytest:%s\n", copytest); while(*next != NULL)< tok = get_token(*next, " \t\0", next); if(tok == NULL) break; printf("%s\n", tok); free(tok); >printf("src after:%s\n", test); printf("copytest after:%s\n", copytest); return 0; > 

Вывод данной программы:

src: They have a cat. copytest: They have a cat. They have a cat. src after: They have a cat. copytest:(null)

Обратите внимание, что в цикле есть дополнительная проверка на NULL указателя tok. Дело в том, что при получении последнего слова в строке (а именно "cat.\n"), указатель next будет указывать на подстроку, состоящую лишь из одних пробелов (плюс нулевой символ). Функция trim_separators() для таких строк возвращает NULL, так как по логике придётся урезать все символы в строке. В итоге get_token() также вернёт NULL, поскольку уже ничего не осталось для сканирования. Поэтому переменная tok сохранит значение NULL, на последнем шаге.

Теперь снова по поводу двойного указателя next. Как вы могли заметить, в вышеприведённом коде ему передаётся адрес переменной copytest, а не переменной test. Дело в том, что мы можем нечаянно затереть значение переменной test (именно переменной, а не самой строки). Для примера, изменим код следующим образом. Передадим адрес test в указатель next. В итоге мы получим следующий вывод.

src: They have a cat. copytest: They have a cat. They have a cat. src after:(null) copytest: They have a cat. 

Как видите, сама строка не меняется, но изменилось значение переменной test. Теперь она содержит NULL, поскольку на последнем шаге, функция присваивает ей соответствующее значение. Отсюда следует, что операции вида:

*next = addr; *next = NULL;

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

Модификация функции get_token(). Экранирование разделителей

Функция get_token() умеет возвращать новые подстроки (токены) из исходной строки, не меняя её. Однако она совершенно не умеет их экранировать, в случае, когда лексемы представляют собой более сложные объекты. Например, а что если лексема содержит символ, который мы выбрали в качестве разделителя?

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

1233,"John Cenna","Male",4.22,"2004, 2005, 2006",1 1234,"John Doe","Male",4.24,"2001, 2004, 2007",0 1235,"Maria Laws","Female",4.23,"2003, 2006, 2008",1

Данные значения формируют следующую таблицу:

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

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