2010-04-02 52 views
2

您好我試圖通過使用fread將整個文件加載到char[]來標記字符串。 由於一些奇怪的原因,它並不總是有效,而valgrind在這個非常小的示例程序中抱怨。valgrind抱怨做了一個非常簡單的strtok在c

鑑於像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 

謝謝

+1

strtok已經過時,有幾個問題。不要使用它。 – 2010-04-02 07:41:47

+0

你會推薦什麼?對於簡單的東西,這不必是線程安全等我仍然覺得它非常有用 – monkeyking 2010-04-02 07:56:58

+0

好吧,顯然它不是那麼簡單,否則'valgrind'不會抱怨。 – 2010-04-02 08:46:27

回答

6

您的buffer大小應爲filesize + 1+1是用於null char。

filesize = fsize(argv[1]); 
char buffer[filesize + 1]; 

而且fread不把\0在字符串的結尾。所以你必須自己去做:

fread(buffer,sizeof(char),filesize,fp); 
buffer[filesize] = 0; 
+0

可以將變量(文件大小+ 1),而不是一個常量,用作數組大小......? – sky 2013-04-08 01:28:23

2

buffer不是空終止的。您需要將其設置爲比文件大一個字節,並且您需要將最後一個字節設置爲\0

1

您的緩衝區太小。試試這個:

int fileSize = fsize(argv[1]); 
char buffer[fileSize + 1]; 
buffer[fileSize] = 0; 

就在您致電fread之前。

2

你的緩衝區必須filesize + 1,你也將需要設置終止0:

int size = fsize(argv[1]); 
char buffer[size + 1]; 
buffer[size] ='\0'; 

此外,你應該在堆上分配,而不是堆棧緩衝區...

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字符串容易得多。

你知道使用高階方法有什麼好處嗎?它需要更少的屏幕資源並且更易於理解。

+1

+1,這個問題被標記爲C和C++,但是很多次這意味着*我正在編程C++,但可以使用C解決方案*,即使在這種情況下代碼和文件名似乎指示純C。無論如何,這是值得的upvote(做C++的人肯定會讀這個),即使它可能不適合用戶。 – 2010-04-02 09:19:01