2015-04-15 2 views
2

Следующее упражнение 10.4 книги «Программирование на C» Стивена Кочана. В нем говорится, что я должен создать функцию, которая выводит часть из входной строки и возвращает эту часть обратно в main() (как строку, а не указатель) и отображает ее. Мой код ниже.Простая программа C. Строка, возвращающаяся из функции, вызывает ошибку

#include <stdio.h> 

char subString (const char source[], int start, int count, char result[count + 1]){ //result will be number of characters (count) + 1 (because of null) 
int i, j, end = start + count; 

// the part excluded must start from i = start and "count" number of characters must be derived and then put on result 
for(i = start, j = 0; i < end; ++i, ++j) 
    result[j] = source[i]; 

result[j] = '\0'; 

return result[count + 1]; 
} 

int main (void){ 
char result[20] = {0}; 

const char text1[] = "character"; 

result[20] = subString(text1, 4, 3, result); 
printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, result); 

return 0; 
} 

И выход

From "character" this part is being excluded-> "act" 

Process returned 0 (0x0) execution time : 0.332 s 
Press any key to continue. 

Обратите внимание, что приведенный выше код работает отлично - никаких предупреждений.

Что я не могу понять, когда я заменить две строки ниже

result[20] = subString(text1, 4, 3, result); 
printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, result); 

с этой линией

printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, subString(text1, 4, 3, result)); 

я получить выход:

From "character" this part is being excluded-> "(null)" 

Process returned 0 (0x0) execution time : 0.332 s 
Press any key to continue. 

Почему это ? Как я могу заставить его работать с использованием одной строки? Кроме того, я немного смущен функциями, возвращающими строки/массивы. Они, как правило, приводят меня к ошибкам, поэтому, если кто-то может предоставить мне пару предложений, которые я всегда должен учитывать при работе с ними, это очень помогло бы мне. Заранее спасибо.

+1

Нет допустимого элемента, называемого 'result [20]'. Подсказка: индекс на основе '0'. –

+1

Возможно, вам необходимо проверить работоспособность параметров и убедиться, что start + count не выходит за пределы исходной строки. И цикл должен быть de-obfuscated в это: 'for (i = 0; i Lundin

+0

@Sourav Ghosh Я инициализировал строку с 20 местами в памяти и поместил в него нуль, потому что кто-то сказал мне здесь некоторое время назад, что я всегда должен заполнять нулевые терминаторы в них, когда я их инициализирую (независимо от размера), поскольку это хорошая практика программирования. –

ответ

2

Пункт 1:

В первом случае вы используете значение result который получил измененную через передается в качестве аргумента subString(). Вы используете , не используя возвращаемое значение из subString() fucntion.

Ото, во втором подходе, вы пытается использовать значение rerturn функции subString(), что тоже используя неправильный спецификатор формата.Вы можете узнать больше о правильных спецификаторах формата в man page of printf()

Точки 2

Индекс массива в C начинается от 0. Таким образом, нет действительного элемента, называемого result[20]. Таким образом,

result[20] = subString(text1, 4, 3, result); 

причина ошибка на единицу, которая в свою очередь вызывает undefined behaviour.

+0

.. а я вижу (примерно пункт 2). Да, я знаю это. Да, я не хотел ставить его на 21-й элемент. Я думал, что это правильный способ ввода массива и хранения внутри нужной строки. Я все еще смотрю на это. Я не понял полностью. И да, точка 1 очень верна, не осознавала этого. Но все же я хочу выяснить, как вернуть строку из функции (а не указателя). Все еще смотря .. –

+1

@ RestlessC0bra да Пожалуйста, смотрите внимательно. Всегда проверяйте типы данных, возвращайте значения и спецификаторы формата. :-) –

+1

@ RestlessC0bra Что вы подразумеваете под 'eturn string из функции (а не указателем) .'? что такое _резинирование__строки_? Вы находите и используете _string_ по адресу _base address_, который является самим указателем. Затем? –

1
printf("From \"%s\" this part is being excluded-> \"%s\"\n", text1, subString(text1, 4, 3, result)); 

Запишите, что subString() возвращает символ не char* и вы используете %s напечатать символ, который приведет к непредсказуемому поведению.

Ваш массив модифицируется в функции subString() и в первом случае, если печать результата массива, возвращая result[count + 1], а также есть неопределенное поведение с

result[20] = subString(text1, 4, 3, result); 

массивом из связанного доступа

Вы должны изменить код, как

char *subString (const char source[], int start, int count, char result[]){ //result will be number of characters (count) + 1 (because of null) 
int i, j, end = start + count; 

// the part excluded must start from i = start and "count" number of characters must be derived and then put on result 
for(i = start, j = 0; i < end; ++i, ++j) 
    result[j] = source[i]; 

result[j] = '\0'; 

return result; 
} 

int main() 
{ 
    // Keep your array here 
    char *p = subString(text1, 4, 3, result); 
    printf("%s\n",p); 
} 

или

void subString (const char source[], int start, int count, char result[]){ //result will be number of characters (count) + 1 (because of null) 
    int i, j, end = start + count; 

    // the part excluded must start from i = start and "count" number of characters must be derived and then put on result 
    for(i = start, j = 0; i < end; ++i, ++j) 
     result[j] = source[i]; 

    result[j] = '\0'; 

    } 

В main()

printf("%s\n",result); 
Смежные вопросы