C编程语言(K& R)ex1-20。我遇到了一些麻烦

时间:2015-01-21 04:18:33

标签: c kernighan-and-ritchie

/*
 * 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个字符的长字符串,它会说:

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

我被困在这里将近三个小时。请帮帮我。

如果我尝试使用单指针,它可以正常工作,如下所示:

#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 个答案:

答案 0 :(得分:1)

我通过将每个输入行读入双向链表来解决问题1_20。列表中的每个节点按顺序表示该行的一个字符。

创建链表后,我从列表末尾删除空格,即从行尾删除。

然后我走链表,扫描标签,保留列数。

当我遇到标签时,我会标记其列号,并计算在下一个标签前需要多少空格。公式是:

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

其中:

  • tabstop是下一个tabstop
  • m是tabstops之间的距离
  • col是标签出现的列

我用空格替换制表符,并在链接列表中插入单个空格的新节点,直到我到达下一个制表符。

我继续从tabstop的列中移动链接列表,搜索下一个制表符并重复转换过程。

当我到达链表的末尾时,我将其打印为输出行。

使用双向链表可能看起来很乏味,但它极大地简化了程序中main()函数的逻辑。

main()函数说:

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

getline()函数使用制表符创建链接列表。

putline()函数会在链接列表中一次打印一个字符时刷新链接列表。

答案 1 :(得分: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;
}