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

Строки (strings) в C++

26.10.2014, 23:36. Показов 1019. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, уважаемые программисты!

Прошу помочь нубу-новичку разобраться с некоторыми нюансами программирования на C++. Сишку учу с нуля по книжкам(прямо рэп какой-то!). В данный момент изучаю строки(strings). Насколько я понял, строка в C++ представляет собой массив из ячеек, хранящих значения типа char, то есть, строка есть ни что иное, как массив символов. Для объявления строки используем следующий синтаксис:
C++
1
char StringName[n] = "SomeChars";
Например:
C++
1
char String[7] = "Hello!";
В данном случае String - название строки, Hello! - содержимое строки, а цифра в скобках [7] - количество символов строки(ячеек массива) с учётом завершающего нулевого символа. Если строку объявить так:
C++
1
char String[6] = "Hello!";
, то компилятор (g++ под Linux) говорит, что "initializer-string for array of chars is too long", то есть, в объявленном массиве не хватает одной ячейки для записи последнего(нулевого) символа. Однако, если выполнить следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string.h>
 
using namespace std;
 
int main()
{
  char String1[7] = "Hello!";
  cout << "String1[0] is: " << String1[0] << "\n";
  cout << "String1[1] is: " << String1[1] << "\n";
  cout << "String1[2] is: " << String1[2] << "\n";
  cout << "String1[3] is: " << String1[3] << "\n";
  cout << "String1[4] is: " << String1[4] << "\n";
  cout << "String1[5] is: " << String1[5] << "\n";
  cout << "String1[6] is: " << String1[6] << "\n\n";
  char String2[2];
  strncpy(String2, String1, 7);
  cout << "String2[0] is: " << String2[0] << "\n";
  cout << "String2[1] is: " << String2[1] << "\n";
  cout << "String2[2] is: " << String2[2] << "\n";
  cout << "String2[3] is: " << String2[3] << "\n";
  cout << "String2[4] is: " << String2[4] << "\n";
  cout << "String2[5] is: " << String2[5] << "\n";
  cout << "String2[6] is: " << String2[6] << "\n\n";
  return 0;
}
, то программа компилируется без всяких предупреждений об ошибках, несмотря на то, что в строке кода 17 значение строки, содержащей 7 символов(String1) копируется в строку, объявленную в строке кода 16 как строка, содержащая лишь 2 символа(String2). Результат выполнения программы следующий:

String1[0] is: H
String1[1] is: e
String1[2] is: l
String1[3] is: l
String1[4] is: o
String1[5] is: !
String1[6] is:

String2[0] is: H
String2[1] is: e
String2[2] is: l
String2[3] is: l
String2[4] is: o
String2[5] is: !
String2[6] is:

Вопрос:
правильно ли я понял, что несмотря на успешную компиляцию и корректную на первый взгляд работу программы, в массив String2 в строке кода 17 записалось лишь два первых символа(H, e) массива String1, а остальные символы(l, l, o, !, /0) записались за пределами массива String1, что является грубейшей ошибкой, а для правильной работы программы необходимо изменить строку кода 16 следующим образом:
C++
1
char String2[7];
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.10.2014, 23:36
Ответы с готовыми решениями:

Строки, Strings
Подскажите пожалуйста как решить задачу: Ввести в Edit1 слова и вывести в Memo1 слова которые...

Строки «Strings»
Переход к решению той или иной задачи выполнить в виде текстового меню. Код сопроводить...

Получить содержимое строки по содержанию переменной, но не из файла strings.xml
&quot;a&quot; это кнопка, и я задаю название кнопки. Название кнопки записано в файле strings_new.xml в...

Strings
Помогите выполнить задание: Read the http://www.javaspe******ts.eu/archive/Issue114.html...

5
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
26.10.2014, 23:51 2
Цитата Сообщение от Alexey104 Посмотреть сообщение
Вопрос:
правильно ли я понял, что несмотря на успешную компиляцию и корректную на первый взгляд работу программы, в массив String2 в строке кода 17 записалось лишь два первых символа(H, e) массива String1, а остальные символы(l, l, o, !, /0) записались за пределами массива String1, что является грубейшей ошибкой, а для правильной работы программы необходимо изменить строку кода 16 следующим образом:
Правильно.

Добавлено через 1 минуту
Цитата Сообщение от Alexey104 Посмотреть сообщение
Насколько я понял, строка в C++ представляет собой массив из ячеек, хранящих значения типа char, то есть, строка есть ни что иное, как массив символов
Это Си-строки: массив char с '\0' в конце. В С++ есть класс string - это совсем другое: http://www.cplusplus.com/reference/string/string/
1
И целого heap'а мало
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
27.10.2014, 00:16 3
Alexey104, тебе пока не нужны сишные строки.
Используй std::string и будет счастье.
Конечно, в плане просветления о том как пробежаться по массиву массивов массивов на них натренируешься;
но сколько копий сломаешь о heap corruption.
Например, выделишь память в куче, малось запишешь не свой кусок. Итого программа падает не сразу, а через некоторое время. Часы медитаций в дебаге и над valgrind. Недосып и, в итоге, переход на std::string.
А ещё лучше сразу перейди на питон, и желательно третий. Ну вот вряд ли тебе плюсы в жизни пригодятся.

Не по теме:

это такое моё нытьё

1
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
27.10.2014, 04:26  [ТС] 4
Во-первых, всем спасибо за участие в моей теме!
Цитата Сообщение от Andrej Посмотреть сообщение
тебе пока не нужны сишные строки.
Используй std::string и будет счастье.
Я просто прохожу главу за главой по книжке и, как ты правильно сказал, чисто "для просветления" пишу всякие бесполезные коды, не имеющие практического применения, просто чтобы въехать, как это всё работает. В данный момент изучаю тему "массивы символов". Насколько практично использовать сишные строки, меня пока мало волнует, главное - въехать в тему на уровне молекул, а потом уже выбирать, что практичнее.
Что касается питона, то я совсем не против(и даже за) его изучить(или ещё чего), но я уже начал в плюсах, достаточно много красноглазил, переварил кучу информации, насиловал свой мозг классами, ссылками, указателями, массивами, функциями, операторами, кучами и стеками, - не зря же я это всё делал! Когда изучу плюсы, с радостью изучу что-нибудь ещё, если, конечно, мозгов хватит.

А по теме хотел бы задать ещё один вопрос:
Правильно ли я понял, что функция strncpy не копирует из исходной строки символ '\0', а сама добавляет его после копирования? То есть в строке 17 кода, указанного выше, говорится не "скопировать из строки String1 в строку String2 символы 'H', 'e', 'l', 'l', 'o', '!', '/0'", а "скопировать из строки String1 в строку String2 символы 'H', 'e', 'l', 'l', 'o', '!' и добавить в конце символ '\0'"? Если это верно, значит в строке 16 кода можно изменить 3-й аргумент функции на 6 вместо 7, и это будет корректно? Я имею-в-виду сделать так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string.h>
 
using namespace std;
 
int main()
{
  char String1[7] = "Hello!";
  cout << "String1[0] is: " << String1[0] << "\n";
  cout << "String1[1] is: " << String1[1] << "\n";
  cout << "String1[2] is: " << String1[2] << "\n";
  cout << "String1[3] is: " << String1[3] << "\n";
  cout << "String1[4] is: " << String1[4] << "\n";
  cout << "String1[5] is: " << String1[5] << "\n";
  cout << "String1[6] is: " << String1[6] << "\n\n";
  char String2[7];
  strncpy(String2, String1, 6);
  cout << "String2[0] is: " << String2[0] << "\n";
  cout << "String2[1] is: " << String2[1] << "\n";
  cout << "String2[2] is: " << String2[2] << "\n";
  cout << "String2[3] is: " << String2[3] << "\n";
  cout << "String2[4] is: " << String2[4] << "\n";
  cout << "String2[5] is: " << String2[5] << "\n";
  cout << "String2[6] is: " << String2[6] << "\n\n";
  return 0;
}
В строке кода 17 копируем из строки String1 в строку String2 6 символов 'H', 'e', 'l', 'l', 'o', '!', а 7-й символ('\0') функция strncpy добавит сама, правильно?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
27.10.2014, 04:49 5
Цитата Сообщение от Alexey104 Посмотреть сообщение
В строке кода 17 копируем из строки String1 в строку String2 6 символов 'H', 'e', 'l', 'l', 'o', '!', а 7-й символ('\0') функция strncpy добавит сама, правильно?
http://www.cplusplus.com/refer... g/strncpy/
Отладчиком умеете пользоваться? Читаете, пробуете, смотрите: когда и что добавляется.
0
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
27.10.2014, 18:03  [ТС] 6
alsav22,
с отладчиком я пока, как обезьяна с гранатой, а вот за ссылки спасибо - всё чётко по теме расписано. Сейчас разбираюсь с GDB, а по данной теме вопросов больше не имею.

Благодарю за участие!
0
27.10.2014, 18:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.10.2014, 18:03
Помогаю со студенческими работами здесь

For и Strings
Нужна помощь в lisbox , с itemheight всё в норме void __fastcall TForm1::Jnrj1Click(TObject...

Strings
По воле случая я со строками не дружу, и с ними вообще не сталкиваюсь. Меня попросили выполнить...

Huge strings
Помогите пожалуйста, у меня делфи rad studio 10 2, хочу в строку string записать больше 255...

BST of strings
Задание реализовать для binary search tree string-ов функции add, find, print. struct tree{...

How to do this? Array of strings
1.George Washington (1789-1797) 2.John Adams (1797-1801) 3.Thomas Jefferson (1801-1809) 4.James...

Соединение Strings
Как обьеденить 2 строки char* в одну чтобы в последущем использовать в system(string) что то типа...


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

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