The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"возврат строки"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"возврат строки" 
Сообщение от lemegeton Искать по авторуВ закладки(??) on 24-Июл-05, 09:09  (MSK)
Есть функция, которая формирует строку. Как мне ее вернуть???
...
str[512];
...
retturn str;

ругается типа что я возвращаю адрес локальной переменной.
функция объявлена так - char*function();

  Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "возврат строки" 
Сообщение от gyn61 Искать по авторуВ закладки(ok) on 24-Июл-05, 10:43  (MSK)
>Есть функция, которая формирует строку. Как мне ее вернуть???
>...
>str[512];
>...
>retturn str;
>
>ругается типа что я возвращаю адрес локальной переменной.
>функция объявлена так - char*function();

static char str[512];

Только функция не реентерабельна :(

Можно ещё:

char *str = malloc(sizeof(char) * 512);

но тогда вызывающая сторона должна делать free() или будут утечки памяти :(

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "возврат строки" 
Сообщение от chip emailИскать по авторуВ закладки(ok) on 24-Июл-05, 16:07  (MSK)
>Есть функция, которая формирует строку. Как мне ее вернуть???
>...
>str[512];
>...
>retturn str;
>
>ругается типа что я возвращаю адрес локальной переменной.
>функция объявлена так - char*function();

Корректнее в функцию передавать адрес буфера + его[буфера] размер. Примеры,
strncpy или ее более "продвинутый" аналог strlcpy (OpenBSD, FreeBSD)
http://www.freebsd.org/cgi/man.cgi?query=strlcpy&apropos=0&sektion=0&manpath=FreeBSD+5.4-RELEASE+and+Ports&format=html


  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "возврат строки" 
Сообщение от lemegeton Искать по авторуВ закладки(??) on 24-Июл-05, 17:37  (MSK)
спасибо за советы. Просто я думал сделать так - функция принимает команду выполняет, на выходе выдает строку. Как оказалось дальше что вернуть корректнее будет указатель на строку( как я понял указатель на первый элемент массива). Фича в том что в функции происходит построчное считывание из файла - fgets(), и получается что в строке, что заполняется fgets содержится последняя строка файла. Теперь я бьюсь над конкатенацйей строк, но пока тщетно, решение нашел пройтись по всем элементам массива(строки) и занести их в другой. НО почему то в конечном массиве содержиться только первай строчка файла...А привыводе на экран после печатанья этой строчки сообщение - segmentation fault. Есть соображения у кого - нибудь по этому поводу, подскажите. Я конечно много незнаю, просто 2 ой день на си программирую ;)
  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "возврат строки" 
Сообщение от lemegeton Искать по авторуВ закладки(??) on 24-Июл-05, 22:34  (MSK)
допер сам - надо при вызове fgets() сдвигать указатель на строку на количество позиций раное количеству символов в строке,
типа:
while(fgets(&str[pointer],128,f))
{
pointer=strlen(str);
}
работает! Всем спасибо.
  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "возврат строки" 
Сообщение от chip emailИскать по авторуВ закладки(ok) on 24-Июл-05, 23:43  (MSK)
>допер сам - надо при вызове fgets() сдвигать указатель на строку на
>количество позиций раное количеству символов в строке,
>типа:
>while(fgets(&str[pointer],128,f))
>{
>pointer=strlen(str);
>}
>работает! Всем спасибо.

ИМХО, это что-то ужасное :(


  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "возврат строки" 
Сообщение от lemegeton Искать по авторуВ закладки(??) on 25-Июл-05, 10:16  (MSK)
>>допер сам - надо при вызове fgets() сдвигать указатель на строку на
>>количество позиций раное количеству символов в строке,
>>типа:
>>while(fgets(&str[pointer],128,f))
>>{
>>pointer=strlen(str);
>>}
>>работает! Всем спасибо.
>
>ИМХО, это что-то ужасное :(
может быть. я не претендую на звание лучшего программиста, поэтому и спросил здесь, в форуме. Если есть варианты лучше подскажите, я буду только рад.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "возврат строки" 
Сообщение от chip emailИскать по авторуВ закладки(ok) on 25-Июл-05, 12:14  (MSK)
>может быть. я не претендую на звание лучшего программиста, поэтому и спросил
>здесь, в форуме. Если есть варианты лучше подскажите, я буду только
>рад.

Задача до конца не ясна :( Если чтение файла, то я бы сделал так:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

static const char *progname;

void
usage() {
  fprintf(stderr, "Usage: %s filename\n", progname);
  exit(1);
}

void
die() {
  perror(progname);
  exit(1);
}

int
main(int argc, char *argv[])
{
  FILE   *fp;
  struct stat st;
  char   *content;
  int    rval;

  progname = argv[0];
  if (argc < 2) usage();

  memset(&st, 0, sizeof(st));
  rval = stat(argv[1], &st);
  if (-1 == rval) die();

  fp = fopen(argv[1], "r");
  
  content = malloc(st.st_size + 1);
  if (!content) die();

  rval = fread(content, st.st_size, 1, fp);
  if (0 == rval) die();
  content[st.st_size] = '\0';
  fclose(fp);
  fprintf(stdout, "%s", content);
  free(content);

  return 0;
}

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "возврат строки" 
Сообщение от dimus emailИскать по авторуВ закладки(??) on 25-Июл-05, 10:36  (MSK)

>Теперь я бьюсь над конкатенацйей строк, но
>пока тщетно, решение нашел пройтись по всем элементам массива(строки) и занести
>их в другой. НО почему то в конечном массиве содержиться только
>первай строчка файла...А привыводе на экран после печатанья этой строчки сообщение
>- segmentation fault.

По поводу Segmentation fault - это наверняка трабла с указателями.

По поводу слияния строк - а вы уверены, что надо Вам именно это? Если реч идет о многострочных командах, вроде как в Си, то говорить лучше о слиянии команд. А вообще вот как можно слить две строки:

char* str1 = "bla-bla-bla\n";
char* str2 = "mla-mla-mla\n";

char* cat_string( char* s1, char* s2 )
{
   char* str = NULL;
   int len;

   // Вычислим необходимый размер памяти
   len = strlen(s1);
   len = len + strlen(s2) + 1;

   str = malloc(len);
   if( str )
   {
      // Это довольно опасный код. Если есть малейшая возможность,
      // что во время вызова функции длина строки может увеличиться,
      // следует использовать strncpy и strncat.
      strcpy( str, s1 );
      strcat( str, s2 );
   }

   return str;
}

А вообще, почему бы не считать файл одним куском, а не построчно? Тогда все, что надо - это выполнить разделение по разделителям команд. Можно потом загнать указатели на эти команды например в связанный список, или в массив, и потом работать с ним дальше.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "возврат строки" 
Сообщение от Vladislav emailИскать по авторуВ закладки(??) on 25-Июл-05, 12:33  (MSK)
Сишники...)) Как у вас все сложно, как много велосипедов))

std::string doSomething(const std::string & in)
{
  return "...";
}

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "возврат строки" 
Сообщение от Аноним emailИскать по авторуВ закладки on 25-Июл-05, 15:16  (MSK)
>Сишники...)) Как у вас все сложно, как много велосипедов))
>

А как в плюсах локальную переменную вернуть? Там тоже фокусов может быть немало.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "возврат строки" 
Сообщение от dimus emailИскать по авторуВ закладки(??) on 25-Июл-05, 15:46  (MSK)
Локальная переменная имеет время жизни, равное времени жизни функции. После того, как функция прекратит свое существование, эта переменная бесследно исчезает. Пример:

char* my_func( void )
{
   // В стеке будет выделен кусок размером MY_ARRAY_SIZE
   char my_array[MY_ARRAY_SIZE];
   // Возвращаем указатель на этот кусок стека - НЕ ДЕЛАЙТЕ ТАК НИКОГДА
   return my_array;
}
// Вышли из функции - стек разрушен, значения, сохраненные в my_array
// будут затерты при первом же вызове какой-либо другой функции

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

14. "возврат строки" 
Сообщение от lemegeton Искать по авторуВ закладки(??) on 29-Июл-05, 10:43  (MSK)
>Сишники...)) Как у вас все сложно, как много велосипедов))
>
>std::string doSomething(const std::string & in)
>{
>  return "...";
>}
Прошу прощение за ламерский вопрос, но где можно почитать про стандартные классы в с++? Желательно на русском. И еще, если так просто можно все решить на с++, зачем применяют С?

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

15. "возврат строки" 
Сообщение от chip emailИскать по авторуВ закладки(ok) on 29-Июл-05, 23:16  (MSK)
>>Сишники...)) Как у вас все сложно, как много велосипедов))
>>
>>std::string doSomething(const std::string & in)
>>{
>>  return "...";
>>}
>Прошу прощение за ламерский вопрос, но где можно почитать про стандартные классы
>в с++? Желательно на русском. И еще, если так просто можно
>все решить на с++, зачем применяют С?

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


  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

12. "возврат строки" 
Сообщение от Ghecko Искать по авторуВ закладки(ok) on 28-Июл-05, 11:51  (MSK)
>По поводу Segmentation fault - это наверняка трабла с указателями.
>
>По поводу слияния строк - а вы уверены, что надо Вам именно
>это? Если реч идет о многострочных командах, вроде как в Си,
>то говорить лучше о слиянии команд. А вообще вот как можно
>слить две строки:
>
>char* str1 = "bla-bla-bla\n";
>char* str2 = "mla-mla-mla\n";
>
>char* cat_string( char* s1, char* s2 )
>{
>   char* str = NULL;
>   int len;
>
>   // Вычислим необходимый размер памяти
>   len = strlen(s1);
>   len = len + strlen(s2) + 1;
>
>   str = malloc(len);
>   if( str )
>   {
>      // Это довольно опасный код. Если
>есть малейшая возможность,
>      // что во время вызова функции
>длина строки может увеличиться,
>      // следует использовать strncpy и strncat.
>
>      strcpy( str, s1 );
>      strcat( str, s2 );
>   }
>
>   return str;
>}
>
>А вообще, почему бы не считать файл одним куском, а не построчно?
>Тогда все, что надо - это выполнить разделение по разделителям команд.
>Можно потом загнать указатели на эти команды например в связанный список,
>или в массив, и потом работать с ним дальше.
Я бы маленькие поправки внес:
char* str1 = "bla-bla-bla\n";
char* str2 = "mla-mla-mla\n";

char* cat_string( char* s1, char* s2 )
{
   char* str = NULL;
   int len;

   // Вычислим необходимый размер памяти
   len = strlen(s1) + strlen(s2) + 1; /* Смысла писать в 2 строки не вижу */

   if(str = malloc(len) != NULL) /* так мне кажется более красиво просто */
   {
      // Это довольно опасный код. Если есть малейшая возможность,
      // что во время вызова функции длина строки может увеличиться,
      // следует использовать strncpy и strncat.
      strcpy( str, s1 );
      strcat( str, s2 );
   }

   return str;
}

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

13. "возврат строки" 
Сообщение от sas emailИскать по авторуВ закладки(ok) on 28-Июл-05, 12:12  (MSK)
>
>   if(str = malloc(len) != NULL) /* так мне кажется

Error:  should be if ( (str=malloc(len)) != NULL )

or

just

if ( (str=malloc(len)) ) {...

>более красиво просто */
>   {
>      // Это довольно опасный код. Если
>есть малейшая возможность,
>      // что во время вызова функции
>длина строки может увеличиться,
>      // следует использовать strncpy и strncat.
>

I know this is not your comment, but I cannot be silent :)

Absolutely wrong comment. In the single threaded environment data cannot be changed and strcpy will work fine. In multithreaded environment one should use mutex for example to avoid dirty reads and overwrites.


strncpy & company should be used if you have some buffer of the fixed lenghth and do not want to overwrite it:

char buf[ BUFSZ ];

strncpy( buf, str, BUFSZ-1 );
buf[ BUFSZ -1 ] = '\0';


>      strcpy( str, s1 );
>      strcat( str, s2 );
>   }
>
>   return str;
>}
>


  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

17. "возврат строки" 
Сообщение от dimus Искать по авторуВ закладки(??) on 04-Авг-05, 11:11  (MSK)

>Absolutely wrong comment.
Да нет, не wrong

>In the single threaded environment data cannot be changed
>and strcpy will work fine.
Согласен

>In multithreaded environment one should use
>mutex for example to avoid dirty reads and overwrites.
Не совсем согласен с вашим утверждением. Приведите пример исходного кода, плиз.

>strncpy & company should be used if you have some buffer of
>the fixed lenghth and do not want to overwrite it:
МОЕ МНЕНИЕ - лучше всегда использовать подобные функции, и вообще забыть о существовании strcpy.


  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

18. "возврат строки" 
Сообщение от dimus Искать по авторуВ закладки(??) on 04-Авг-05, 11:31  (MSK)
Хочу добавить пояснение к своему несогласию.
Утверждение sas насчет мьютексов верно для многопоточных приложений - желающие могут почитать man pthread_mutex_init - однако данные в некоторых случаях могут меняться не только другими потоками. Если рассмотреть случай, когда данные находятся в разделяемой памяти, или, что еще хуже, в буфере какого-то устройства, становится понятно, что тут просто так не отделаешься.
МОЕ МНЕНИЕ: лучше подстраховаться, тем более, что накладные затраты на вызов функции с проверкой длины лишь немногим больше, чем на функцию без такой проверки. Как говорится, береженого Бог бережет.
  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

19. "возврат строки" 
Сообщение от sas emailИскать по авторуВ закладки(ok) on 04-Авг-05, 17:15  (MSK)
>Хочу добавить пояснение к своему несогласию.
>Утверждение sas насчет мьютексов верно для многопоточных приложений - желающие могут почитать
>man pthread_mutex_init - однако данные в некоторых случаях могут меняться не
>только другими потоками. Если рассмотреть случай, когда данные находятся в разделяемой
>памяти, или, что еще хуже, в буфере какого-то устройства, становится понятно,
>что тут просто так не отделаешься.
>МОЕ МНЕНИЕ: лучше подстраховаться, тем более, что накладные затраты на вызов функции
>с проверкой длины лишь немногим больше, чем на функцию без такой
>проверки. Как говорится, береженого Бог бережет.

Sorry for english, but this laptop does not have russian characters on the keyboard and i do not      remember layout.

1. If there is a resource which can be changed from different threads or processes or ... you need to use some kind of synchronization (mutexes, semaphores etc).

2. Since you allocated exact memory for particular operation it is possible and better/faster to use strcpy/memcpy etc. Moreover your comment stated that if data could be changed on the fly then strncpy ("n" family for the future) will save you. This is wrong from conceptual point of view.

3. I already mentioned when it is neccessary to use "n" family functions in my previous post.

<qoute>
char buf[ BUFSZ ];

strncpy( buf, str, BUFSZ-1 );
buf[ BUFSZ -1 ] = '\0';
</quote>

Only when you have buffer which should be protected from overwriting and overreading (in case of strncpy remember of the '\0')

Thanks and good luck
--- sas

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

16. "возврат строки" 
Сообщение от knsi Искать по авторуВ закладки(??) on 01-Авг-05, 14:58  (MSK)
Функция не может вернуть строку ибо такого типа данных нет в с, но можно сделать так,

struct sString
{
char str[512];
}

//Пример функции
sString func1()
{
...
sString temp;
...
return temp;
}

//пример использования
void func2()
{
printf(((char *)&func1());
}
еще можно с переопределениями операторов, как это сделано в CString, но будет только в c++ работать

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх


Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ]
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру