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

проблема с передачей параметра функции

14.11.2011, 13:12. Показов 3545. Ответов 41
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Изучил уже 6 языков программирования, но С++ не дается как-то так просто.
Вот есть например часть кода.
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
#include <cstring>
#include <stdio.h>
#include <iostream>
#include <Windows.h>
 
int convert (){
char str[] = "Фізика";
char qwe[] = "";
   char c = 'і';
   char *p;
   int result;
   printf( "String :      %s\n", str );
   printf( "Search char:   %c\n", c );
   p = strchr( str, c );
   result = (int)(p - str + 1);
   if ( p != NULL )
      printf( "Result :   first %c found at position %d\n", 
              c, result );
   else
      printf( "Result :   %c not found\n" );
   *strchr( str, c ) = 'i';
   CharToOem(str, qwe);
   printf( "New String :      %s\n", qwe );
   int a;
   std::cin>>a;
    return 0;
}
 
int main() {
    convert();
}
если же сделать:
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
int convert [B](char str[])[/B]{
char qwe[] = "";
   char c = 'і';
   char *p;
   int result;
   printf( "String :      %s\n", str );
   printf( "Search char:   %c\n", c );
   p = strchr( str, c );
   result = (int)(p - str + 1);
   if ( p != NULL )
      printf( "Result :   first %c found at position %d\n", 
              c, result );
   else
      printf( "Result :   %c not found\n" );
   *strchr( str, c ) = 'i';
   CharToOem(str, qwe);
   printf( "New String :      %s\n", qwe );
   int a;
   std::cin>>a;
    return 0;
}
 
int main() {
    [B]convert("Фізика");[/B]
}
то идет ошибка:
Первый этап обработки исключения в "0x0080110a" в "code.exe": 0xC0000005: Нарушение прав доступа при записи "0x008058bd".
Необработанное исключение в "0x0080110a" в "code.exe": 0xC0000005: Нарушение прав доступа при записи "0x008058bd".
Первый этап обработки исключения в "0x0080110a" в "code.exe": 0xC0000005: Нарушение прав доступа при записи "0x008058bd".
Необработанное исключение в "0x0080110a" в "code.exe": 0xC0000005: Нарушение прав доступа при записи "0x008058bd".
2. Может есть какой-то способ заставить консоль воспринимать украинскую букву "і"? А то приходиться заменять ее на английский аналог.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.11.2011, 13:12
Ответы с готовыми решениями:

Проблема, связана с неправильной передачей параметров
Создал на Fortran dll по вычислению некоторой функции: SUBROUTINE ARRAYTEST(x,arr) ...

Вызов функции внутри другой функции с передачей локальной переменной по ссылке
Столкнулся с очень с интересной проблемой. Можно ли так делать? #include &lt;iostream&gt; using...

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

Ошибка с передачей функции потоку
Вообщем, создаю поток - всё нормально, но как только передаю ему какую-либо функцию программа...

41
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 16:39 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от SlesherY Посмотреть сообщение
ясно.спасибо.
да кстати return qwe; из convert() возвращает уже строковую константу. тоесть я должен объявить как char *convert (char str[]) , а потом уже принимать результат char *res;
res = convert(str);
.
qwe - это же чар[1000];
При этом надо понимать, если ты попытаешься вернуть указатель на локальный массив функции convert, то по завершении работы функции convert данный локал будет уже несуществующим и получится, что указатель смотрит на невалидную память
1
6 / 6 / 0
Регистрация: 14.11.2011
Сообщений: 54
14.11.2011, 16:41  [ТС] 22
-=ЮрА=-, спасибо. задание просто этим то не ограничевается. Мне как раз надо было разбить на несколько функций. Ну пока я свою проблему развязал и еще почерпнул много полезного.
Всем спасибо)
0
Заблокирован
Автор FAQ
14.11.2011, 16:52 23
Цитата Сообщение от SlesherY Посмотреть сообщение
задание просто этим то не ограничевается.
- как оно звучит???

Не по теме:

Я потому и слил всё в тело main т.к. городить функцию пользователя на ровном месте для решения именно приведенного в топике задание аналогично 5-му колесу в телеге:)

0
6 / 6 / 0
Регистрация: 14.11.2011
Сообщений: 54
14.11.2011, 17:00  [ТС] 24
-=ЮрА=-, ну вообще я понемногу переделываю клиент для некоторой работы с БД с языка PHP на С++.
да, насколько я понял, если уже есть некое char str[1000] = "TEXT"; , то изменить его можно только при помощи strcpy(str, "another text")?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 17:07 25
Цитата Сообщение от SlesherY Посмотреть сообщение
с языка PHP на С++
Тогда тебе небесами велено использовать std::string вместо работы с указателями на char
1
Заблокирован
Автор FAQ
14.11.2011, 17:27 26
Цитата Сообщение от SlesherY Посмотреть сообщение
strcpy(str, "another text")?
- да можно, только вот "another text" не должен превышать длинны str лучше использовать sprintf(str,"%s","another text"); - на мой взгляд меньше граблей с перекрытием блоков памяти. Ну и если уж используем плюсы то std::string упомянутая Evg, имеет больший функционал чем char * (хотя CharToOem вы к string таким образом не примените
C++
1
2
string str = "БлаБлаБла";
CharToOem(str.c_str(),str.c_str())

думаю всё равно чаровский буферок потребуется, что-то вроди такого
C++
1
2
3
4
char * buf = new char[str.length()];
CharToOem(str.c_str(),buf);
str = buf;
delete [] buf;
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 17:32 27
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
лучше использовать sprintf(str,"%s","another text"); - на мой взгляд меньше граблей с перекрытием блоков памяти
Грабли ровно те же самые - отсутствие контроля за размером буфера. А вот с контролем - это strncpy и snprintf (есть не везде). Но контроль выражается в то, что лишняя часть строки будет молча откидываться, а потому такие простые решения годятся только для программ-самоделок.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
std::string имеет больший функционал чем char *
На самом деле любая частность (коей является класс string) ВСЕГДА имеет меньшие возможности, чем общий случай (коим является char*). std::string просто более удобен в работе, больше ничего особенно полезного или принципиально лучшего в нём нет
1
6 / 6 / 0
Регистрация: 14.11.2011
Сообщений: 54
14.11.2011, 17:32  [ТС] 28
Evg, значит будем использовать.
с буферком идея хорошая. Возможно и получше.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 17:35 29
Цитата Сообщение от SlesherY Посмотреть сообщение
с буферком идея хорошая. Возможно и получше
Нет. В данном случае std::string является оптимальным решением, потому что в perl'е есть понятие строки, которое по простому отображается на плюсовые string'и. А работа с Си'шными буферами и указателями - это больше возможностей, чтобы ошибиться. Особенно если нет опыта работы с ними
0
Заблокирован
Автор FAQ
14.11.2011, 17:39 30
Цитата Сообщение от Evg Посмотреть сообщение
std::string имеет больший функционал чем char *
- Evg, я под этим подразумевал уже наличие методов find erase sub, которые в char * ещё нужно писать, так на форуме string-ом почти не балуюсь, как и бустом, т.к предпочитаю своё "доморощенное магазинскому"А вот за strncpy не очень понял я к этому
C
1
2
3
char srs[] = "bla7bla";
char dst[4];
strncpy(dst,srs,3);
то далее сделав такое str[2] = '\0'; как мне кажется изменим и dst с bla на b, а вот sprintf вроди как работает с блоками отдельно
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 17:59 31
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- Evg, я под этим подразумевал уже наличие методов find erase sub, которые в char * ещё нужно писать
У string'а - методы класса, у char* - стандартные библиотечные функции

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
А вот за strncpy не очень понял я к этому
C
1
2
3
char buf[2];
strcpy (buf, "abcdefg");
sprintf (buf, "%s", "abcdefg");
оба вызова сломаются на исполнении

C
1
2
3
char buf[2];
strncpy (buf, "abcdefg", sizeof (buf));
snprintf (buf, sizeof (buf), "%s", "abcdefg");
оба вызова отработают успешно, молча откинув хвост

Добавлено через 1 минуту
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
а вот sprintf вроди как работает с блоками отдельно
Не понял вообще ничего. sprintf ничего не знает о размере буфера и никак его не контролирует.
1
Заблокирован
Автор FAQ
14.11.2011, 18:19 32
Evg, спасибо я понял наверное в кодах где как мне казалось было перекрытие я сам косячил
Сталкивался с проблеммой связи dst1 и str при этом str[2] = '\0';, но как показал этот код где всё чётко в плане выделения памяти подрезание исходника на производных строках не отображается
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
 
int main() 
{
    char str[] = "blablabla";
    long sLen = strlen(str);
    char *dst1 = (char *)malloc(sizeof(char)*sLen);
    char *dst2 = (char *)malloc(sizeof(char)*sLen);
    strcpy (dst1,str);      
    sprintf(dst2,"%s",str); 
    
    printf("dst1 : %s\n",dst1);
    printf("dst2 : %s\n",dst2);
    str[2] = '\0';
    printf("dst1 : %s\n",dst1);
    printf("dst2 : %s\n",dst2);
    system("pause");
    return 0;
}
0
6 / 6 / 0
Регистрация: 14.11.2011
Сообщений: 54
14.11.2011, 18:25  [ТС] 33
блин string это же намного проще...
зачем было с этим всем мучится, тем более что они взаимноприсваемые, если судить из кода
C++
1
2
3
4
char * buf = new char[str.length()];
CharToOem(str.c_str(),buf);
str = buf;
delete [] buf;
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
14.11.2011, 18:28 34
Цитата Сообщение от SlesherY Посмотреть сообщение
printf( "String : %s\n", str );
printf( "Search char: %c\n", c );
Вы использовали сишный ввод-вывод, вот все и решили, что STL C++ вам не подойдёт.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 18:40 35
-=ЮрА=-, в посте #32 при вызове malloc'а надо к размеру добавлять ещё +1, потому как strlen учитывает только значащие символы, но не учитывает хвостовой ноль

Цитата Сообщение от SlesherY Посмотреть сообщение
блин string это же намного проще...
зачем было с этим всем мучится, тем более что они взаимноприсваемые, если судить из кода
То, что ты привёл этот пример - это вовсе не string. Ну а в какой-то момент тебе всё равно придётся опуститься до указателей, как того требует CharToOem
0
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
14.11.2011, 18:53 36
Цитата Сообщение от Evg Посмотреть сообщение
Ну а в какой-то момент тебе всё равно придётся опуститься до указателей, как того требует CharToOem
Да и вообще, полезно знать, как оно работает. Си ещё никто не отменял.
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 18:59 37
Цитата Сообщение от talis Посмотреть сообщение
Да и вообще, полезно знать, как оно работает
Это верно. Только тренироваться лучше на кошках
0
6 / 6 / 0
Регистрация: 14.11.2011
Сообщений: 54
14.11.2011, 19:12  [ТС] 38
а как сделать взаимный переход из одного типа к другому?
ну, string, char[], char*

Добавлено через 18 секунд
кастованием вроде не получится
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.11.2011, 19:40 39
C++
1
2
3
4
5
char *s;
std::string ss;
 
ss = s; // здесь вовнутрь класса копируются данные из указателя
s = ss.c_str(); // Здесь мы получаем указатель на данные класса, но не копию данных
0
Заблокирован
Автор FAQ
14.11.2011, 20:41 40
Evg, простите но здесь с вами не соглашусь (по крайней мере в пределах до VS 2008)
Цитата Сообщение от Evg Посмотреть сообщение
ss.c_str();
это const char * и запихнуть этот указатель в (char *) никак не выйдет
Вижу два варианта
Нужен char-вский буффер, а из него уже можно впихивать в указатель по примеру этого

Цитата Сообщение от SlesherY Посмотреть сообщение
char * buf = new char[str.length()];
CharToOem(str.c_str(),buf);
str = buf;
delete [] buf;
Либо присваивание делать
C++
1
const char * s = ss.c_str();
Миниатюры
проблема с передачей параметра функции  
1
14.11.2011, 20:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.11.2011, 20:41
Помогаю со студенческими работами здесь

Разработайте перегружены функции, в которые передаются два параметра типов int или float и три параметра типов
Разработайте перегружены функции, в которые передаются два параметра типов int или float и три...

Функции с передачей разного количества параметров
есть код: #include &lt;iostream&gt; using namespace std; void Char(int num, char a1, char a2, ...);...

Использование функции как параметра другой функции
В задании указано, что функция P прибавляет значение функции ff к элементу массива, если он входит...

Передача функции в качестве параметра функции
Дорогие форумчане! Повторяю пример из книжки. До конца не понял его! Помогите разобраться! Тема:...


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

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