/*
* 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;
}
答案 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;
}