reallocとstrtokの併用について
fscanfで文字列を読み込み、strtokでカンマ区切りにするという関数を作りたいのですが、
reallocすると先頭から徐々にデータが文字化けしていきます。
まず最初に4つ分のchar*を取ります。
もし、5つ目が見つかったらさらに4つ増やし、9つ目が見つかったらさらに。。。というようになっております。
n個目の判定はcntがn-1で真になり、reallocが成功したら個数を増やすようになってます。
5つ目が見つかった時点では出力に問題は無いのですが、6個目から侵食が始まっていきます。
原因がどうしても自分では分からなかったので、誰かお願い致します。
words.txtの内容(末尾改行なし)
iii,jjj,kkkkkkkkk,l,m,n,ooooo,pppppppp,a,s,d,f,g
main.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"C:\borland\bcc55\Include\malloc.h"
int readlinefile(FILE *fp,char **words){
int cnt=0,len;
char *line=(char *)malloc(256);
char *tmp;
if(line==NULL) return 0;
if(fscanf(fp,"%s",line)!=EOF){
if((tmp=(char *)realloc(line,sizeof(char)*(strlen(line)+1)))==NULL){//できるだけメモリを節約してみる
return 0;
}else{
line=tmp;
}
len=strlen(line);
printf("line:%d:%d:%s\n",len,_msize(line),line);
if(len>1){//ファイル終端の改行を排除
int i;
char *tok=strtok(line,",");//カンマで区切ったアドレスを得る
while(tok){
if(cnt==0)printf("tok:1st:%x\n",tok);
if(cnt>3&&cnt%4==0){//サイズが足りなくなった時
char **tmp2;
if((tmp2=(char **)realloc(words,sizeof(char *)*(4+4*(cnt%4))))==NULL){
printf("words realloc ERROR\n");
break;
}else{
printf("realloc\n");
words=tmp2;//reallocを適用
}
}
words[cnt]=tok;
if(cnt){
printf("line(func)");
for(i=0;i<len+1;i++){
printf("%c",words[0][i]);
}
printf("\n");
}
tok=strtok(NULL,",");
printf("words[%d]:%x:%s\n",cnt,words[cnt],words[cnt]);
printf("\n");
printf("tok:%d回目:%x\n",cnt+1,tok);
cnt++;
}
return cnt;//正常終了した
}else{
free(line);
}
}
return 0;
}
int main(){
FILE *fp=fopen("words.txt","r");
if(fp){
int cnt=1;
while(cnt){
int i;
char **words=(char **)malloc(sizeof(char *)*4);
words[0]=NULL;
cnt=readlinefile(fp,words);
printf("mainに戻りました\n");
if(cnt) printf("words:%d\n",cnt);
for(i=0;i<cnt;i++){
printf("words[%d]:%x:%s\n",i,words[i],words[i]);
}
free(words[0]);
words[0]=NULL;
printf("\n");
free(words);
}
}else{
printf("file open ERROR\n");
}
return 0;
}
実行結果
なぜかコピペできないので実行するか斧でダウンロードお願いします。
http://www1.axfc.net/u/3352789.txt
全てまとめたもの
http://www1.axfc.net/u/3352796.zip
お礼
while実行後にprintf文にてstA.pTmp内を参照すると ABCDEFGしか出力されなくなってしまいます。