Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > срочно нужно написать функцию


Автор: chudik 5.5.2007, 01:12
помогите написать функцию  для дублирования строки
например: "боб" -> "боббоб"

Автор: anwe 5.5.2007, 01:20
Посмотри API-функцию lstrcat.

Автор: apook 5.5.2007, 06:23
Код

#include"iostream.h"


void duplicat( char wstr[] )
{
int i, j, c;
for( i=0; wstr[ i ]!='\0'; i++ );

for( j=i, c=j, i=0; c>0; j++, i++, c-- )
    wstr[ j ]=wstr[ i ];

return;
}


void main()
{
char str[ 100 ]="Bob";

duplicat( str );

cout << str << endl;

return;
}

Автор: adLucem 5.5.2007, 08:39
Дублирование строки с выделением памяти для новой строки.
Код

#include "stdio.h"
#include "string.h"

char *DuplicateString ( const char *source ) {
    char *result = new char [ strlen ( source ) * 2 + 1 ];
    strcpy ( result, source );
    strcpy ( result + strlen ( source ), source );
    return result;
}

void main ( ) {
    char source [10] = "Bob";
    printf ( "%s\n", DuplicateString ( source ) );
}


Так как DuplicateString выделяет память для строки, то не забывайте освобождать ее.

Код

void main ( ) {
    char source [10] = "Bob";
    char *destination = DuplicateString ( source );
    printf ( "%s\n", destination );
    delete destination;
    destination = NULL;
}


Дублирование строки без выделения памяти для новой строки.
Код

#include "stdio.h"
#include "string.h"

void DuplicateString ( char *source ) {
    char *buffer = strdup ( source );
    strcpy ( source + strlen ( source ), buffer );
    delete buffer;
}

void main ( ) {
    char source [10] = "Bob";
    DuplicateString ( source );
    printf ( "%s\n", source );
}

Автор: Robin 5.5.2007, 08:40
если в переменной a достаточно места, почему не просто не скопировать в нее ее саму?
///опередили

Автор: chudik 5.5.2007, 11:58
Видимо я не так выяснилась, что вы меня не поняли.
Мне нужно по программированию написать функцию которая будет копировать любую введеную строку, а то был просто пример.
Тоесть я с клавы ввожу любой текст, а эта функция должна его скопировать. Готовые функции использовать нельзя. функция должна быть написана самостоятельно.

Автор: apook 5.5.2007, 12:06

Цитата

помогите написать функцию  для дублирования строки


Цитата

Мне нужно по программированию написать функцию


Цитата

 Готовые функции использовать нельзя. функция должна быть написана самостоятельно.


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

Автор: adLucem 5.5.2007, 12:25
 smile 
http://forum.vingrad.ru/act-SR/f-27.html
Цитата

Заголовок сообщения должен кратко отражать суть проблемы, нельзя давать заголовки типа «Помогите», «Срочно нужна помощь», «Есть вопрос», «Очень надо», «Сложный вопрос по программированию» и тому подобное.


Цитата(chudik @  5.5.2007,  09:58 Найти цитируемый пост)
Видимо я не так выяснилась, что вы меня не поняли.
Мне нужно по программированию написать функцию которая будет копировать любую введеную строку, а то был просто пример.
Тоесть я с клавы ввожу любой текст, а эта функция должна его скопировать. Готовые функции использовать нельзя. функция должна быть написана самостоятельно. 


По моему вы ошиблись - с такими вопросами нужно обращаться в центр помощи.
Цитата

Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".

Или вы считаете, что форум предназначен для написания для вас лабораторных работ по программированию?

Надеюсь вы учтете все вышесказанное в дальнейшем.
 smile 

Решение.
Код

#include "stdio.h"

#define BUFFER_SIZE 100

void main ( ) {
    // Считываем строку
    char *buffer = new char [ BUFFER_SIZE ];
    scanf ( "%s", buffer );

    // Вычисляем длину строки
    int length = 0;
    while ( buffer [ length ] ) {
        length++;
    }

    // Дублируем строку
    for ( int i = 0; i < length; i++ ) {
        buffer [ length + i ] = buffer [ i ];
    }
    buffer [ length * 2 ] = 0;

    // Выводим результат
    printf ( "%s\n", buffer );

    // Уничтожаем строку
    delete buffer;
}


Забавные варианты (детям до 16 лет использование запрещено smile )
Код

#include "stdio.h"
#include "malloc.h"

#define BUFFER_SIZE 100

void main ( ) {
    char *buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );
    scanf ( "%s", buffer );

    int length = 0;
    while ( buffer [ ++length ] );
    int i = 0;
    while ( ( buffer [ length + i ] = buffer [ i ] ) && ( i++ < length ) );
    buffer [ length * 2 ] = 0;

    printf ( "%s\n", buffer );
    free ( buffer );
}


Код

#include "stdio.h"
#include "malloc.h"
#include "memory.h"

#define BUFFER_SIZE 100

void main ( ) {
    char *buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );
    scanf ( "%s", buffer );

    int length = 0;
    while ( buffer [ ++length ] );
    memcpy ( buffer + length, buffer, length + 1 );

    printf ( "%s\n", buffer );
    free ( buffer );
}


Только на указателях (с контролем длины вводимой строки).
Код


#include "stdio.h"
#include "conio.h"
#include "malloc.h"

#define BUFFER_SIZE 100

void main ( ) {
    char *buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );

    char *src = buffer - 1;
    while ( ( ++src < buffer + BUFFER_SIZE / 2 - 1 )
        && ( ( *src = getch ( ) ) != 0xD ) );
    char * dest = src;
    while ( ( dest - src < src - buffer )
        && ( *dest++ = buffer [ dest - src ] ) );
    *dest = 0;

    printf ( "%s", buffer );
    free ( buffer );
}


А кто-нибудь может это сделать менее чем на трех переменных (тип не имеет значения)?

Автор: JackYF 6.5.2007, 10:14
Цитата(adLucem @  5.5.2007,  12:25 Найти цитируемый пост)
детям до 16 лет

Не согласен. До 14. smile

Автор: ama_kid 6.5.2007, 11:23
В качестве дополнения решения от adLucem (если все-таки дублирование строки надо сделать функцией):
Код
#include "stdio.h"
#define BUFFER_SIZE 100

char * StrDup(char *s, char *buf)
{
 // Вычисляем длину строки
 int length = 0;
 while ( s[ length ] ) length++;
 // Дублируем строку
 for ( int i = 0; i < length; i++ )
 { 
   buf [ i ] = s[ i ];
   buf [ length + i ] = buf [ i ];
 }
 buf [ length * 2 ] = 0;
 //Возвращаем указатель на сформированный буфер
 return buf;
}

void main ( ) 
{
    // Считываем строку
    char *bufferIn = new char [ BUFFER_SIZE ];
    char *bufferOut = new char [ BUFFER_SIZE ];
    char *pBufOut;
    scanf ( "%s", bufferIn );
    // Вызываем функцию дублирования строки
    pBufOut = StrDup(bufferIn,bufferOut);
    // Выводим результат
    printf ( "%s\n", pBufOut );
    // Уничтожаем строки
    delete bufferIn;
    delete bufferOut;
}


Цитата(adLucem @  5.5.2007,  12:25 Найти цитируемый пост)
детям до 16 лет использование запрещено
Не согласен - пусть учатся с пелёнок   smile 

Автор: nickless 6.5.2007, 13:30
Цитата(adLucem @  5.5.2007,  11:25 Найти цитируемый пост)
А кто-нибудь может это сделать менее чем на трех переменных (тип не имеет значения)?

Чтоб только на указателях?
Вот на двух char*-ах smile 
Код
#include "stdio.h"
#include "malloc.h"

#define BUFFER_SIZE 100

int main ()
{
    char* buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );
    char* src = buffer - 1;

    while (( ++src < buffer + BUFFER_SIZE / 2 - 1 ) && ( (*src = getchar()) != 0xA ))
        ;
    *src = 0xA;

    while ( (*++src = *++buffer) != 0xA )
        ;
    *src = 0;
    src -= 2*(src-buffer);
    *buffer = *src;
    buffer = src;

    printf("%s\n", buffer);
    free ( buffer );
    return 0;
}

Автор: adLucem 6.5.2007, 14:28
nickless, зачтено

Немного переработанный код.
Код

void main ( ) {
    char* buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );

    char* src = buffer - 1;
    while ( ( ++src < buffer + BUFFER_SIZE / 2 - 1 ) 
        && ( (*src = getchar ( ) ) != 0xA ) );
    *src = 0;
    while ( ( *++src = *++buffer ) );
    *buffer = * ( buffer - ( src - buffer ) );
    buffer = buffer - ( src - buffer );

    printf("%s", buffer);
    free ( buffer );
}


Интересно, а еще можно уменьшить количество переменных  smile или количество строк кода (имеется в виду не за счет сведения двух строк в одну)?

Автор: Dov 6.5.2007, 21:44
Сложно у вас как-то, ребяты! Аж в глазах рябит.  smile  Имхо, по-проще нада делать.  smile 
Код
int main()
{
    char source[100];    

    cin.getline(source, 100);    
    for(int len = 0; source[len]; len++);
    for(int i = len; i >= 0; i--)
        source[i + len] = source[i];
    
    cout << source << endl;
    return 0;
}

 smile 

Автор: adLucem 7.5.2007, 11:11
Dov, проверяйте ваш код перед публикацией  smile  :
Код

int main()
{
    char source[100];    
    cin.getline(source, 100);    
    for(int len = 0; source[len]; len++); // len объявлен только в области видимости данного цикла
    for(int i = len; i >= 0; i--) // ошибка компилятора error C2065: 'len' : undeclared identifier

        source[i + len] = source[i];
    
    cout << source << endl;
    return 0;
}


И еще - перед тем как упрощать (хотя что именно вы упростили непонятно) знакомтесь со всеми приведенными вариантами, то что вы предлагаете ничем не отличается моего кода, который был предложен как самый простой вариант (кроме использования статического массива и cin).

Автор: betal 7.5.2007, 16:58
Цитата(chudik @  5.5.2007,  01:12 Найти цитируемый пост)
помогите написать функцию  для дублирования строки
например: "боб" -> "боббоб" 

проще всего делать двойной вывод в этом случае smile 

Автор: Promitheus 8.5.2007, 10:53
Господа, а граммотно ли 

Код

#define BUFFER_SIZE 100
...
char* buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );
    char* src = buffer - 1;


Писать через #define жесткое количество элементов, а потом под них динамически память выделять ?
Не экономнее ли скажем массив завести ?

Или уж тогда с клавы читать количество требуемых элементов, а потом память выделять ? 

Автор: Promitheus 8.5.2007, 12:01
 smile 

adLucem, я прекрасно понял в чем суть вопроса. Прямого отношения к задаче (помогите написать функцию  для дублирования строки) мои замечания не имеют, но косвенно всё же они относятся к и данной задаче в том числе. И я, чтобы не заводить новую тему написал сюда вопрос, сам я так не пишу, и хотел выяснить насколько это целесообразно и может быть есть подводные камни, о которых я не знаю.

Ваш тон это ваше личное дело.

Я бы так сделал, по-деревенски:

Код

doublestr(char *dest,const char *source)
{int i=0,j=0;
  while (dest[j++]=source[i++]);
  i=0;j--;
  while (dest[j++]=source[i++]);}

Автор: Promitheus 8.5.2007, 13:16
 smile  Прежде всего спокойно, я войну никому не объявляю.

Кардинально оно ничем не отличается от приведенных варинатов, но на мой взгляд оно лаконичнее и все операторы делают то, что должны.  В принципе тему можно было закончить, после 3 поста, поскольку функция написана, вывод в поток есть - всё. Но коли уж Вы решили написать еще пару функций, вот я и решил задать Вам вопрос, на который, я так понимаю Вы отказываетесь отвечать ...



 

Автор: adLucem 8.5.2007, 13:39
Цитата(Promitheus @  8.5.2007,  08:53 Найти цитируемый пост)
Писать через #define жесткое количество элементов, а потом под них динамически память выделять ?
Не экономнее ли скажем массив завести ?


В данном случае действительно можно использовать статический массив (использование динамической памяти пришло в процессе экспериментов).

Но в общем случае вопросы использования #define для задания максимального размера буфера и способа выделения памяти не связаны.

Автор: Voldemar2004 8.5.2007, 13:56
Цитата(chudik @  5.5.2007,  02:12 Найти цитируемый пост)
помогите написать функцию  для дублирования строкинапример: "боб" -> "боббоб"

Код
#include <string>

std::string DblStr(std::string My){

return My+=My;

}

Автор: Promitheus 8.5.2007, 15:46
adLucem, Всё спасиб. Про то, что такое #define я знаю.  smile  Всё, хватит уж воду в ступе толочь по этому поводу.

Автор: W4FhLF 8.5.2007, 16:57
Цитата(adLucem @  5.5.2007,  12:25 Найти цитируемый пост)
А кто-нибудь может это сделать менее чем на трех переменных (тип не имеет значения)?


Конечно, 1 переменная.

Код

void main(void)
{
    char str[ 100 ]="Bob";

    __asm {
        pushad
        
        //определяет длину строки
        lea edi, str
        xor eax,eax
        xor ecx, ecx
        not ecx
        repne scasb
        lea eax, str
        sub edi, eax
        mov eax, edi
        dec eax
        //////////////////////////

        //копируем строку
        lea esi,str
        mov edi,esi
        add edi,eax
        mov ecx,eax
        rep movsb
        //////////////////

        popad
    };

    cout << str << endl;
    return;
}



Автор: chudik 9.5.2007, 22:07
 а как сделать так чтобы ваши программы правильно определяли длинну строки? во всех ваших программах строка ситается до пробела после пробела информация не копируется. smile 

Автор: dizzy1984 10.5.2007, 07:01
Информация копируется до символа '\0', т.е символа с кодом 0.
Пробелы также копируются.

Автор: chudik 10.5.2007, 13:24
Цитата(dizzy1984 @ 10.5.2007,  07:01)

Пробелы также копируются.

но в том то и дело что не в одной из программ пробелы не копируются

Автор: dizzy1984 10.5.2007, 13:49
Borland C++ 3.1
Код

#include <stdio.h>

doublestr(char *dest, const char *source)
{int i=0,j=0;
while (dest[j++]=source[i++]);
i=0;j--;
while (dest[j++]=source[i++]);}

void  main() {
    char arr1[] = {"ad dsa sak"};
    char arr2[sizeof(arr1) * 2];

    doublestr(arr2, arr1);
    printf("%s\n%s", arr1, arr2);
};

Вывел
ad dsa sak
ad dsa sakad dsa sak

Что абсолюно верно. Пробелы скопировались.
Почему вы считаете иначе?

Автор: ama_kid 10.5.2007, 13:54
Цитата(dizzy1984 @  10.5.2007,  13:49 Найти цитируемый пост)
Почему вы считаете иначе?
Он считает иначе, потому что у тебя строка присваивается жестко, а в предложенных выше вариантов - строка считывается с помощью scanf или cin, которые считывают данные до пробела...
chudik, Все варианты работают правильно, только инициализацию строки надо проводить по другому. Вариант с scanf тебе предложили как наименее геморройный... Формирование строки с пробелом - это уже другая задача... 

Автор: Dronchik 11.5.2007, 13:17
А не легчели сделать...

Цитата

А кто-нибудь может это сделать менее чем на трех переменных (тип не имеет значения)?


Код

long stroka;
cin >> stroka;
cout << stroka << stroka;

Автор: Voldemar2004 11.5.2007, 21:42
Мне кажется, самое простое это то, что я предложил:
Код
#include <string>
std::string DblStr(std::string My){
return My+=My;
}
 smile 

Автор: chudik 25.5.2007, 14:19
Цитата(adLucem @ 6.5.2007,  14:28)
nickless, зачтено

Немного переработанный код.
Код

void main ( ) {
    char* buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );

    char* src = buffer - 1;
    while ( ( ++src < buffer + BUFFER_SIZE / 2 - 1 ) 
        && ( (*src = getchar ( ) ) != 0xA ) );
    *src = 0;
    while ( ( *++src = *++buffer ) );
    *buffer = * ( buffer - ( src - buffer ) );
    buffer = buffer - ( src - buffer );

    printf("%s", buffer);
    free ( buffer );
}


[/b]

а вы не могли бы закоментировать этот код

Автор: adLucem 25.5.2007, 15:48
Код

#include <malloc.h>
#include <stdio.h>

#define BUFFER_SIZE 100

void main ( ) {
    // Выделяем память для буфера, в которм будет храниться строка.
    char* buffer = ( char* ) malloc ( sizeof ( char ) * BUFFER_SIZE );
    // Устанавливаем указатель для начала записи данных в буфер.
    // Так как при записи мы используем пре-инкремент запись начнется с первого символа буфера.
    char* src = buffer - 1;
    // Посимвольно считываем вводимые данные.
    // Условиями завершения является:
    //  - достижение половины заданного размера буфера, так буфер должен дублироваться и не следует допускать переполнения.
    //  - нажатием пользователем клавиши Enter, которая считается терминальным (завершающим) символом при вводе строки.
    while ( ( ++src < buffer + BUFFER_SIZE / 2 - 1 ) 
        && ( (*src = getchar ( ) ) != 0xA ) );
    // Ставим в конце строки нулевой символ, чтобы получить строку в С-стиле.
    *src = 0;
    // src указывает на последний символ строки, buffer - на первый символ, копируем из начала в конец, пока не достигнем нуля.
    // Копирование начинается со второго символа, чтобы не затереть нуль (последний символ) в конце и не получить вечный цикл.
    while ( ( *++src = *++buffer ) );
    // src указывает на последний символ продублированной строки, buffer - на первый символ продублированной строки (который в данный момент равен нулю), копируем из начала в конец, пока не достигнем нуля.
    // Копируем пропущенный первый символ.
    *buffer = * ( buffer - ( src - buffer ) );
    // Устанавливаем указатель buffer на начало строки.
    buffer = buffer - ( src - buffer );
    // Выводим строку на экран.
    printf ( "%s", buffer);
    // Очищаем память, выделенную для буфера.
    free ( buffer );
}

Автор: adLucem 25.5.2007, 16:23
W4FhLF
Цитата(W4FhLF @  8.5.2007,  14:57 Найти цитируемый пост)
Конечно, 1 переменная.


Не зачтено - речь шла о С/С++, а не об ассемблере.

Автор: W4FhLF 26.5.2007, 05:56
Цитата(adLucem @  25.5.2007,  16:23 Найти цитируемый пост)
Не зачтено - речь шла о С/С++, а не об ассемблере.


Конструкция __asm {} является частью языка, поэтому всё в пределах допустимого, никаких доп. средств и извращений я не использовал. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)