2014-04-05 3 views
0

C 구문이 새로워서 어쩌면 그냥 벙어리 오류가 발생했을 것입니다. 똑같은 프로세스를 사용하여 strcat() 함수를 직접 구현하려고합니다. 내 모방 자 함수는 strcat406()입니다.세그먼트 화 오류,하지만 무한 루프가 없습니다 ... 내 생각 엔

프로그램을 실행하려고 할 때 오류로 계속 세그먼트 화 오류가 발생합니다.

EDIT : strcat406()의 첫 번째 while 루프는 strlen() 함수를 둘러보기위한 제 시도입니다. 내장 된 작업을 사용하지 않으려 고합니다.

EDIT2 : 좋아요, 사람들이 지적했듯이 '\ n'을 '\ 0'으로 바꿨습니다. 멍청한 실수. 그런 다음 'string1 [i] = string [i]'를 제거하여 전체를 수정했습니다. 이렇게하면 첫 번째 루프가 i (문자열 1의 길이)를 결정하기 위해 반복되고, 두 번째 while 루프에서는 string1에 string2가 추가됩니다. 아래 코드의 수정.

#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); 
    } 
} 
+0

무엇이'string1 [i] = string1 [i];'입니까? 오히려 불필요한 것 같습니다 ... 또한 segfaults 반드시 무한 루프의 결과가 아닙니다 : 그것은 일반적으로 당신이 소유하지 않은 메모리 액세스/수정 때문입니다. 문자열을 다 사용하지 않았는지 확인하십시오. – Kninnug

+0

어떻게 1의 공간에서 2 문자 배열을 연결할 수 있습니까? – cppcoder

+0

@cppcoder : 현재 하나는 포함하고 있지만 두 개를 모두 포함 할 수있는 버퍼에는 2 개의 문자열을 연결해야합니다. – Deduplicator

답변

0

문자열은 null이 아닌 문자 '\0'을 포함하는 문자 배열이며 줄 바꿈 문자 '\n'이 아닙니다. 따라서 strcat406 함수에서 줄 바꿈 문자가 아닌 null 바이트 값을 확인해야합니다. str2string2을 추가 할 수있을만큼 커야하며 그렇지 않으면 정의되지 않은 동작을 호출하는 버퍼 오버플로가 발생합니다. 또한 문자열 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; 
} 
+0

귀하의 답변이 가장 유용했습니다. 귀하의 코드가 제 것보다 훨씬 앞서기는했지만 문제에 대한 당신의 논리가 가장 좋았습니다. 당신은 내 'string1 [i] = string [i]'라인이 말이 안되는 것을 깨닫게했고 아마도 그 일을 망쳤습니다. 보라, 보라, 그것이 그 대답이었다. 당신의 도움을 주셔서 감사합니다. – clenard

2

문제는 개행 문자가 종료에 대한 귀하의 while 루프를 찾고 있습니다,하지만 scanf("%s", ...) 스캔 한 문자열의 끝 바꿈이 포함되지 것입니다. 해당 루프를 종료하려면 '\0'을 찾아야합니다.

그런데 ...이 질문의 제목은 오해를 반영합니다. 당신은 segfault를 얻었지만 "무한 루프가 없다"고했습니다. Segfault는 일반적으로 무한 루프에 의해 발생하지 않습니다. 그것들은 일반적으로 널 포인터를 역 참조하는 것 또는 다른 방법으로 "나쁜"포인터가 원인입니다. 배열 인덱싱은 포인터 역 참조 (dereference)의 한 형태이므로 "나쁜"배열 인덱스를 사용하는 것은 똑같은 일임을 주목하십시오.

0

문제는 입력 문자열 중 하나의 상단에 연결 결과를 쓰는 것입니다. 현재 첫 번째 루프 (string1 이상)는 아무 것도하지 않습니다. 문자 1 문자 씩 위에 문자 1을 복사하는 것입니다. 나는 당신이 줄 바꿈 문자 '\ n'과 문자열 종료 문자 '\ 0'사이에서 혼란스러워하고 있다고 생각한다.

segfaults가 나타나는 이유는 두 번째 루프에서 첫 번째 입력 문자열 다음에 오는 메모리에 쓰기가 시작된다는 것입니다. 단지 81 문자의 메모리가 예약되어 있지만, 연결을 위해 그 이상을 쓸 수도 있습니다.

나는 대답은 함수의 결과를 포함하는 새로운 문자열을 만드는 것이라고 생각한다. 먼저 입력 문자열을 반복하면서 길이를 계산하여 얼마나 오래 있어야하는지 알아야합니다. 그런 다음 결과에 두 개의 문자열을 복사하면 메모리에 예약 한 공간 만 사용하게됩니다. 또한 현재 메소드의 또 다른 문제점 인 함수의 일부로 입력을 변경하지 않습니다.

+0

버퍼 오버런은 확실히 가능할 수 있지만, 입력을 얻는 방법으로도 가능합니다. 현재 테스트 입력이 짧기 때문에 즉각적인 문제는 줄 바꿈과 null이지만 오버런 문제는 장기적으로주의 또는 제한이 필요합니다. –

+0

참. '\ n'/ '\ 0'문제가 해결되면 이는 여전히 일반적으로 문제가되며 매우 드물게 나타날 수 있습니다. – gandaliter