valgrind抱怨在c做一个非常简单的strtok

mon*_*ing 2 c c++ valgrind tokenize strtok

嗨,我正在尝试通过将整个文件加载到char[]使用中来标记字符串fread.由于一些奇怪的原因,它并不总是有效,而valgrind在这个非常小的示例程序中抱怨.

给出类似的输入 test.txt

first
second
Run Code Online (Sandbox Code Playgroud)

以及以下方案

#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;
}
Run Code Online (Sandbox Code Playgroud)

编译像

gcc test.c -std=c99 -ggdb
Run Code Online (Sandbox Code Playgroud)

跑得像

./a.out test.txt
Run Code Online (Sandbox Code Playgroud)

谢谢

cod*_*ict 6

你的buffer尺寸应该是filesize + 1.这+1是为了nullchar.

filesize = fsize(argv[1]);
char buffer[filesize + 1];
Run Code Online (Sandbox Code Playgroud)

fread不要\0在字符串的末尾放置一个.所以你必须自己做:

fread(buffer,sizeof(char),filesize,fp);
buffer[filesize] = 0;
Run Code Online (Sandbox Code Playgroud)


Mat*_* M. 5

从这个网站:

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"]
}
Run Code Online (Sandbox Code Playgroud)

比处理那些让你头疼的令人讨厌的C字符串容易得多.

你知道使用高阶方法有什么好处吗?它占用的屏幕更少,更容易理解.