/*
* 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;
}
When I enter a short string, it works correctly, but if I enter a long string of maybe 50 characters, it says this:
*** Error in `./a.out': free(): invalid next size (fast): 0x0961b068 ***
Aborted (core dumped)
I have been stuck here for almost three hours. Please help me.
It works OK, if I try to use single pointer, like this:
#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;
}