2014-04-05 3 views
0

Новый синтаксис C, поэтому, возможно, я просто делаю тупая ошибка. Я пытаюсь реализовать функцию strcat() самостоятельно, используя тот же самый процесс. Моя функция подражания - strcat406().Сегментация Fault, но у меня нет бесконечных циклов ... Я думаю,

При попытке запустить программу я все время испытываю ошибку сегментации как ошибку.

EDIT: первый цикл while в strcat406() - это моя попытка обойти функцию strlen(). Я пытаюсь избежать использования встроенных операций.

EDIT2: Хорошо, так как люди указали, я заменил '\ n' на '\ 0'. Глупая ошибка. Затем я исправил все это, удалив строку 'string1 [i] = string [i]'. Таким образом, первый цикл просто выполняет итерацию для определения i (длина строки1), затем строка string2 добавляется в строку1 во втором цикле while. Исправления в коде ниже.

#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];' for? Это кажется излишним ... Также segfaults не обязательно являются результатом бесконечных циклов: обычно это связано с доступом/изменением памяти, которой вы не владеете. Проверьте, не закончились ли строки. – Kninnug

+0

Как вы можете объединить 2 массива символов в пространстве 1? – cppcoder

+0

@cppcoder: Вы имеете в виду concatenate 2 строки в буфере, который в настоящее время содержит один, но достаточно большой для обоих ;-)? – Deduplicator

ответ

0

Строка представляет собой массив символов, содержащих конечный нулевой символ '\0', а не символ новой строки '\n'. Поэтому в функции strcat406 вы должны проверить значение для нулевого байта, а не символ новой строки. Обратите внимание: str2 должен быть достаточно большим для добавления к нему string2, иначе это вызовет переполнение буфера, вызывающее неопределенное поведение. Также обратите внимание, что длины обеих строк string1 и string2 должны быть меньше 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, но «не имеют бесконечных циклов». Segfaults обычно не вызваны бесконечными циклами. Они обычно вызваны разыменованием нулевого указателя или указателем, который является «плохим» каким-либо другим способом. Обратите внимание, что индексирование массива является формой разыменования указателя, поэтому использование индекса «плохого» массива - это одно и то же.

0

Проблема в том, что вы пишете результат конкатенации поверх одной из входных строк. В настоящий момент первый цикл (поверх строки1) ничего не делает; это просто копирование string1 поверх самого символа по символу. Я думаю, что вы можете запутаться между символом новой строки '\ n' и символом завершения строки '\ 0'.

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

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

+0

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

+0

Правда. Если проблема '\ n'/'\ 0' разрешена, это все равно будет проблемой в целом и может появиться только очень редко. – gandaliter

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