디버거를 사용하여 버그를 찾았습니다. 그리고 나는 그 버그가 무엇인지를 발견 할 수있었습니다. 하지만 왜 그것이 발생하는지 모르겠습니다. 버그는 linep
이 1 push
이후에 약간의 멍청한 주소 (1 칸 추가됨)를 나타냅니다. 그래서 두번째로 push
에서이 라인에 오류가 발생합니다 : tmp1 = tmp2 = *x;
linep
은 약간의 어수선한 주소입니다 (아마도). 내가 linep
가 어색한 주소가되는 이유를 모르겠다. 누군가가 그 사실을 설명 할 수 있기를 바랍니다. 코드는 다음과 같습니다.Entab 프로그램에서 예기치 않은 오류가 발생했습니다 (액세스 위반 읽기)
참고 : 프로그램의 목적은 모든 탭을 4 칸 바꾸는 것입니다.
#include <stdio.h>
#define MAXLINESIZE 1000
#define TABSPACES 4
void push(char *x, char val, int index);
int mgetline(char *s, int lim);
int main(void) {
char line[MAXLINESIZE];
char *linep = line;
while (mgetline(line, MAXLINESIZE) > 0) {
while (*linep) {
if (*linep == '\t') {
*linep = ' ';
for (int i = 1; i <= TABSPACES - 1; i++) {
push(line, ' ', linep - line + 1);
linep++;
}
}
linep++;
}
printf("%s", line);
linep = line;
}
return 0;
}
void push(char *x, char val, int index) {
char tmp1, tmp2, cnt;
char *ptc;
x += index - 1;
ptc = x;
tmp1 = tmp2 = *x;
cnt = 0;
while (tmp2) {
tmp2 = *x;
*x = tmp1;
tmp1 = *(x + 1);
*(x + 1) = tmp2;
x += 2;
cnt++;
}
*ptc = val;
}
int mgetline(char *s, int lim)
{
int c;
char *t = s;
while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
*s++ = c;
if (c == '\n')
*s++ = c;
*s = '\0';
return s - t;
}
참고 : 입력 .
탭 (09 진수 ASCII 코드)와 동일하다 *
공간 (20 진수 ASCII 코드)와 동일하다.
입력 :.
ABCD의 *의 EF ** g의 ****의 HJ * .k ** 리터
당신은에 제대로 포인터를 복사 루프를 설정해야
당신은 자리에서 선 더 이상 할 수없는 변경 될 수 있습니다. 삽입 포인터가 소스 포인터를 따라 잡아서 당신 앞에있는 도로를 파괴 할 것이므로 문자를 걸러 내고 더 짧게 만들 수 있습니다. null 종결자를 개구리 도약시킬 수도 있습니다. –
또한 읽는 모든 행에 대해'linep'를'line'의 시작으로 재설정해야합니다. 현재, 라인 읽기 루프 밖에서는 처음 한 번만 시작합니다. –
좋아요, 공백을 삽입하면 전체 줄을 오른쪽으로 밀면됩니다. 이는 매우 비효율적이며 텍스트가 오른쪽 끝에있는 불법 영역으로 밀려 들어갈 위험이 있습니다. 입력란 하나, 출력물 하나씩 두 줄로 나누어 보십니까? 또는 버퍼 오버런의 위험이 항상있는 중간 문자열을 사용하지 않고 즉시 출력 스트림에 인쇄하십시오. –