C strcpy_s-缓冲区太小&&;0错误

C strcpy_s-缓冲区太小&&;0错误,c,buffer,C,Buffer,我在这条线上有缓冲区问题 strcpy_s(*(单词+单词计数),单词长度,单词); 我试图从argv[1]中读取一个文件,并打印出该文件中的每个单词及其出现的次数,但我不知道出了什么问题 int main(int argc, char* argv[]) { char *delimiters = argv[2]; // Prose delimiters char buf[BUF_LEN];

我在这条线上有缓冲区问题 strcpy_s(*(单词+单词计数),单词长度,单词); 我试图从argv[1]中读取一个文件,并打印出该文件中的每个单词及其出现的次数,但我不知道出了什么问题

int main(int argc, char* argv[])
{
    char *delimiters = argv[2];                     // Prose delimiters
    char buf[BUF_LEN];                                       // Buffer for a line of keyboard input
    size_t str_size = INIT_STR_EXT;                          // Current memory to store prose
    char*  filePath = argv[1];
    FILE *fP ;
    char* pStr = malloc(str_size);                           // Pointer to prose to be tokenized
    *pStr = '\0';                                            // Set 1st character to null
    fopen_s(&fP, filePath, "r");
    fread(buf, BUF_LEN, 10, fP);





    size_t maxWords = 10;                                     // Current maximum word count
    int word_count = 0;                                       // Current word count
    size_t word_length = 0;                                   // Current word length
    char** pWords = calloc(maxWords, sizeof(char*));          // Stores pointers to the words
    int* pnWord = calloc(maxWords, sizeof(int));              // Stores count for each word

    size_t str_len = strnlen_s(buf, BUF_LEN);                // Length used by strtok_s()
    char* ptr = NULL;                                          // Pointer used by strtok_s()
    char* pWord = strtok_s(buf, delimiters, &ptr);  // Find 1st word

    if (!pWord)
    {
        printf("No words found. Ending program.\n");
        return 1;
    }

    bool new_word = true;                                     // False for an existing word
    while (pWord)
    {
        // Check for existing word
        for (int i = 0; i < word_count; ++i)
        if (strcmp(*(pWords + i), pWord) == 0)
        {
            ++*(pnWord + i);
            new_word = false;
            break;
        }

        if (new_word)                                            // Not NULL if new word
        {
            //Check for sufficient memory
            if (word_count == maxWords)
            { // Get more space for pointers to words
                maxWords += WORDS_INCR;
                pWords = realloc(pWords, maxWords*sizeof(char*));

                // Get more space for word counts
                pnWord = realloc(pnWord, maxWords*sizeof(int));
            }

            // Found a new word so get memory for it and copy it there
            word_length = ptr - pWord;      // Length of new word
            *(pWords + word_count) = malloc(word_length);         
            strcpy_s(*(pWords + word_count), word_length, pWord); // Copy to array
            *(pnWord + word_count++) = 1;                         // Increment word count
        }
        else
            new_word = true;                                      // Reset new word flag

        pWord = strtok_s(NULL, delimiters, &ptr);      // Find subsequent word
    }
intmain(intargc,char*argv[])
{
char*delimiters=argv[2];//散文分隔符
char buf[buf_LEN];//一行键盘输入的缓冲区
size\u t str\u size=INIT\u str\u EXT;//存储散文的当前内存
char*filePath=argv[1];
文件*fP;
char*pStr=malloc(str_size);//指向要标记化的散文的指针
*pStr='\0';//将第一个字符设置为null
fopen_s(&fP,文件路径,“r”);
fread(buf,buf_LEN,10,fP);
size\u t maxWords=10;//当前最大字数
int word_count=0;//当前字数
size\u t word\u length=0;//当前字长
char**pWords=calloc(maxWords,sizeof(char*);//存储指向这些单词的指针
int*pnWord=calloc(maxWords,sizeof(int));//存储每个单词的计数
size_t str_len=strnlen_s(buf,buf_len);//strtok_s()使用的长度
char*ptr=NULL;//strtok_s()使用的指针
char*pWord=strtok_s(buf、分隔符和ptr);//查找第一个单词
if(!pWord)
{
printf(“找不到字。正在结束程序。\n”);
返回1;
}
bool new_word=true;//现有单词为False
while(pWord)
{
//检查现有单词
for(int i=0;i
将空字节添加到字符串末尾。您需要
malloc(word\u length+1)
将空字节添加到字符串末尾。您需要
malloc(word\u length+1)
将空字节添加到字符串末尾。您需要
malloc(word\u length+1)

在字符串末尾添加一个空字节。您需要
malloc(word\u length+1)

在我看来,您好像忘记了为0字符添加一个额外的字节。
尽管如此:不必为文件分配固定的缓冲区大小,您可以使用SEEK_END和偏移量0通过fseek获得文件大小,以分配这么多内存+1字节

在我看来,您好像忘记了为0字符获取额外的字节。
尽管如此:不必为文件分配固定的缓冲区大小,您可以使用SEEK_END和偏移量0通过fseek获得文件大小,以分配这么多内存+1字节

在我看来,您好像忘记了为0字符获取额外的字节。
尽管如此:不必为文件分配固定的缓冲区大小,您可以使用SEEK_END和偏移量0通过fseek获得文件大小,以分配这么多内存+1字节

在我看来,您好像忘记了为0字符获取额外的字节。
尽管如此:您不必为文件分配固定的缓冲区大小,而是可以使用SEEK_END和偏移量0通过fseek获得文件大小,以分配这么多的内存+1字节

fread(buf, BUF_LEN, 10, fP);
首先,当您读取10个元素时,缓冲区太小了10倍

其次,它读取文件的距离不超过BUF_LEN(之前,*10)

此外,代码不处理
换行符
字符,因为我无法在
argv[2]
分隔符规范中传递该字符,即使是
“\\n”

我建议您将
fread()
替换为
fgets()的循环,并重新定义单词分隔符

#define BUF_LEN 1000                        // plenty of room
...
char buf[BUF_LEN+1];                        // allow for 0 terminator
char delimiters[] = " \n\t";                // predefined
...
//size_t str_len = strnlen_s(buf, BUF_LEN); // unnecessary
while (fgets(buf, BUF_LEN, fP) != NULL) {   // new outer loop
    char* ptr = NULL;                       // carry on as you were
    ...
}
接下来,正如其他人所评论的,增加字符串空间分配

*(pWords + word_count) = malloc(word_length+1);

此外,尽管您使用了“安全”字符串函数,但您没有检查
argc
或任何
fopen_s()
fread()
malloc()
calloc()
realloc()
,也没有关闭文件或释放内存。

这一行有两个问题:

fread(buf, BUF_LEN, 10, fP);
首先,当您读取10个元素时,缓冲区太小了10倍

其次,它读取文件的距离不超过BUF_LEN(之前,*10)

此外,代码不处理
换行符
字符,因为我无法在
argv[2]
分隔符规范中传递该字符,即使是
“\\n”

我建议您将
fread()
替换为
fgets()的循环,并重新定义单词分隔符

#define BUF_LEN 1000                        // plenty of room
...
char buf[BUF_LEN+1];                        // allow for 0 terminator
char delimiters[] = " \n\t";                // predefined
...
//size_t str_len = strnlen_s(buf, BUF_LEN); // unnecessary
while (fgets(buf, BUF_LEN, fP) != NULL) {   // new outer loop
    char* ptr = NULL;                       // carry on as you were
    ...
}
接下来,正如其他人所评论的,增加字符串空间分配

*(pWords + word_count) = malloc(word_length+1);
此外,尽管您使用了“saf