2015-01-21 1 views
2
/* 
* 1-20. Write a program detab that replaces tabs in the input with the proper number 
* of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns. 
* Should n be a variable or a symbolic parameter? 
* 
*/ 

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define N 4 

void detab(char **str); 

int main(){ 
    char *line=NULL; 
    char *newline; 
    int len; 
    while(getline(&line,&len,stdin)!=-1){ 
     detab(&line); 
     printf("%s",line); 
    } 
    free(line); 
    return 0; 
} 
void detab(char **str){ 
    int len=0,num=0; 
    int i=0; 
    char c; 
    while((c=(*str)[i])!='\0'){ 
     if(c=='\t'){ // get the number of tab 
      num++; 
     } 
     len++;   // get length of string 
     i++; 
    } 
    char *newline; 
    newline=(char *)malloc(len+(N-1)*num+1); //use four blank replace one tab 
    if(newline==NULL){ 
     fprintf(stderr,"can't malloc space\n"); 
    } 
    i=0; 
    int j=0;  //index of newline 
    while((c=(*str)[i])!='\0'){ 
     if(c=='\t'){ 
      int k; 
      for(k=0;k<N;k++){ 
       newline[j]=' '; 
       ++j; 
      } 
     } 
     else{ 
      newline[j]=c; 
      ++j; 
     } 
     ++i; 
    } 
    newline[j]='\0'; 
    free(*str); 
    *str=newline; 
} 

이 제대로 작동 몇 가지 문제가 발생하지만 어쩌면 50 문자의 긴 문자열을 입력하면,이 말한다 :C 프로그래밍 언어 (K & R) ex1-20. 나는 짧은 문자열을 입력하면

*** Error in `./a.out': free(): invalid next size (fast): 0x0961b068 *** 
Aborted (core dumped) 

거의 여기 붙어있다 세 시간. 도와주세요. 나는 이중 연결리스트로 각 입력 라인을 읽고 문제 1_20 해결

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define N 4 

char* detab(char *str); 

int main(){ 
    char *line=NULL; 
    char *newline; 
    int len; 
    while(getline(&line,&len,stdin)!=-1){ 
     newline = detab(line); 
     printf("%s",newline); 
     free(newline); 
    } 
    free(line); 
    return 0; 
} 
char* detab(char *str){ 
    int len=0,num=0; 
    int i=0; 
    char c; 
    while((c=str[i])!='\0'){ 
     if(c=='\t'){ 
      num++; 
     } 
     len++; 
     i++; 
    } 
    char *newline; 
    newline=(char *)malloc(len+(N-1)*num+1); //use four blank replace one tab 
    if(newline==NULL){ 
     fprintf(stderr,"can't malloc space\n"); 
    } 
    i=0; 
    int j=0;  //index of newline 
    while((c=str[i])!='\0'){ 
     if(c=='\t'){ 
      int k; 
      for(k=0;k<N;k++){ 
       newline[j]=' '; 
       ++j; 
      } 
     } 
     else{ 
      newline[j]=str[i]; 
      ++j; 
     } 
     ++i; 
    } 
    newline[j]='\0'; 
    return newline; 
} 
+2

가 [malloc을 (친구)의 결과를 캐스팅하지 마십시오 (http://stackoverflow.com/q/605845). 또한, 할당 실패를 확인하는 것이 좋지만 'stderr'에 쓰는 대신'abort()'또는 다른 것을 사용해서는 안됩니까? – Deduplicator

+0

'getline'은 포인터뿐만 아니라 버퍼에 대한 포인터를 기대합니다. 그것을 확인하십시오 [여기] (http://crasseux.com/books/ctutorial/getline.html) – dmg

+0

내가 볼 수있는 유일한 오류는'getline()'의 두 번째 인수는'size_t *'가 아니라 'int *'. 오류를 일으키는 데 사용 된 긴 문자열의 예를 들려 줄 수 있습니까? valgrind 또는 수동 검사 중 하나를 사용하여 오류를 트리거 할 수 없었습니다. –

답변

1

:이처럼 하나의 포인터를 사용하려고하면

그것은 확인을 작동합니다. 목록의 각 노드는 순서대로 행의 한 문자를 나타냅니다.

링크 된 목록을 만든 후 목록의 끝에서 즉 줄 끝에서 공백을 삭제합니다.

그런 다음 링크 된 목록을 살펴보고 탭을 검색하여 열 개수를 유지합니다.

탭이 발견되면 열 번호를 표시하고 다음 탭 정지까지 필요한 공백 수를 계산합니다. 공식은 다음

tabstop = ((col + (m-1))/m) * m; 

:

  • tabstop 다음 탭 위치
  • m이다 tab stop로 사이의 거리
  • col는 탭

발생하는 열이고 나는 탭을 공백으로 대체하고 죄의 새로운 노드를 삽입한다. 다음 탭 위치에 도달 할 때까지 링크 된 목록의 공백을 제거하십시오.

다음 탭 문자를 검색하고 변환 프로세스를 반복하면서 탭 목록 열에서 링크 된 목록을 계속 걷습니다.

일단 연결 목록의 끝에 도달하면 출력 선으로 인쇄합니다.

이중 연결 목록을 사용하면 지루할 수 있지만 프로그램의 main() 함수의 논리를 크게 단순화합니다.

main() 기능은 말합니다 :

while (not end of file) 
    { 
    getline() 
    remove_final_white_space() 
    convert_tabs_to_spaces() 
    putline() 
    } 

getline() 기능은 탭 문자와 링크 된 목록을 만듭니다.

putline() 함수는 한 번에 한 문자 씩 인쇄하는 동안 연결된 목록을 플러시합니다.

0

괜찮 먼저 :

  • 당신이 지금까지 읽은 내용의 범위를 고려은 당신이 malloc()

  • 같은 범위 함수의 포인터를 사용하고 밖으로 수 없습니다

  • 을 사용할 수 있습니다 이 ex1-20은 지금까지 배운 내용 만 사용하도록 설계되었으므로 상황이 복잡하지 않습니다.

ex1-20 :

#include <stdio.h> 
#define MAXLINE 1000 

void getendtab(char s[],int lim,int n){ 

int c, i; 
i=0; 

while((c = getchar()) != EOF){ 
    if(c == '\t'){ 
    while(n != 0){ 
    s[i] = ' '; 
    i++; 
    n--; 
    } 
    n = 3; 
    }else{s[i] = c; i++;} 
} 

} 

int main(){ 

int n = 3; 
int len; 
char bytes[MAXLINE] = {0}; 
getendtab(bytes,MAXLINE,n); 
printf("%s",bytes); 

return 0; 
}