2016-07-15 2 views
1

Я пытался выяснить метод подстроки, такой как сращивание Python, например. 'Привет' [2: 4].Нарезка в C по сравнению с Python

OLD: Указатели new и toret (вернуться) то же самое, но при хранении в hello, имеет новый адрес. Есть ли способ сохранить адрес и распечатать фрагмент?

NEW: Каков наилучший способ поместить символы в буфер?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

//char * substr(char *str, int start, int end); 
//void substr(char *str, int start, int end); 
void get_substr(char *str, int start, int end, char *buffer); 

int main() { 
    char word[] = "Clayton"; 
    char buffer[15]; 
    printf("buffer is now %s",get_substr(word,2,5,buffer); 
    return 0; 
} 


void get_substr(char *str, int start, int end, char *buffer) { 
    int length = end - start; 
    printf("length %d\n",length); 
    //char buffer[length]; //init normal array  
    //assign values from *str 
    int i; 
    for (i = 0; i < length; i++) { 
     buffer[i] = *(str+i+start); 
    } 
} 


//char * substr(char *str, int start, int end) { 
/* char * substr(char *str, int start, int end) { 
    int length = end - start; 
    printf("length %d\n",length); 
    char buffer[length]; //init normal array  
    //assign values from *str 
    int i; 
    for (i = 0; i < length; i++) { 
     buffer[i] = *(str+i+start); 
     printf("i=%d buffer[i]=%c ptr=%c\n",i,buffer[i],*(str+i+start)); 
    } 
    //add endline if not present 
    if (buffer[length] != '\0') { 
     buffer[length] = '\0'; 
     printf("buffer[%d] is %c\n",length,buffer[length]); 
     printf("0 added\n"); 
    } 
    printf("buffer %s %p\n",buffer,buffer); 
    printf("len(buffer) is %d\n",strlen(buffer)); 
    char *toret; 
    toret = (char*) &buffer; 
    printf("toret %s %p\n",toret,toret); 
    return toret; 
} */ 

Извините, это может быть дубликат, но я не могу найти те же примеры в этом домене. Я ЕСМЬ НОВЫЙ ДЛЯ C!

+0

Не принимайте это плохо, но ваш код настолько завален явными ошибками, что ответить на ваш вопрос совершенно невозможно.Использование 'new' в качестве имени переменной? Возвращает адрес выделенной стеком переменной? Доступ к индексу * n * массива длины с индексом 0 * n *? Запутать 'sizeof' с длиной строки? – spectras

+1

@spectras: при использовании 'new' в качестве имени переменной не рекомендуется в C (я не поощряю его, например, или использование какого-либо другого ключевого слова C++, которое не является ключевым словом C), тем не менее, возникает вопрос: помечен C, а не C++, а компилятор C _must_ принимает 'new' как допустимое имя переменной. Если это не так, это не компилятор C, а, возможно, скрытый компилятор C++. (Это не утверждение, что код хорош - это не так! Это просто наблюдение, что 'new' является допустимым именем для общего использования в коде C.) –

+0

@spectras Спасибо, просмотрев некоторые [strncpy] (http://stackoverflow.com/a/14042078/5645103)s мой код, кажется, работает сейчас –

ответ

4

Вы не можете вернуть указатель на буфер, объявленный локально внутри функции. Эта память находится в стеке, и следующий вызов функции, скорее всего, перезапишет эту память. Вам нужно будет использовать malloc для создания необходимой вам памяти, если вы собираетесь вернуть ее вызывающей функции, которая затем должна быть очищена с помощью free, как только вы закончите с ней.

Это, как говорится, обычно нецелесообразно выделять память в вызываемой функции и возвращать ее. Чтобы не допустить, чтобы вызывающий абонент забыл очистить память, я бы рекомендовал запросить буфер, в который будет скопирована подстрока.

Я хотел бы изменить подпись функции, чтобы вернуть пустоту, и возьмите дополнительный буфер, в который подстрока будет скопирована:

void get_substr(char *str, int start, int end, char *buffer) 

Тогда в вашей вызывающей функции, вы можете сделать это:

int main() { 
    char name[] = "Clayton"; 
    char buffer[10]; 

    get_substr(name, 0, 3, buffer); 
    /* "Cla" now copied into buffer */ 

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

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

Ваша подпись может выглядеть следующим образом:

int substr(char *str, int start, int end, char *substr) 

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

int main() { 
    char name[] = "Clayton"; 
    char *substr; 
    int substr_len = substr(name, 0, 3, substr); 
    /* substr now points to name, substr_len = 3 */ 

    /* Copy substring to buffer to print */ 
    char buffer[10]; 
    strncpy(buffer, substr, substr_len); 

    printf("%s", buffer); 
    return 0; 
} 
+0

Спасибо, мой код почти такой же для первого? –

+0

@ClaytonWahlstrom Я не знаю, что ваш код реализован правильно. Сначала я должен проверить 'start> = 0' и' start <= end' и использовать 'strlen' для проверки параметра' end' (чтобы убедиться, что это не конец конца строки). Если вы идете с первым подходом, вы должны использовать 'strncpy' для копирования символов в буфер. Если вы перейдете ко второму подходу, вы можете вычислить 'substr_len' и установить указатель' substr' на 'str + start'. – Darthfett

1

Не тестировался, но нечто подобное следующим образом должно работать:

char name[] = "Clayton"; 
int slice_begin = 0, slice_end = 3; 
printf("%.*s", slice_end - slice_begin, name + slice_begin); 

Update На основе этого метода, вы можете использовать две переменные представляют собой подстроки: указатель на начало среза, и целое число, представляющее длину.

+0

Как это работает в функции? (или это нужно?) –

+0

@ClaytonWahlstrom Все зависит от ваших потребностей. Я считаю, что это слишком просто, чтобы быть функцией самостоятельно, но если вы хотите, чтобы она была более ориентированной на объекты, вы можете обязательно обернуть все в структуре (указатель и длину) и создать функцию управления структурой. – xuhdev

1

Поскольку вы хотите эмулировать кусок Python, я бы с чем-то вроде:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 

char *slice(char *string, int start, int stop, int step) { 
    size_t string_length = ceil(fabs((stop - start)/(float) step)); 

    char *new_string = malloc(string_length + 1); 

    for (int i = start, j = 0; j < string_length; i += step, j++) { 
     new_string[j] = string[i]; 
    } 

    new_string[string_length] = '\0'; 

    return new_string; 
} 

int main() { 
    char *name = "Clayton"; 

    char *hello = slice(name, 0, 3, 1); 

    printf("%s\n", hello); 

    free(hello); 

    char *letters = "abcdefghijklmnopqrstuvwxyz"; 

    char *goodbye = slice(letters, strlen(letters) - 1, -1, -1); 

    printf("%s\n", goodbye); 

    free(goodbye); 

    return 0; 
} 

С выходом:

Cla 
zyxwvutsrqponmlkjihgfedcba 
Смежные вопросы