获取'分段错误'当运行简单的字符串操作程序

时间:2015-12-17 18:17:07

标签: c string

我试图学习一些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。我花了相当多的时间环顾四周并阅读有关指针的书籍,但似乎无法弄清楚我在做什么搞乱。感谢您的帮助!

4 个答案:

答案 0 :(得分: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 {stringstringstream设施实际上要容易得多。

如果您坚持使用C语言,那么明确跟踪char指针旁边的长度和分配的容量(就像C ++字符串一样)是很好的做法。哦,重写strlen没有明显的好处。

答案 1 :(得分:3)

*output中,您更改了参数output = verb; ,可能是因为您认为复制了字符串。

// Set birthday date picker min and max
        let currentDate: NSDate = NSDate()
        let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        calendar.timeZone = NSTimeZone(name: "UTC")!
        let components: NSDateComponents = NSDateComponents()
        components.calendar = calendar
        components.year = -18
        let minDate: NSDate = calendar.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
        components.year = -150
        let maxDate: NSDate = calendar.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
        self.birthdayDatePicker.minimumDate = minDate
        self.birthdayDatePicker.maximumDate = maxDate

因此该函数不会向您提供的字符串写入任何内容。然后当你打印它时,它仍然是未初始化的变量

答案 2 :(得分:1)

您不能像通过分配那样复制字符串(char *):

output = verb;

你在这里做的只是在输入字符串处将输出更改为 point ,因此对其中一个字符串所做的任何更改也将适用于另一个字符串 - 因为它们都指向相同的内存

你需要显式地复制内存的函数 - 例如strcpy(确保提供以null结尾的字符串)或memcpy。

而且,关于你的逻辑,因为你最后没有真正检查字符串'ar',只是假设有,为什么不使用这样简单的东西:

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

答案 3 :(得分:1)

在函数conjugatePresentAr()中,您更改了参数* output

output = verb;

是地址影响,而不是价值。 应重新读取指针定义