The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
возврат строки, !*! lemegeton, 24-Июл-05, 09:09  [смотреть все]
Есть функция, которая формирует строку. Как мне ее вернуть???
...
str[512];
...
retturn str;

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

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

    static char str[512];

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

    Можно ещё:

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

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

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

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


    • возврат строки, !*! lemegeton, 17:37 , 24-Июл-05 (3)
      спасибо за советы. Просто я думал сделать так - функция принимает команду выполняет, на выходе выдает строку. Как оказалось дальше что вернуть корректнее будет указатель на строку( как я понял указатель на первый элемент массива). Фича в том что в функции происходит построчное считывание из файла - fgets(), и получается что в строке, что заполняется fgets содержится последняя строка файла. Теперь я бьюсь над конкатенацйей строк, но пока тщетно, решение нашел пройтись по всем элементам массива(строки) и занести их в другой. НО почему то в конечном массиве содержиться только первай строчка файла...А привыводе на экран после печатанья этой строчки сообщение - segmentation fault. Есть соображения у кого - нибудь по этому поводу, подскажите. Я конечно много незнаю, просто 2 ой день на си программирую ;)
      • возврат строки, !*! lemegeton, 22:34 , 24-Июл-05 (4)
        допер сам - надо при вызове fgets() сдвигать указатель на строку на количество позиций раное количеству символов в строке,
        типа:
        while(fgets(&str[pointer],128,f))
        {
        pointer=strlen(str);
        }
        работает! Всем спасибо.
        • возврат строки, !*! chip, 23:43 , 24-Июл-05 (5)
          >допер сам - надо при вызове fgets() сдвигать указатель на строку на
          >количество позиций раное количеству символов в строке,
          >типа:
          >while(fgets(&str[pointer],128,f))
          >{
          >pointer=strlen(str);
          >}
          >работает! Всем спасибо.

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


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

            • возврат строки, !*! chip, 12:14 , 25-Июл-05 (8)
              >может быть. я не претендую на звание лучшего программиста, поэтому и спросил
              >здесь, в форуме. Если есть варианты лучше подскажите, я буду только
              >рад.

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


              #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;
              }

      • возврат строки, !*! dimus, 10:36 , 25-Июл-05 (7)

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

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

        • возврат строки, !*! Vladislav, 12:33 , 25-Июл-05 (9)
          Сишники...)) Как у вас все сложно, как много велосипедов))

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

          • возврат строки, !*! Аноним, 15:16 , 25-Июл-05 (10)
            >Сишники...)) Как у вас все сложно, как много велосипедов))
            >

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

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

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

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

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

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


        • возврат строки, !*! Ghecko, 11:51 , 28-Июл-05 (12)
          >По поводу 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;
          }

          • возврат строки, !*! sas, 12:12 , 28-Июл-05 (13)
            >
            >   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;
            >}
            >


            • возврат строки, !*! dimus, 11:11 , 04-Авг-05 (17)

              >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.


              • возврат строки, !*! dimus, 11:31 , 04-Авг-05 (18)
                Хочу добавить пояснение к своему несогласию.
                Утверждение sas насчет мьютексов верно для многопоточных приложений - желающие могут почитать man pthread_mutex_init - однако данные в некоторых случаях могут меняться не только другими потоками. Если рассмотреть случай, когда данные находятся в разделяемой памяти, или, что еще хуже, в буфере какого-то устройства, становится понятно, что тут просто так не отделаешься.
                МОЕ МНЕНИЕ: лучше подстраховаться, тем более, что накладные затраты на вызов функции с проверкой длины лишь немногим больше, чем на функцию без такой проверки. Как говорится, береженого Бог бережет.
                • возврат строки, !*! sas, 17:15 , 04-Авг-05 (19)
                  >Хочу добавить пояснение к своему несогласию.
                  >Утверждение 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

  • возврат строки, !*! knsi, 14:58 , 01-Авг-05 (16)
    Функция не может вернуть строку ибо такого типа данных нет в с, но можно сделать так,

    struct sString
    {
    char str[512];
    }

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

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




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

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