2013-07-17 2 views
-2

Есть ли способ обратить вспять строку в C с минимальными (возможно, однострочными) исходными строками кода. C++ поддерживает это, используя #include <algorithm>, как предложено here. Интересно, поддерживает ли C такой механизм.Однострочный реверсивный шнур

+13

Сделайте свою собственную функцию, затем назовите ее одной строкой. Это в основном то, что вы имеете в виду с примером C++. – chris

+0

Вы можете упаковать всю программу в одну строку. – ShuklaSannidhya

+1

Это один из способов, но я на самом деле реферировал, если у него есть стандартная библиотека, которая делает это. – Nagaraju

ответ

7

Вот один вкладыш (своего рода, необходимо объявить переменные), которые не используются библиотечные функции: -

char s [] = "hello world"; 
char *p,*q; 
for (p=s,q=0;p>q;q?*p^=*q,*q^=*p,*p--^=*q++:!*++p?q=s,*--p:0); 

объяснение того, как работает код: -

Переменные: -

  • p: конец указателя строки, инициализированный в начале строки и используется для поиска конца
  • д: два pruposes, указывает на начало строки и используется для государственных

государства: -

  • д == 0: цикл ищет конца входной строки, р инкрементируются найти конец
  • д = 0: для петли замена символов из первой половины строки, а второй половины строки

Termination: -

Петля заканчивается, когда указатель на первую половину строки находится за указателем на вторую половину строки. При поиске конца строки указатель на первую половину (q) равен 0, поэтому условие всегда истинно.

Инкрементирование: -

Третья часть для цикла зависит от состояния и может быть разбита следующим образом: -

if state is searching for end of string (q == 0) 
    increment end of string pointer (++p) 
    if end of string pointer is pointing at null terminator (*p == 0) 
    set start of string pointer and set state to swapping characters (q=s) 
    decrement end of string pointer (--p) 
    endif 
else 
    swap characters (the three ^=) 
    move first and secondhalf pointers (--p, ++q) 
endif 

Причина, по-видимому ненужной * в *--p является чтобы все части тройных операторов имели один и тот же тип.

Если вы все это понимаете, вы должны обнаружить ошибку в коде.

+0

Ouch .. более эффективный, чем Принимая strlen :) – Amarghosh

+0

Я не сказал, что это был хороший код! – Skizz

+0

на второй мысли, это делает то же самое .. сначала находит длину, а затем петли до середины. Пришлось запустить его, чтобы увидеть его. +1 – Amarghosh

2
#include <string.h> 
char *strrev(char *string); 

Описание strrev меняет порядок символов в данной строке. Конечный нулевой символ (\ 0) остается на месте.

Возвращает

strrev возвращает указатель на измененную строку. Там нет возвращаемого значения ошибки

это работает только в Windows

+2

[применимо только к окнам] (http://stackoverflow.com/questions/8534274/is-strrev-function-not-available-in-linux) –

+1

Предполагая, что даже машины с Windows могут закончиться из памяти, я полагаю, что strrev может на самом деле возвращают NULL, когда у него заканчивается память, когда вы переворачиваете свою строку. – hetepeperfan

+0

@SuvP спасибо, я его обновил. –

2

Нет, нет стандарта Си библиотеки подпрограммы для изменения строки (или других последовательностей или диапазонов.)

5

А «минимальное количество of lines "не делает , что много смысла (ведь вся ваша программа может быть написана в одной строке). Если вы готовы пойти на разворот на месте вы можете иметь довольно легкую реализацию, хотя:

void strrev(char *s) { 
    char *p = s + strlen(s); 
    while (s + 1 < p) { 
     char tmp = *s; 
     *s++ = *--p; 
     *p = tmp; 
    } 
} 
+2

+1 но имена функций не должны начинаться с 'str', они зарезервированы для будущего. http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html – ShuklaSannidhya

0

Здравствуйте, это не одна линия, но она работает отлично

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

char *revstr(char *str) 
{ 
    int i; 
    int size; 
    int max; 
    char save; 

    i = 0; 
    size = strlen(str); 
    max = size/2; 
    while (i < max) 
    { 
     save = str[i]; 
     str[i] = str[size - 1 - i]; 
     str[size - 1 -i] = save; 
     i = i + 1; 
    } 
    return(str); 
} 

int main() 
{ 
    char *str; 

    str = strdup("hello"); 
    str = revstr(str); 
    printf("%s\n", str); 
} 
0

Если вы настаиваете один один лайнер, вы получите один лайнер.

for(int i = -1, len = strlen(s), t = 0; ++i < len/2; t = s[i], s[i] = s[len - 1 - i], s[len - 1 - i] = t); 
+0

Это не декларация внутри a for (т.е. 'for (type var = ...') функция C++? – Skizz

+0

@Skizz поддерживается в c99. 'gcc -std = c99'. – Amarghosh

+0

Компилятор VC2010 C/C++ не поддерживает этот стиль цикла for, поэтому я предполагаю, что компилятор тогда не C99. – Skizz

1
#include <stdio.h> 

int strrev_r(char *str, int pos){ 
    char ch = str[pos]; 
    return (ch == '\0')? 0 : ((str[pos=strrev_r(str, ++pos)]=ch), ++pos); 
} 
void strrev(char *str){ 
    strrev_r(str, 0); 
} 

int main(){ 
    char string[] = "string"; 
    strrev(string); 
    puts(string); 
    return 0; 
} 
+0

+1: забава сделать рекурсивную версию. :-) –