2015-12-17 3 views
1

Я пытаюсь изучить некоторые C, и у меня есть немного проблем с манипулированием строками. Пытаясь узнать их, я решил создать простой испанский глагол-конъюгатор, но я застреваю. Прямо сейчас я просто пытаюсь удалить последние 2 не '\ 0' строки, а затем добавить к ней 'o'. (Например, для ввода «hablar» я хочу, чтобы он выводил «hablo»). Вот мой код. Я старался быть слишком подробным в своих комментариях, чтобы надеяться помочь понять, что я теряю концептуально.Получение «ошибки сегментации» при запуске простой программы управления строкой

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

/* Reimplemented the length function of a string for practice */ 
int len(char *); 
void conjugatePresentAr(char *, char *); 

int len(char *arr){ 
    int l = 0; 
    while (*arr++ != '\0'){ 
     l++; 
    } 
    return l; 
} 

void conjugatePresentAr(char *verb, char *output){ 
    output = verb; 
    int i = len(verb); 
    while (output < (verb + i -2)){ 
     *output = *verb; 
     output++; 
     verb++; 
    } 
    *output = 'o'; 
    output++; 
    *output = '\0'; 
} 

int main(){ 
    char input[20]; 
    scanf("%s", input); 
    printf("%s\n",input); 
    char conjugated[20]; 
    conjugatePresentAr(input, conjugated); 
    printf("%s\n", conjugated); 
    return 0; 
} 

Для любого входа я получаю Segmentation Fault: 11. Я потратил приличное количество времени, глядя здесь и читать с помощью книг на указателях, но не вполне могу показаться, чтобы выяснить, что я Мессинг , Я ценю вашу помощь!

+1

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

+0

@ dacrovinunghi благодарит брата. Никогда бы не догадался, что мой код сосет. Вместо того, чтобы публиковать этот забавный комментарий, на самом деле было бы более полезно объяснить, почему это плохо/почему он не нужен. Я не просто сбрасывал эту штуку, как 10 минут. Верьте или нет, я на самом деле думал и многое изменил, но я, очевидно, не понимаю понятия. –

+0

показывает отсутствие понимания различий между указателем (хранилищем, используемым для хранения адресов памяти), содержимым указателя (конкретным адресом памяти) и содержимым, которое указывает указатель (содержимое этого адреса памяти) – Speed8ump

ответ

3

В conjugatePresentAr() вы изменили аргумент *output, возможно, потому, что считали, что копируете строку.

output = verb; 

поэтому функция ничего не пишет в строку, которую вы поставили. Затем, когда вы печатаете его, он все еще является неинициализированной переменной.

+0

Да. Это причина сегрегации. – haccks

+0

Поскольку это, по крайней мере, ссылка на github, а не screencap, ее достаточно легко редактировать (Weather Vane просто избил меня). – Useless

+0

@ dacrovinunghi nope: Я видел это для себя, прежде чем вы прокомментировали, но мне потребовалось минуту или две, чтобы ответить. Вы меня превзошли? –

3
int i = len(verb); 
while (output < (verb + i -2)){ 
    *output = *verb; 
    output++; 
    verb++; 
} 

будет продолжать идти навсегда: вы чеканка (verb + i - 2), удаляясь на расстояние (вы увеличиваем verb внутри цикла).

Попробуйте что-то вроде:

char *end = verb + strlen(verb) - 2; 
while (output < end) { 
    ... 
    verb++; /* this doesn't change end */ 
} 

(а также исправить ошибку Флюгер пятнистый, который я полностью пропустил).


Примечание: в общем, обработка строк трудно делать хорошо в C, так как встроенные средства столь низкого уровня. На самом деле гораздо проще использовать C++ с его объектами string и stringstream.

Если вы придерживаетесь C, то явная длина отслеживания и выделенная емкость вместе с указателем char (как и строка C++ для вас) является хорошей практикой. О, и нет очевидной выгоды для перезаписи strlen.

+0

Хорошо. Вау, это была действительно глупая ошибка. Большое спасибо за то, что вы нашли время, чтобы ответить, а не просто умалить мое, по общему признанию, очень плохое понимание C –

+0

Сделать тупая ошибка не делает вас глупым - только повторение такой же глупой ошибки может сделать это :) – Useless

1

Вы не можете копировать строки (символ *) по заданию, как вы делали здесь:

output = verb; 

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

Вам необходимо явно использовать функцию копирования памяти - например, strcpy (обязательно укажите строку с завершающим нулевым символом) или memcpy.

И, о вашей логике, так как вы не действительно проверить строку для «ар», в конце концов, и просто предположим Eсть, почему бы не использовать что-то немного проще, как это:

void conjugatePresentAr(char *verb, char *output) 
{ 
    strcpy(output,verb); 
    int len = strlen(verb); 
    output[len - 2] = 'o'; 
    output[len - 1] = '\0'; 
} 
1

В функции conjugatePresentAr() вы alterered в аргумент * выход

output = verb; 

является ли адрес притворство, а не значение. Необходимо перечитать определение указателя

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