您好我正在尝试通过使用char[]
将整个文件加载到fread
来标记字符串。
由于一些奇怪的原因,它并不总是有效,而valgrind在这个非常小的样本程序中抱怨。
给出像test.txt
first
second
以下程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
//returns the filesize in bytes
size_t fsize(const char* fname){
struct stat st ;
stat(fname,&st);
return st.st_size;
}
int main(int argc, char *argv[]){
FILE *fp = NULL;
if(NULL==(fp=fopen(argv[1],"r"))){
fprintf(stderr,"\t-> Error reading file:%s\n",argv[1]);
return 0;
}
char buffer[fsize(argv[1])];
fread(buffer,sizeof(char),fsize(argv[1]),fp);
char *str = strtok(buffer," \t\n");
while(NULL!=str){
fprintf(stderr,"token is:%s with strlen:%lu\n",str,strlen(str));
str = strtok(NULL," \t\n");
}
return 0;
}
编译如
gcc test.c -std=c99 -ggdb
像
一样运行./a.out test.txt
感谢
答案 0 :(得分:6)
buffer
尺寸应为filesize + 1
。 +1
适用于null
字符。
filesize = fsize(argv[1]);
char buffer[filesize + 1];
同样fread
不会在字符串末尾放置\0
。所以你必须自己做:
fread(buffer,sizeof(char),filesize,fp);
buffer[filesize] = 0;
答案 1 :(得分:5)
从此site:
int main(int argc, char* argv[])
{
std::string str = "The quick brown fox";
// construct a stream from the string
std::istringstream stream(str);
// use stream iterators to copy the stream to the vector
// as whitespace separated strings
std::istream_iterator<std::string> it(stream), end;
std::vector<std::string> results(it, end);
// results = ["The", "quick", "brown", "fox"]
}
比处理那些让你头疼的令人讨厌的C字符串容易得多。
你知道使用高阶方法有什么好处吗?它占用的屏幕更少,更容易理解。
答案 2 :(得分:2)
buffer
不会以空值终止。您需要使其大于文件大小一个字节,并且您需要将最后一个字节设置为\0
。
答案 3 :(得分:2)
您的缓冲区必须为filesize + 1
,您还需要设置终止0:
int size = fsize(argv[1]);
char buffer[size + 1];
buffer[size] ='\0';
此外,您应该在堆上而不是堆栈上分配缓冲区...
答案 4 :(得分:1)
你的缓冲区太小了。试试这个:
int fileSize = fsize(argv[1]);
char buffer[fileSize + 1];
buffer[fileSize] = 0;
在致电fread
之前。