2015-03-27 2 views
0
void reverses(char s[]) 
{ 
    int i, count; 
    i = count = 0; 

    // Get the total character count in array 
    while (s[count] != '\0') ++count; 

    char copy[count]; 

Char копию массива только определяется, когда целое число используется непосредственно, например, char copy[15]; или char copy[DEFINED];.C массив символов Определение длины с помощью переменной не работает

Я передаю ему целое число через int count;, у которого есть объявленное значение, поэтому почему мой массив не определен?

Я нашел ошибку в своем коде после того, что скопировано здесь, извините.

Я использовал цикл while, чтобы сделать обратное - изменение этого на цикл for устранило проблему.

Многие из ваших ответов были очень полезны для меня в любом случае. Так, СпасибоDavid Cullen, Vlad from Moscos, R Sahu, user0815 и haccks

ответ Влада является фантастическим, спасибо за информативное me-- я задумываюсь к вашему ответу. Дэвид Каллен точно следил за моей логикой и получил правильный ответ!

+1

Если вы используете 'gcc', вы можете использовать' -std = c99' для включения массивов переменной длины. –

+0

Эта строка: 'while (s [count]! =' \ 0 ') ++ count;' должно быть: «count = strlen (s)»; – user3629249

+1

Эта строка: 'char copy [count];' должен быть 1 байт дольше, чтобы разрешить байт завершения строки NUL: 'char copy [count + 1];' – user3629249

ответ

2

Этот код произвел ожидаемый результат:

#include <stdio.h> 

void reverses(char s[]) 
{ 
    int i, count; 
    i = count = 0; 

    while (s[count] != '\0') ++count; 

    printf("count = %d\n", count); 

    char copy[count + 1]; 

    for (i = 0; i < count; i++) { 
     copy[count - i - 1] = s[i]; 
    } 
    copy[count] = '\0'; 

    printf("copy = %s\n", copy); 
} 

int main(void) 
{ 
    reverses("string"); 
} 

Выход:

count = 6 
copy = gnirts 

Это было проверено с помощью GCC на OS X:

 
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) 
Target: x86_64-apple-darwin13.4.0 
Thread model: posix 
+0

Это не будет компилироваться с использованием компилятора, который не поддерживает C99, и это, кажется, проблема. – user0815

+0

Я был уверен, что проблема связана с компилятором, но я хотел опубликовать рабочий пример. Если OP компилирует рабочий пример с его компилятором и все работает, то он знает, что у него есть другая проблема. –

+0

@David Cullen Вы забыли добавить завершающий нуль в массив. –

2

Кажется, что ваш компилятор не поддерживает массивы переменной длины.

Учтите, что для записи функции reverse нет необходимости определять вспомогательный массив. Функция может быть записана следующим образом:

char * reverse(char s[]) 
{ 
    size_t i = 0, n = 0; 

    while (s[n]) ++n; 

    for (; i < n/2; i++) 
    { 
     char c = s[i]; 
     s[i] = s[n-i-1]; 
     s[n-i-1] = c; 
    } 

    return s; 
} 
+0

, скорее всего, первый оператор неверен, но следующий оператор и код хороши – user3629249

+1

@ user3629249 Что не так? –

+0

есть проблема с этим кодом. Массив является литералом в памяти только для чтения, поэтому он не может быть изменен. Поэтому массив copy [] генерируется – user3629249

0

Массивы переменной длины являются одной из функций, добавленных в C99. Вам необходимо скомпилировать код с флагом -std=c99 в GCC.

Следует также отметить, что если вы используете MSVS, MSVS не поддерживает VLA.

-1

в более ранних версиях C, переменная может быть определена только сразу после открывающей фигурной скобки «{»

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

I.E.

{ 
    char copy[count+1]; 
    ..... // other associated code that uses the 'copy' variable 
} 
+0

Это не проблема клюв ause 'char copy [15];' работает. – user0815

+1

@ user3629249 Ваш ответ неверен. –

+0

Кажется маловероятным, чтобы какой-либо компилятор поддерживал VLA, но не поддерживал объявления после операторов –

0

правильный способ реализовать массивы переменной длины в C с помощью mallo с.

#include <stdlib.h> 

void makeArrayOfSize(int size) { 
    // Create memory for array 
    char *chars = (char *)malloc(size * sizeof(char)); 

    // Do business logic 

    free(chars); // ALWAYS free pointers to allocated memory to avoid leaks 
} 

Хотя, вы можете сделать строку реверса без копирования строки (если он не жестко закодированы в таблице строк) ...

void reverse(char* string) { 
    int length = 0; 
    int index = 0; 
    char temp; 

    // Ensure string is not null 
    if (!string) { 
     return; 
    } 

    // Get length assuming string has proper '\0' char at the end 
    while (string[length]) { 
     ++length; 
    } 

    // Play catch! 
    while (index < length/2) { 
     temp = string[index++]; 
     string[index - 1] = string[length - index]; 
     string[length - index] = temp; 
    } 
} 

Отказ от ответственности: я не компилировать или запустите этот код ...но это напомнило мне старое задание на домашнее задание, поэтому я счел его ностальгирующим, чтобы дать ему выстрел :)

Редактировать: Скомпилировал этот код. Работает отлично, если строка не жестко закодирована в таблице строк (приведет к ошибке шины). Также не будет сбой, если строка пуста.

Взял больше, чтобы написать хороший тест, чем код, но вот тест и выход показывая работать динамические данные, но ошибка на жестком строку:

int main(int argc, char** arcv) { 
    char *string; 
    char string0[0]; 
    char string1[1]; 
    char string2[2]; 
    char string3[3]; 
    char string4[4]; 
    char string5[5]; 
    char string6[6]; 
    char *string7 = "abcdef"; 

    string2[0] = 'a'; 

    string3[0] = 'a'; 
    string3[1] = 'b'; 

    string4[0] = 'a'; 
    string4[1] = 'b'; 
    string4[2] = 'c'; 

    string5[0] = 'a'; 
    string5[1] = 'b'; 
    string5[2] = 'c'; 
    string5[3] = 'd'; 

    string6[0] = 'a'; 
    string6[1] = 'b'; 
    string6[2] = 'c'; 
    string6[3] = 'd'; 
    string6[4] = 'e'; 

    printf("String: %s\n", string); 
    reverse(string); 
    printf("Reverse String: %s\n", string); 

    printf("String0: %s\n", string0); 
    reverse(string0); 
    printf("Reverse String0: %s\n", string0); 

    printf("String1: %s\n", string1); 
    reverse(string1); 
    printf("Reverse String1: %s\n", string1); 

    printf("String2: %s\n", string2); 
    reverse(string2); 
    printf("Reverse String2: %s\n", string2); 

    printf("String3: %s\n", string3); 
    reverse(string3); 
    printf("Reverse String3: %s\n", string3); 

    printf("String4: %s\n", string4); 
    reverse(string4); 
    printf("Reverse String4: %s\n", string4); 

    printf("String5: %s\n", string5); 
    reverse(string5); 
    printf("Reverse String5: %s\n", string5); 

    printf("String6: %s\n", string6); 
    reverse(string6); 
    printf("Reverse String6: %s\n", string6); 

    printf("String7: %s\n", string7); 
    printf("(error after this)\n"); 
    reverse(string7); 
    printf("Reverse String7: %s\n", string7); 

    return 0; 
} 

Выход:

String: (null) 
Reverse String: (null) 
String0: 
Reverse String0: 
String1: 
Reverse String1: 
String2: a 
Reverse String2: a 
String3: ab 
Reverse String3: ba 
String4: abc 
Reverse String4: cba 
String5: abcd 
Reverse String5: dcba 
String6: abcde 
Reverse String6: edcba 
String7: abcdef 
(error after this) 
Bus error: 10 
+0

«Игра поймать!» часть фантастическая, очень продуманная! Спасибо, что разделили так много! –

+0

Рад, что вы оценили усилия :) Хотя vlad дал такое же решение за меньшее время, чем потребовалось мне, чтобы написать тестовый драйвер. Честно говоря, malloc/free является правильной декларацией динамического массива в C. – Lytic

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