Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 74

Задача из Дейтела char и string

23.01.2020, 15:26. Показов 1971. Ответов 16

Студворк — интернет-сервис помощи студентам
Подскажите пожалуйста, начал делать задачу из Дейтела:
«Предположите, что определена структура, содержащая закрытые элементы
данных:
char lastName[ 15 ];
и открытые элемент-функции:
// функции доступа к фамилии (lastName)
void setLastName( string );
и т.д.»
так вот компилятор ругается, да и у меня возник вопрос если переменные char,
а в функциях им будут присваиваться string значения, типа так
setLastName( string lname)
{
lastName = lname;
}
или я что-то не понимаю??
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.01.2020, 15:26
Ответы с готовыми решениями:

Задача на catch из Дейтела
Попробовал решить такую задачу: Напишите условное выражение, которое возвращает или тип double, или int. Напишите catch-обработчики для...

Задача из учебника Дейтела Харви
Задача: используйте одномерный массив для решения слудующей задачи. прочитайте 20 чисел, каждое из которых находится в диапазоне от 10 до...

есть массив char. есть строка string. как присвоить значению string-a значение char-a?
есть массив char. есть строка string. как присвоить значению string-a значение char-a?

16
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
23.01.2020, 15:31
Лучший ответ Сообщение было отмечено mlippi80 как решение

Решение

C++
1
2
strncpy(lastName, lname.c_str(), 15);
lastName[14] = 0;
1
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 74
23.01.2020, 15:53  [ТС]
Я не столько ищу решение, сколько хочу убедиться в корректности задания, например c_str мы ещё не проходили, а касательно вашего кода зачем 14 элементу присваивать 0?
0
Одессит
 Аватар для kylroma
243 / 88 / 44
Регистрация: 30.12.2013
Сообщений: 316
Записей в блоге: 2
23.01.2020, 16:03
Я подозреваю что тут void setLastName( string ); под словом string емеется ввиду имя переменной. А её тип char *.
C++
1
2
3
4
5
void setLastName(const char* string )
{
   strncpy(lastName, string, 14);
   lastName[14] = 0;
}
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
23.01.2020, 16:07
Цитата Сообщение от mlippi80 Посмотреть сообщение
а касательно вашего кода зачем 14 элементу присваивать 0?
потому что если lname "длиннее" lastName, то терминальный ноль не запишется
1
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 74
24.01.2020, 09:49  [ТС]
Нет string это тип именно а не имя переменной. Вообще корректное ли задание?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.01.2020, 16:22
Цитата Сообщение от mlippi80 Посмотреть сообщение
Вообще корректное ли задание?
Так вы задание-то целиком сюда скиньте, не у всех есть книга, чтобы посмотреть.
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
24.01.2020, 16:32
Цитата Сообщение от mlippi80 Посмотреть сообщение
Вообще корректное ли задание?
Если вам известна операция индексации для массивов и std::string, то почему бы и нет (можно ручками посимвольно скопировать)
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.01.2020, 13:26
C++
1
lastName[14] = 0;
Как я помню лишнее strncpy вроде должно само добавлять '\0' главное что бы размер был больше на 1
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
25.01.2020, 13:55
char *strncpy( char *dest, const char *src, std::size_t count );
If count is reached before the entire string src was copied, the resulting character array is not null-terminated.
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.01.2020, 15:19
Тут не видно полного контекста, вполне возможно что 0 был записан до этого.
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
25.01.2020, 15:24
Цитата Сообщение от Avazart Посмотреть сообщение
вполне возможно что 0 был записан до этого.
If, after copying the terminating null character from src, count is not reached, additional null characters are written to dest until the total of count characters have been written.
Но мы это не проверяем, а просто пишем ноль в конец
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.01.2020, 15:30
Я к тому что буфер изначально мог быть инициализирован нулями. Тогда дописывать нет смысла.
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
25.01.2020, 15:34
Цитата Сообщение от Avazart Посмотреть сообщение
Тогда дописывать нет смысла.
А если strlen(src) >= count - 1? (count - размер буфера)
Хотя если инициализировать буфер нулями и копировать sizeof(bufer) - 1, то да - это лишнее
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.01.2020, 15:43
Я думаю что вообще в использовании strncpy в данном случае мало смысла. Можно использовать strcpy но до этого проверять "руками" "впихуемость" и если нет кидать исключение.
Согласитесь плохо будет если к примеру в базе данных будет половина фамилии.
0
0 / 0 / 0
Регистрация: 31.05.2017
Сообщений: 74
30.01.2020, 18:41  [ТС]
в общем не сообразил я сразу, похожее решение было в книге, действительно через strncpy. на всякий случай оставлю задачу и свое решение.
Напишите ряд операторов для выполнения каждой из приведенных ниже
операций. Предположите, что определена структура, содержащая закрытые элементы
данных:
char lastName[ 15 ];
char £irstName[ 15 ];
char age[ 4 ];
и открытые элемент-функции:
// функции доступа к фамилии (lastName)
void setLastName( string );
string getLastName() const;
// функции доступа к имени (firstName)
void setFirstName( string );
string getFirstName() const;
// функции доступа к возрасту (age)
void setAge( string );
string getAge() const;
Также предположите, что открыты все требуемые файлы произвольного доступа.
a) Инициализируйте файл nameage.dat со 100 записями, содержащими
lastName = "unassigned", firstName = "" и age= ".
b) Введите 10 фамилий, имен и соответствующие возрасты, запишите эти данные
в файл.
c) Обновите записи, которые имеют указанные сведения, а если таких сведений
нет, то сообщите пользователю «Нет сведений».
d) Удалите запись, которая содержит информацию, путем ее повторной
инициализации.
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <iostream>
using std::cerr;
using std::endl;
using std::ios;
using std::cout;
using std::cin;
#include <fstream>
using std::fstream;
using std::ostream;
#include <cstdlib> 
using std::exit; // exit function prototype
#include <string>
using std::string;
#include <cstring>
using std::strncpy;
using std::fixed;
using std::ios;
using std::left;
#include <iomanip>
using std::setw;
 
class MyClass 
{
public:
    MyClass( string = "unassigned",  string = "", string = "0" );
    void setLastName( string ); 
    string getLastName() const ;
    void setFirstName( string ); 
    string getFirstName() const; 
    void setAge( string ); 
    string getAge() const; 
private:
   char lastName[ 15 ];
   char firstName[ 10 ];
   char age[ 4 ];
};
 
MyClass::MyClass( string lName, string fName, string ag )
{
   setLastName( lName );
   setFirstName( fName );
   setAge( ag );
} 
void outputLine( ostream&, const MyClass &, int ); 
string MyClass::getLastName() const
{
   return lastName;
} 
void MyClass::setLastName( string lastNameString )
{
   const char *lastNameValue = lastNameString.data();
   int length = lastNameString.size();
   length = ( length < 15 ? length : 14 );
   strncpy( lastName, lastNameValue, length );
   lastName[ length ] = '\0'; 
}
string MyClass::getFirstName() const
{
   return firstName;
} 
void MyClass::setFirstName( string firstNameString )
{
   const char *firstNameValue = firstNameString.data();
   int length = firstNameString.size();
   length = ( length < 15 ? length : 14 );
   strncpy( firstName, firstNameValue, length );
   firstName[ length ] = '\0'; 
} 
string MyClass::getAge() const
{
   return age;
} 
void MyClass::setAge( string AgeString )
{
   const char *ageValue = AgeString.data();
   int length = AgeString.size();
   length = ( length < 5 ? length : 3 );
   strncpy( age, ageValue, length );
   age[ length ] = '\0'; 
} 
 
int main()
{
   fstream outDate( "nameage.dat", ios::out | ios::binary |ios::in );
   if ( !outDate ) 
    {
        cerr << "File could not be opened." << endl;
        exit( 1 );
    } 
    MyClass MyClassObject; 
    for ( int i = 0; i < 20; i++ )/////// записать в файл 20 строк
        outDate.write( reinterpret_cast< const char * >( &MyClassObject ),   sizeof( MyClass ) );
    outDate.seekg( 0 ); 
    for ( int i = 1; i < 3; i++ )//////// записать в файл с начала 5 строк с вручную введенными данными
    {
        cout << "enter LastName, FirstName, Age " << endl;
        string a, b, c;
        cin >> a >> b >> c;
        MyClass MyClassObject (a, b, c);
        outDate.write( reinterpret_cast< const char * >( &MyClassObject ),   sizeof( MyClass ) );   
    }
        outDate.seekg( 0 ); 
        outDate.read( reinterpret_cast< char * >( &MyClassObject ),   sizeof( MyClass ) );  
    for ( int i = 0; i < 20; i++ )  /////// вывести данные из файла
    {
        outputLine( cout, MyClassObject, i + 1);
        outDate.read( reinterpret_cast< char * >( &MyClassObject ),   sizeof( MyClass ) );  
    }
    cout << endl << "for replace" << endl << "enter LastName, FirstName, Age " << endl; //// запрашиваем данные для замены
    string a, b, c;
    cin >> a >> b >> c;
    MyClass MyClassObjectReplace (a, b, c);;    
    outDate.clear(); 
    outDate.seekg( 0 );      
    int mark = 0;
    for ( int i = 0; i < 20; i++ )  ///////// поиск совпадений по файлу
    {
        outDate.read( reinterpret_cast< char * >( &MyClassObject ),   sizeof( MyClass ) );  
        if (a == MyClassObject.getLastName()) ///// если совпадение фамилии, замена введенными данными
        {
            outDate.seekg( -sizeof( MyClass ),  ios::cur ); 
            outDate.write( reinterpret_cast< const char * >( &MyClassObjectReplace ),   sizeof( MyClass ) );
            mark = 1;
        }
    }   
    if (mark == 0) ///// если совпадение не встретилось
        cout << endl << "no such entries" << endl;
    else
    {
        outDate.clear(); 
        outDate.seekg( 0 );      
        cout << endl << "after replace" << endl ; ///// если совпадение фамилии, замена введенными данными
        for ( int i = 0; i < 20; i++ )  
        {
            outDate.read( reinterpret_cast< char * >( &MyClassObject ),   sizeof( MyClass ) );  
            outputLine( cout, MyClassObject, i + 1 );
        }
    }
 
    cout << endl << "for delete" << endl << "enter LastName" << endl; //// запрашиваем фамилию для удаления записи
    string d;
    cin >> d;
    MyClass MyClassObjectDelete; 
    outDate.clear(); 
    outDate.seekg( 0 );      
    mark = 0;
    for ( int i = 0; i < 20; i++ )  ///////// поиск совпадений по файлу
    {
        outDate.read( reinterpret_cast< char * >( &MyClassObject ),   sizeof( MyClass ) );  
        if (d == MyClassObject.getLastName()) ///// если совпадение фамилии, стираем данные
        {
            outDate.seekg( -sizeof( MyClass ),  ios::cur ); 
            outDate.write( reinterpret_cast< const char * >( &MyClassObjectDelete),   sizeof( MyClass ) );
            mark = 1;
        }
    }   
    if (mark == 0) ///// если совпадение не встретилось
        cout << endl << "no such entries" << endl;
    else
    {
        outDate.clear(); 
        outDate.seekg( 0 );      
        cout << endl << "after delete" << endl ; ///// если совпадение фамилии, замена введенными данными
        for ( int i = 0; i < 20; i++ )  
        {
            outDate.read( reinterpret_cast< char * >( &MyClassObject ),   sizeof( MyClass ) );  
            outputLine( cout, MyClassObject, i + 1 );
        }
    }
   return 0;
} 
 
void outputLine( ostream &output, const MyClass &record, int i )
{
   output << left 
      << setw( 5 ) << i 
      << setw( 16 ) << record.getLastName()
      << setw( 16 ) << record.getFirstName()
      << setw( 5 ) << record.getAge()
      << endl;
}
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.01.2020, 19:23
Цитата Сообщение от mlippi80 Посмотреть сообщение
C++
1
2
3
4
5
const char *firstNameValue = firstNameString.data();
 int length = firstNameString.size();
 length = ( length < 15 ? length : 14 );
 strncpy( firstName, firstNameValue, length );
 firstName[ length ] = '\0';
Слишком дофига переменных и строк кода.

И как я говорил Выше допускать обрезание фамилии это тупо.
Как в принципе и хранение данных в char с возвращением наружу std::string

Если кратко: очередной студенческий гавнокод.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.01.2020, 19:23
Помогаю со студенческими работами здесь

Передача в функцию char*([Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings])
Почему компилятор на это матерится? ObjA.Show(&quot;A&quot;); deprecated conversion from string constant to 'char*' #include &lt;iostream&gt;...

Как из объекта String получить char* (НЕ const char*)
Доброго времени! Стандартная процедура работы с SD-card принимает параметр типа char *. Однако, объект String имеет метод(c_str)который...

Строка: чем отличается строки string, char, char*?
Помогите разобраться,совсем плохо идёт,чем отличается строки string,char,char* И если можно пару примеров Буду весьма признательна

Подскажите, пожалуйста, как преобразовать данные из excel в string или в char*, char perm [] в visual c++
Подскажите, пожалуйста, как преобразовать данные из excel в string или в char*, char perm также для вывода на экран среда visual c++ ...

Преобразование между типами System::String, char*, wchar_t*, std::string и др.
При написании кода, взаимодействующего как с .NET и управляемым кодом, так и с неуправляемым кодом (такими как стандартные библиотеки C и...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru