C Новичок: Помощь с простой функцией - PullRequest
1 голос
/ 02 декабря 2010

Спойлер: Я абсолютный новичок в C. Я быстро собрал эту программу, чтобы проверить свои знания, но мой компилятор выдает мне ошибки. В чем проблема и почему?

#include <stdio.h>

void main()
{
    char *string = "abcdefghi";

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

    printf("%s\n\n", substr(string, 1, 2));
}

char * substr(char *string, int start, int length)
{
    int i;
    char *temp;

    for(i = 0; i < length; i++)
    {
        temp[i] = string[i+start];
    }

    return temp;
}

EDIT:

Извините, здесь как час ночи, я пытаюсь это выяснить.

Ошибки:

main.c: In function ‘main’:
main.c:9: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
main.c: At top level:
main.c:12: error: conflicting types for ‘substr’

Ответы [ 5 ]

5 голосов
/ 02 декабря 2010

Вот ошибки, которые я вижу:

Использование неинициализированного указателя

В substr вы объявляете char *temp;, а затем используете его, ничего не инициализируя.Это не ошибка во время компиляции, но эта программа почти наверняка завершится сбоем при запуске, поскольку temp будет эффективно указывать на случайный адрес памяти.Это случай неопределенного поведения , и C переполнен этим.Неопределенное поведение придет из ниоткуда и съест ваших питомцев, если вы не будете осторожны.

Рассмотрите malloc() немного памяти или попросите вашу функцию получить указатель на буфер, в который она может записать частьstring.

Использование функции, еще не объявленной

В C вы должны объявить функции перед их использованием или, по крайней мере, объявить их прототип.Над объявлением main() добавьте эту строку:

char * substr(char *string, int start, int length);

Не использовать const там, где это имеет смысл

При назначении строкового литерала для char* этой переменнойдолжен быть объявлен const.Так что измените

char *string = "abcdefghi";

на

const char *string = "abcdefghi";

Вам придется изменить прототип вашей функции на

char * substr(const char *string, int start, int length)

, что должно быть в первую очередь.

Добавлено 2010-12-02:

substr() не добавляет завершающий нулевой символ

Функция substr(), хотя алгоритмически корректнав любом другом смысле не добавляет завершающий нулевой символ в новую строку.Это приведет к тому, что printf() и любая другая функция, использующая строки (например, strlen(), strcpy() и т. Д.), Выполнит запуск конца строки в нераспределенную кучную память или в стек стека (в зависимости от того, как вы решите "«неинициализированный указатель».)добавлен в цикл for, поскольку это приведет к созданию строки нулевой длины.

1 голос
/ 02 декабря 2010

Самая очевидная ошибка в том, что вам нужно включить прототип в ваш код ...

char * substr(char *string, int start, int length);

main()
...

В противном случае ваша программа не будет знать, что substr был определен (как функция) ниже основногокод.

1 голос
/ 02 декабря 2010

Во-первых, тип возврата main равен int.Во-вторых, вы должны объявить функции перед их использованием.Либо измените порядок main и substr, либо поместите прототип для substr перед вашим main определением.В-третьих, temp не инициализируется.Вам либо нужно malloc() места для него, либо выделить статический буфер (не в стеке).

0 голосов
/ 02 декабря 2010

Проблемы с компилятором: нет прототипа для substr.Ваш компилятор, вероятно, позволит это сделать, если вы не компилируете со строгими стандартами ANSI / ISO.

Некоторые проблемы во время выполнения: вы не выделяли место для * temp.Когда вы объявляете локальную переменную без инициализации, она содержит мусорное значение.Поскольку temp - это указатель на символ, содержимое temp - это указатель на некоторый адрес, который, скорее всего, вам не принадлежит.

0 голосов
/ 02 декабря 2010

На последней итерации этого цикла for, i будет указывать на последнюю позицию строки.Но вы добавляете значение start (в данном случае 1) к i и , затем , индексируя в строку - это означает, что вы, вероятно, получаете ошибку индекса за пределами этогоПоследняя итерация цикла.

Исправление (при условии, что я правильно диагностировал проблему): инициализируйте i до start вместо добавления start к i.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...