Строка это массив?
Артём Заборских, я цитату общего определения для кого привёл?
Ой, кажется, я взломал жаваскрипт.





- Вконтакте

Строка ─ это массив чаров. И это в целом особенность языков программирования.
- Вконтакте

Чтение через квадратные скобки и свойство length — на этом и заканчиваются общие черты, пожалуй? У строки чтение символа по его позиции через квадратные скобки — скорее просто синтаксический «сахар», более короткая запись метода строки charAt()
Фундаментальное отличие строки от массива символов — строка неизменяема (иммутабельна, immutable).
Почему неудобно заменять строки массивами символов
Следующая страница
Задачи
Cкачать материалы урока
- формат ANSI;
- cтроки с завершающим нулем (используется в C).
Работа со строками в С
- ввод и вывод строк;
- преобразование строк;
- обработка строк.
- перевод строки,
- табуляция;
- пробел.
char * fgets(char * buffer, int size, FILE * stream);
int sscanf(const char * restrict buffer, const char * restrict string, [address] . );
Почему неудобно заменять строки массивами символов
Следующая страница
Задачи
Cкачать материалы урока
Уроки 97 — 104
Символьные строки. Функции для работы с символьными строками
§66. Символьные строки
Следующая страница
Задачи
Cкачать материалы урока
воскресенье, 4 августа 2013 г.
- Ещё более доступное объяснение
- Дополнительные материалы
- 12 задач на программирование с автоматической проверкой решения
- Как и любая переменная, строка может быть инициализирована (т.е. ей присвоено некоторое значение) непосредственно при её объявлении.
- Мы можем не задавать при инициализации размер массива.
- Массив символов, в который необходимо записать вводимую строку.
- Количество символов, которые может считать функция с учетом символа конца строки. В нашем случае это 10, т.е. рабочих из них девять, и один зарезервирован для конца строки.
- Откуда читать данные. В нашем случае указан стандартный поток ввода.
- На вход программе подается строка, длинной не более 100 символов. Напишите программу, которая определяет длину этой строки, без учета нулевого символа.
- Напишите программу, которая переводит данную строку в нижний регистр. Т.е. и строки «Hello WorlD» должна получиться строка «hello world»
- На вход программе подается строка, длинной не более 100 символов. Определить, является ли она перевертышем. Например, как слово «шалаш» или «топот». Учтите что строка может содержать пробелы, их учитывать не нужно. Например, строка «А роза упала на лапу Азора» будет являться перевертышем.
- Пользователь вводит две строки. Необходимо сравнить их между собой, и вывести yes если строки полностью совпадают, или no в противном случае. Регистр учитывать не нужно. Т.е строки «Hello WorlD» и «hello world» считаются двумя одинаковыми строками.
- Напишите программу, которая читает из файла строку, длинной не более 200 символов. И считает количество вхождения в строку всех используемых в ней символов,без учета регистра. На вход поступает строка состоящая из букв латинского алфавита и пробелов. Программа должна вывести в первой строке длину введенной строки. В следующих строках встречаемые символы и их количество. Например, для строки «hello world», вывод будет следующим.
- Капитан Флинт зарыл клад на Острове сокровищ. Есть описание, как найти клад. Описание состоит из строк вида: «North 5», где первое слово – одно из «North», «South», «East», «West», а второе целое число – количество шагов, необходимое пройти в этом направлении. Напишите программу, которая по описанию пути к кладу определяет точные координаты клада, считая, что начало координат находится в начале пути, ось OX направлена на восток, ось OY – на север. На вход подается последовательность строк указанного формата. На выходе программа должна вывести координаты клада – два целых числа через пробел
int main () setlocale(LC_ALL, «Russian»);
int k, j, i=0, tmp=1;
char str[]=»A roza upala na lapu Azora»;
while (str_1[str_1_i] != 0) str_1_i++;
>
while (str_2[str_2_i] != 0) str_2_i++;
>
if (str_1_i == str_2_i) for (i = 0; i < str_1_i; i++) if (str_1[i] != str_2[i]) if (((str_1[i] — str_2[i]) == 32)||((str_2[i]-str_1[i]) == 32)) tmp++;
>
>
if (str_1[i] == str_2[i]) tmp++;
>
>
> else printf(«No\n»);
if (tmp == i) printf(«YES\n»);
> else printf(«No\n»);
return (0);
>
while (str_1[str_1_i] != 0) str_1_i++;
>
while (str_2[str_2_i] != 0) str_2_i++;
>
if (str_1_i == str_2_i) for (i = 0; i < str_1_i; i++) if (str_1[i] != str_2[i]) if (((str_1[i] — str_2[i]) == 32)||((str_2[i]-str_1[i]) == 32)) tmp++;
>
>
if (str_1[i] == str_2[i]) tmp++;
>
>
char str[200], str_bp[200]=»0″, t;
int i = 0, k = 0, p = 0;
while (str[i] != 0) if ((str[i] > 96)&&(str[i] < 123)) str[i]-=32;
>
if (str[i] != 32) str_bp[k] = str[i];
k++;
>
i++;
>
printf(«%d», i);
p = i — k;
for (k = k-1; k > 0; k—) for (i = 0; i < k; i++) if (str_bp[i] > str_bp[i+1]) t = str_bp[i];
str_bp[i] = str_bp[i+1];
str_bp[i+1] = t;
Как стать программистом
Это моя личная ссылка-приглашение на Stepik для вас. Регистрируясь по этой ссылке, записываясь на курсы и решая задачи, Вы помогаете автору данного сайта принять участие в конкурсе платформы Stepik! Подробности конкурса здесь: https://vk.cc/75rKuS
воскресенье, 4 августа 2013 г.
Занятие 14. Строки и символьные массивы в языке Си.
Прочитайте улучшенную версию этого урока «Ввод и вывод символьных строк».
- Ещё более доступное объяснение
- Дополнительные материалы
- 12 задач на программирование с автоматической проверкой решения
| Рис.1. Символьный массив |
| Рис 2. Символьная строка |
Объявление и инициализация строк.
| Рис.3. Символьный массив после объявления |
- Как и любая переменная, строка может быть инициализирована (т.е. ей присвоено некоторое значение) непосредственно при её объявлении.
- Мы можем не задавать при инициализации размер массива.
| Рис. 4. Вывод на экран символьного массива без нулевого элемента в конце |
Ввод и вывод строк.
| Рис.5 Ввод строки с использованием функции scanf(). |
| Рис. 6. Ввод строки с использованием функции gets() |
- Массив символов, в который необходимо записать вводимую строку.
- Количество символов, которые может считать функция с учетом символа конца строки. В нашем случае это 10, т.е. рабочих из них девять, и один зарезервирован для конца строки.
- Откуда читать данные. В нашем случае указан стандартный поток ввода.
| Рис.7. Ввод с помощью функции fgets(). |
| Рис.8. Иллюстрация особенностей ввода функции fgets(). |
| Рис.9. Использование стандартных функций вывода строки puts(), fputs(). Особенности вывода. |
- На вход программе подается строка, длинной не более 100 символов. Напишите программу, которая определяет длину этой строки, без учета нулевого символа.
- Напишите программу, которая переводит данную строку в нижний регистр. Т.е. и строки «Hello WorlD» должна получиться строка «hello world»
- На вход программе подается строка, длинной не более 100 символов. Определить, является ли она перевертышем. Например, как слово «шалаш» или «топот». Учтите что строка может содержать пробелы, их учитывать не нужно. Например, строка «А роза упала на лапу Азора» будет являться перевертышем.
- Пользователь вводит две строки. Необходимо сравнить их между собой, и вывести yes если строки полностью совпадают, или no в противном случае. Регистр учитывать не нужно. Т.е строки «Hello WorlD» и «hello world» считаются двумя одинаковыми строками.
- Напишите программу, которая читает из файла строку, длинной не более 200 символов. И считает количество вхождения в строку всех используемых в ней символов,без учета регистра. На вход поступает строка состоящая из букв латинского алфавита и пробелов. Программа должна вывести в первой строке длину введенной строки. В следующих строках встречаемые символы и их количество. Например, для строки «hello world», вывод будет следующим.
h — 1
l — 3
o — 2
r — 1
w — 1
probel — 1
- Капитан Флинт зарыл клад на Острове сокровищ. Есть описание, как найти клад. Описание состоит из строк вида: «North 5», где первое слово – одно из «North», «South», «East», «West», а второе целое число – количество шагов, необходимое пройти в этом направлении. Напишите программу, которая по описанию пути к кладу определяет точные координаты клада, считая, что начало координат находится в начале пути, ось OX направлена на восток, ось OY – на север. На вход подается последовательность строк указанного формата. На выходе программа должна вывести координаты клада – два целых числа через пробел
Если Вам понравился этот урок, расскажите о нем вашим друзьям. В этом Вам могут помочь кнопки основных социальных сетей, расположенные ниже. Вам остается всего лишь кликнуть по любой из них.
120 комментариев :
Самый непонятный урок для меня 🙁
Особенно с длинной строки.
"Количество символов, которые может считать функция с учетом символа конца строки. В нашем случае это 10, т.е. рабочих из них девять, и один зарезервирован для конца строки."
Почему 9 да еще и минус один под конец строки и того 8? А на выводе все равно получается, что считали и вывели 9 символов. (Листинг 14.8)
Последний символ 100% записывается в конец строки и считается n-ным (последним) элементом массива? Как этот символ считать? т.е. как написать for (i = 0; i == конец строки; i++); (ага пока читал извилина шевельнулась. Не знаю только в правильную ли сторону 🙂 Получается так сделать нельзя т.к. мы сначала i приравниваем к целому числу, а потом хотим проверить не равено ли он символу. Тогда все равно не понятно как сделать такой цикл, что бы он выполнялся до конца строки).
char str[];
Если я введу с клавиатуры 'Hello world' и жмакну enter.
gets(str) — считает Hello world\0
fgets(str,11,stdin) — считает Hello worl\0\n
И длинна массива в обоих случаях будет 12 символов? Так?
Ну и продолжая тему с функциями ввода вывода. Получается:
puts(str) — выведет Hello world\0\n
fputs(str,stdout) — выведет Hello world\0
Я наверное коряво написал. Смотрите 10 можете считать. Из них рабочих 9. А десятый, который не рабочий как раз и зарезервирован под конец строки.
Вы забыли, что тип char совместим с целым типом. каждому символу соответствует число, код этого символа в таблице ASCII. Вот символу конца строки соответствует число нуль. Поэтому конец строки мы можем проверять как str[i] != 0;
Длина массива и длинна строки это разные вещи ведь. Длинна массива может быть и 100 элементов, а вот длина строки, которая хранится в этом массиве может быть и меньше. Например, Литстинг 14.3
Длинна массива str 17 элементов, а длина строки, которую мы туда поместили всего двенадцать. Из них, как мы уже разобрались 11 рабочие и последний, двенадцатый символ конца строки. )
Теперь, с учетом этих пояснений попробуйте ответить на свои последние вопросы или переформулировать их. Если не получится, напишите я или отвечу или дам еще подсказку. )
int main () <
setlocale(LC_ALL, "Russian");
int k, i=0;
char str [100];
//0-99 рабочих (100) + 1 на конец строки.
printf("Введите строку, не больше 100 символов.\n");
fgets(str,100,stdin);
//считаем кол-во символов
while (str != 0) <
i++;
>
printf("Длинна строки = %d\n",i);
/////////////////////////////////
//ASCII — англ. символы в верхнем регистре имеют индекс [65,90], в нижнем [97,122]
//разница между верх. и ниж. ригистрах 32
char str [100];
//0-99 рабочих (100) + 1 на конец строки.
тут всего с 0 по 99, сотого нет. Чтобы уместить 100, нужно объявлять 101. Тогда будет как вы написали. Но это не важно. =))
Сама идея правильная, именно такое решение я и ожидал увидеть.
Но есть ошибки в коде. Например, цикл для длины строки бесконечный. Внимательно посмотрите на условие.=))
Этот комментарий был удален автором.
/*Месье знает толк в извращениях — думаю есть решение проще. И да я не выполнил условие "На вход программе.." т.к. не могу его проверить, т.к. компилятора под рукой нет, компилю онлайн, и нет возможности ввода.
p.s. Почему то при вводе Русских символов не переводит в один регистр. Не пойму в чем дело.. вроде так же должно быть как и с анг. символами. Может просто компилятор не хочет с ними работать?
*/
#include "stdio.h"
#include "locale.h"
int main () <
setlocale(LC_ALL, "Russian");
int k, j, i=0, tmp=1;
char str[]="A roza upala na lapu Azora";
while (str[i] != 0) <
i++;
>
//удаляем пробелы и переводим в один регистр.
for (k = 0; k < i; k++) <
if (str[k] == 32) <
for (j = k; j < i; j++) <
str[j] = str[j+1];
>
i—; /*отнимаем от длинны строки каждый пробел т.к. мы его удалили*/
>
if (((str[k] > 64)&&(str[k] < 91))||((str[k] > 191)&&(str[k] < 223))) <
str[k]+=32;
>
С Русскими символами кажется разобрался. Не ту таблицу посмотрел.
Для преобразованию Русских символов такой код:
if ((str[i] > 127)&&(str[i] < 159)) <
if ((str[i] > 127)&&(str[i] < 144)) <
str[i]+=32;
> else <
str[i]+=80;
>
>
В программу встраивать не стал.
Длину строки и удаление пробелов нужно сделать за один цикл. Думаю туда же можно включить и преобразование регистра. =)) В общем, доведите программу до нормально вида, а то это даже вам, кажется извращением. =))
И не парьтесь с русскими символами. )) Выполняйте задание только для латиницы. Никакого отдельного интереса они не представляют. Принцип тот же. )
Все действительно в один While. Вот только для удаления пробелов потребовался еще один цикл, благо он меньше While на количество уже пройдены шагов, а так проскакивает столько же тиков.
И снова нет! =))
У вас опять вложенные циклы.
Смотрите как должно быть.
1. Запускается программа.
2. Считываем данные в строку.
3. Приводим строку к стандартному виду (узнаем её длину, меняем регистр, удаляем пробелы.)
4. Проверяем строку палиндром она или нет и выводим ответ.
На 3 пункт нужен один цикл простой. Тут будет while скорее всего.
На 4 пункт еще один цикл простой. Тут удобней for.
И они не вложенные друг в друга.
Теперь немного по удалению пробелов. Почему бы вам не завести еще одну строку, в которой будет храниться строка в правильном виде. А не из-за одного пробела добегать перекопировывать целый хвост.Представьте, что у вас строка
"A ro za u p a l a n a l a p u A z o r a"
И так после каждого пробела, будет запускаться внутренний цикл и копироваться все не нужное влево на один символ. Это не экономно. =))
Сравнение строк, в отличии от предыдущей задачи не меняет сами строки 🙂
char str_1[100], str_2[100];
int i=0, tmp = 0, str_1_i = 0, str_2_i = 0;
pritnf("Введите две строки не больше 100 символов каждая. Все символы выше лимита будут обрезаны.\n");
printf("Введите первую строку: \n");
fgets(str_1,100,stdin);
printf("Введите вторую строку: \n");
fgets(str_2,100,stdin);
while (str_1[str_1_i] != 0) <
str_1_i++;
>
while (str_2[str_2_i] != 0) <
str_2_i++;
>
if (str_1_i == str_2_i) <
for (i = 0; i < str_1_i; i++) <
if (str_1[i] != str_2[i]) <
if (((str_1[i] — str_2[i]) == 32)||((str_2[i]-str_1[i]) == 32)) <
tmp++;
>
>
if (str_1[i] == str_2[i]) <
tmp++;
>
>
> else printf("No\n");
if (tmp == i) <
printf("YES\n");
> else printf("No\n");
return (0);
>
Как только вот это увидел
while (str_1[str_1_i] != 0) <
str_1_i++;
>
while (str_2[str_2_i] != 0) <
str_2_i++;
>
if (str_1_i == str_2_i) <
for (i = 0; i < str_1_i; i++) <
if (str_1[i] != str_2[i]) <
if (((str_1[i] — str_2[i]) == 32)||((str_2[i]-str_1[i]) == 32)) <
tmp++;
>
>
if (str_1[i] == str_2[i]) <
tmp++;
>
>
Дальше читать не стал. Слишком сложно и муторно. Задача очень простая, чтобы решать её такими силами. =) Один цикл и два if максимум. =))) А быть может, даже проще можно. Одним if обойтись.Подумайте, что лишнего вы ищете и проверяете. =)) Например, так ли вам нужно знать длины строк? Ну и там еще посмотрите, что можно упростить.
Не компилирую, но это правильно. Замечательно! Именно это я и хотел увидеть. =)))
Попроще, да? Чем предыдущий код? ))
Хотя нет, условие плоховато для цикла.
"A roza upala na lapu Azora" и "a roza upala" вернет YES, но это же явный NO. )))
Так то оно так, но если ввести не только буквы, а ещё и цифры
то введённые : R и 2 в разные строки, напишет yes.
Пятая. С предыдущими разобрался, но выкладывать уже думаю смысла нет, и так все разжевано.
char str[200], str_bp[200]="0", t;
int i = 0, k = 0, p = 0;
while (str[i] != 0) <
if ((str[i] > 96)&&(str[i] < 123)) <
str[i]-=32;
>
if (str[i] != 32) <
str_bp[k] = str[i];
k++;
>
i++;
>
printf("%d", i);
p = i — k;
for (k = k-1; k > 0; k—) <
for (i = 0; i < k; i++) <
if (str_bp[i] > str_bp[i+1]) <
t = str_bp[i];
str_bp[i] = str_bp[i+1];
str_bp[i+1] = t;
Если сами разобрались, то конечно не стоит писать сюда. Хотя я бы почитал, как Вы решили проблему с удаление лишних пробелов. =)
Теперь по пятой программе. Выводит она не то, что требуется. Лишнее есть. Снова мной замечены вложенные циклы. Мне это не нравится. Думаю можно сделать без этого. Кстати, стоит рассказать, чем мне так не нравятся вложенные циклы? )
Подумайте еще или хотя бы исправьте вывод. Уберите все лишнее. )))
Все у меня голова сегодня не варит 🙂
По последней задаче.
Можно ведь считывать введенное с клавиатуры таким образом:
сканф(строка)
и т.к. пробел сработает как разделитель еще раз считать но уже число после пробела тогда все легко.
Но если использовать фгетс и введенное полностью считать как сторку..тут посложнее и вот тут то похоже меня опять в дебри и понесло.
Что я хотел сделать читать строку до пробела и получить ASCII сумму направления.
Дальше читать от пробела до конца строки количество символов и получить разрядность.
Опять читать от пробела до конца строки получать int iй элемент умножать его на разрядность и отнимать от последней один разряд. т.о. получить число. Что то я сомневаюсь в рациональности такого метода 🙂
Не совсем понял, что вы хотите сделать. =))
Я лучше посмотрю Ваш код, когда вы его напишете, и прокомментирую более подробно. Посмотрим, что там можно улучшить и от чего можно избавиться, что оптимально, а что не очень. =)))
Спасибо урок очнь интересный.
Задание 1
#include ((stdio.h))//задание 1 защиту от дураков не делал
int main() <
char str[101];
int i=0;
printf(" Vvedite stroku simvolov, ne bolee 100\n");
gets(str);
do/do
switch (str[i]) <
case '\0':printf("vvedeno %d simvolov \n",i);return(0);
>
i++;>//do'
while(i!=101);
return(0);
>
вроде работает .
задание 2
#include //задание 2 смена регистра вниз
#include
int main() <
char str[101];
int i=0;
printf(" Vvedite stroku simvolov, ne bolee 100\n");
gets(str);
do/do
str[i]= tolower(str[i]);
i++;>//do'
while(str[i]); //проверка окончания строки
puts(str);
return(0);
>
Хаа, какой вы шустрый. Хвалю что знаете такую функцию, но нужно написать программу без использования стандартных функций. Основываясь на закономерностях таблицы символов ASCII. ))
#include ((stdio.h)).//задание 3 строка перевертыш
#include ((cctype))
int main()
<
char str[101];//строка
int i=0,n;// счётчики
printf(" Vvedite stroku simvolov, ne bolee 100\n");
fgets(str,101,stdin);//ввели строку
do/do 1
switch (str[i]) <
case ' '://ловим пробел
<
n=i;
i—;
do
/do 2
str[n]=str[n+1];
n++;
>while(str[n-1]);//do 2' выбросили пробел
>//case ' '
default:str[i]=toupper(str[i]);
>//switch(str[i])
i++;
>while(str[i]);//do1' выбросили все пробелы и поменяли регистр
i-=2;
n=0;
do//do 3' проверка зеркальности
else< n++;i--;>
>while(n
>//switch(str[i])
i++;
>while(str[i]);//do1' выбросили все пробелы и поменяли регистр
//i=длинна строки без пробелов+ноль символ,k=кол-во пробелов
int kolvo[201],a;
kolvo[1]=k ;//кол во пробелов
kolvo[0]=i-1+k;//кол символов стр 30
i=0;
while(str[i]) <
//stemp=str[i];
k=1;
a=i;// стр 35
do <
n=a+1;
if (str[n]==str[i])
<
k++;
do
/do
str[n]=str[n+1];
n++;
>while(str[n-1]);//выбросили символ
>//if
else a++;
>while(str[a-1]);//выбросили все символы
i++;
kolvo[i+1]=k;
>// while(str[i])
printf( "%d\n", kolvo[0]);
i=0;
while(str[i+1])
<
printf(" %c\t%d\n", str[i],kolvo[i+2]);
i++;
>
printf( "probelov %d\n", kolvo[1]);
return(0);
>
Задание 6
#include ((stdio.h))// задание 6
int main()
<
char str[5];
int x=0,y=0,a,i=0;
printf (" Vvedite koordinaty v lyubom porydke.\n");
printf (" obrazec:\n");
printf (" North 5\n East 3\n South 1\n West 7\n");
printf (" Esli est' ne vse koordinaty, vvedite v konce 0\n");
do <
scanf("%s",&str);
switch (str[0]) <
case'N': scanf("%d",&a);y+=a;break;
case'E': scanf("%d",&a);x+=a;break;
case'S': scanf("%d",&a);y-=a;break;
case'W': scanf("%d",&a);x-=a;break;
case'0': i=3;break;
default : i—;printf (" povtorite vvod pravilno.\n "); break;
>
i++;
>while(i<4);
printf("%d %d\n", x,y);
return(0);
>
Неправильно. Путь может состоять и из 100 шагов Например:
North 5
East 3
South 2
North 2
East 12
South 1
West 22
=)))
И при некоторых данных происходит выход за пределы массива кажется.