Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Перенос кода из C++ в C (СИ)

#cpp #c #строки


Пытаюсь переписать этот код, написанный на C++ в C (СИ)
Код делает следующее: читает str2 если находит * читает str1 от позиции * до ближайшей
< потом прибавляет ,

Результат: Test_Value,564,Test_Value2,456,Test_Value3,123,

int main()
{

    std::string make_string{};
    std::string final_string{};
    std::string str1(" Test_Value 564  Test_Value2
456  Test_Value3 123 "); 
    std::string str2(" * *  * *
 * * ");
    size_t i = 0;
    i = str2.find("*", i);
    int position = i;
    auto count = 0;
    while (true)
    {
        while (str1[position] != '<') //читаем от позиции * до позицици <
        {
            make_string += str1[position]; // сохранить в переменную
            position++; // увеличить позицию на 1
        } // повторить цикл

        i = str2.find('*', i + 1); // найти позицию следующей звезды
        if (i > str1.length()) // если звездочек больше нет, выйти из цикла
            break;

        final_string += make_string + ','; //записать в основную строку и поставить
запятую
        make_string.clear(); // очистить временную строку

        count += 2;
        position = i + (final_string.length() - count); // вычисляем позицию для
следующей итерации так: позиция следующей звездочки известна (20) прибавим длину записанных
символов и вычтем * и ,

    }
    final_string += make_string;

    cout << final_string << endl;
    return 0;
} 


Переделал вот так для СИ. 

#include 
#include 

int main(void)
{
        char *make_string = NULL;
        char *final_string = NULL;

        char *str1[] = " Test_Value 564  Test_Value2
456  Test_Value3 123 ";
        char *str2[] = " * *  * *
 * * ";
        size_t i = 0;
        char *ptr = strchr(str2, '*');
        i = ptr - str2; // нашли позицию *
        int position = i; 
        int count = 0;
        for (ptr = str2; *ptr != '\0'; ptr++) { // читаем строку посимвольно передвигаем
указатель
            if (*ptr == '*') { // нашли звезду -> установили указатель на позицию *

                --->
            }
            memset(&make_string, '\0', sizeof(char*)); //make_string = "";              
        }
        strcat(final_string, make_string);  //final_string += make_string;
        printf("%s\n",final_string);
        return 0;
}


Вопросы: ---> здесь нужно читать от позиции * до < в str1.

Как переместить указатель на туже позицию где он стоит в str2?
    


Ответы

Ответ 1



#include #include int main(void) { char *make_string = NULL; char *final_string = NULL; char str1[] = " Test_Value 564 Test_Value2 456 Test_Value3 123 "; char str2[] = " * * * * * * "; size_t i = 0; size_t i2=0; size_t str1_length=strlen(str1); size_t str2_length=strlen(str2); size_t final_string_length=0; //указатель на * в str2 char *ptr2 = strchr(str2, '*'); //указатель на < в str1 char *ptr1=NULL; size_t position = ptr2-str2; size_t count = 0; while (ptr2!=NULL) { // пока находится указатель на звёздочку в str2 //позиция * i=ptr2-str2; //ищем < в str1 if(position #include int main(void) { char *make_string = NULL; char *final_string = NULL; size_t final_string_length=0; char str1[] = " Test_Value_Very_Big_Big_value_VALUE 564 Test_Value2 456 Test_Value3 123 "; char str2[] = "< tr > < th >* * * * * * "; size_t str1_length=strlen(str1); size_t str2_length=strlen(str2); size_t substr_length=0; int more1_count=0; int more2_count=0; char *more1_last=NULL;//позиция последнего '>' в str1 char *less1=NULL;//позиция '<' в str1 int i2=0;//текущая позиция в str2 int i1=0;//текущая позиция в str1 size_t comma_length=0; for(i2=0;i2': more2_count++; if(more1_count'); if(!more1_last) break;//соответствующий '>' не найден, заканчиваем перебор i1=more1_last-str1+1;//передвигаем позицию в str1 на знак за '>' more1_count++; } break; case '*': if(!more1_last) break;//не было '>' в str1 - некорректные входные данные less1=strchr(more1_last,'<'); if(!less1) break;//нет '<' str1 в str1 - некорректные входные данные substr_length=less1-more1_last-1; make_string=(char*)realloc(make_string,substr_length+1); strncpy(make_string,more1_last+1,substr_length); make_string[substr_length]='\0'; //TODO:соединить с final_string if(final_string) comma_length=1; final_string=(char*)realloc(final_string,final_string_length+substr_length+1+comma_length); final_string[final_string_length]='\0'; if(comma_length) final_string=strcat(final_string,","); final_string=strcat(final_string,make_string); final_string_length=final_string_length+substr_length+1; break; } } //добавляем последнюю запятую final_string=(char*)realloc(final_string,final_string_length+1); final_string[final_string_length]='\0'; final_string=strcat(final_string,","); printf("%s\n",final_string); //TODO: освободить память free(make_string); free(final_string); return 0; }

Ответ 2



avp@avp-ubu1:hashcode$ gcc obtain_text.c -Wall && ./a.out Test_Value,564,Test_Value2,456,Test_Value3,123, avp@avp-ubu1:hashcode$ cat obtain_text.c Поправил немного прошлую версию и добавил комментариев #include #include // тут realloc-ом собираем результат (кусочки текста и запятые) struct result { char *str; int capacity, // сколько памяти всего выделено size; // сколько байт накоплено в str }; // добавим символ в конец накапливаемого результата // завершающий 0 не заносим, поэтому его надо добавлять на верхнем уровне static inline char * add_char (struct result *r, char c) { if (r->size >= r->capacity - 1) if (!(r->str = realloc(r->str, r->capacity *= 2))) return 0; // ENOMEM r->str[r->size++] = c; return r->str; } // пропустим заданное число символов // скопируем символы текста до завешающего `<` в результат // при пропуске и копировании анализируем источник на завершающий 0 // возвращаем адрес найденного `<` или завершающего 0-ля, // т.е. адрес, с которого начинается поиск следующего кусочка результата static const char * add_text (struct result *r, const char *src_text, int nskip) { for (; nskip && *src_text; nskip--) src_text++; while (*src_text && *src_text != '<') if (!add_char(r, *src_text++)) return 0; // out of memory return src_text; } // returns comma separeted text in dynamic memory // or NULL on ENOMEM char * obtain_text (const char *text, const char *pattern) { int nskip; struct result result = {malloc(16), 16, 0}; if (!result.str) return 0; // ENOMEM for (nskip = 0; *pattern; nskip++, pattern++) if (*pattern == '*') { // найдено начало очередного фрагмента текста в nskip символах от text if (!(text = add_text(&result, text, nskip)) || !add_char(&result, ',')) return 0; nskip = -1; } // завершим изготовление результата // (add_char(), добавлявший символы, не записывает завершающий 0) result.str[result.size] = 0; return realloc(result.str, result.size + 1); } int main (int ac, char *av[]) { char str1[] = " Test_Value 564 Test_Value2 456 Test_Value3 123 "; char str2[] = " * * * * * * "; char *str = obtain_text(str1, str2); // Test_Value,564,Test_Value2,456,Test_Value3,123, if (str) { puts(str); free(str); } else exit((perror("obtain_text"), 1)); return 0; }

Комментариев нет:

Отправить комментарий