分段错误,但我没有无限循环......我想

时间:2014-04-05 14:16:45

标签: c

C语法的新手,所以也许我只是犯了一个愚蠢的错误。我试图通过使用完全相同的过程自己实现strcat()函数。我的copycat函数是strcat406()。

尝试运行程序时,我一直将分段错误视为错误。

编辑:strcat406()中的第一个while循环是我尝试绕过strlen()函数。我试图避免使用内置操作。

EDIT2:好的,正如人们指出的那样,我更换了' \ n'到' \ 0'。愚蠢的错误。然后我通过删除' string1 [i] = string [i]'来修复整个事情。这样第一个循环只是迭代来确定i(string1的长度),然后在第二个while循环中将string2添加到string1。以下代码中的更正。

#include <stdio.h>

char *strcat406(char string1[ ], char string2[ ]) {

    int i = 0, j = 0;

    while (string1[i] != '\0') { //replaced '\n' with '\0'
        //removed: string1[i] = string1[i];
        i++;
    }
    while (string2[j] != '\0') { //replaced '\n' with '\0'
        string1[i+j] = string2[j];
        j++;
    }
    string1[i+j] = '\0';
    return string1;
}

int main() { 

    char str1[81], str2[81]; 
    char again = 'y', newline;

    while (again == 'y') { 
        printf("Enter a string\n"); 
        scanf("%s", str1); 
        printf("Enter another string\n"); 
        scanf("%s", str2); 
        printf("The concatention is %s\n", strcat406(str1, str2)); 
        printf("Second test:  The concatenation is %s\n", str1);
        printf("The second string is still %s\n", str2); 
        printf("Again? (y/n)\n"); 
        scanf("%c%c", &newline, &again); 
    }
}

3 个答案:

答案 0 :(得分:2)

问题是您的while循环正在寻找要终止的换行符,但scanf("%s", ...)不会在扫描的字符串中包含结尾换行符。您应该寻找'\0'来终止这些循环。

顺便说一句......这个问题的标题反映了一种误解。你说你得到了段错误,但是没有无限循环&#34;。段错误通常不是由无限循环引起的。它们通常是由解除引用空指针或“坏”指针引起的。以某种其他方式。请注意,数组索引是指针取消引用的一种形式,因此使用&#34; bad&#34;数组索引也是一样的。

答案 1 :(得分:0)

问题是您正在将一个连接的结果写在其中一个输入字符串之上。此时第一个循环(通过string1)什么都不做;它只是逐个字符地复制string1。我想你可能会在换行符'\ n'和字符串终止字符'\ 0'之间感到困惑。

你得到段错误的原因是你在第二个循环中开始写入第一个输入字符串后面的内存。只为它保留了81个字符的内存,但是你可能会为串联编写更多的内存。

我认为答案是创建一个新字符串来包含函数的结果。您需要首先循环输入字符串,计算它们的长度,以了解它需要多长时间。然后,当您将两个字符串复制到结果中时,您将只使用您在内存中为其保留的空间。此外,您不会将输入更改为函数的一部分,这是当前方法的另一个问题。

答案 2 :(得分:0)

字符串是包含终止空字符'\0'的字符数组,而不是换行符'\n'。因此,在strcat406函数中,您应该检查空字节的值而不是换行符。请注意str2必须足够大,以便string2附加到它,否则会导致缓冲区溢出,从而调用未定义的行为。另请注意,字符串string1string2的长度均应小于81,其长度之和应小于81 + 81 == 162

#include <stdio.h>

char *strcat406(char string1[], char string2[]) {
    int i = 0, j = 0;
    // increment i till the terminating null byte is reached
    while(string1[i++]) ; // the null statement

    i--;  // reset i to the index of the null byte

    // copy the characters from string2 to string1 till and 
    // including the terminating null byte of string2
    while((string1[i++] = string2[j++])) ; // the null statement

    return string1;
}

int main(void) { 
    char str1[81], str2[81]; 
    char again = 'y';

    while(again == 'y') { 
        printf("Enter a string\n"); 
        scanf("%s", str1); 
        printf("Enter another string\n"); 
        scanf("%s", str2); 
        printf("The concatention is %s\n", strcat406(str1, str2)); 
        printf("Second test:  The concatenation is %s\n", str1);
        printf("The second string is still %s\n", str2); 
        printf("Again? (y/n)\n");

        // note the leading space in the format string of scanf.
        // this reads and discards the newline left in the buffer in 
        // the previous scanf call
        scanf(" %c", &again);  
    }
    return 0;
}