C strcpy_s - 缓冲区太小 && 0 错误
C strcpy_s - Buffer is too small && 0 error
我在这条线上有缓冲问题
strcpy_s(*(pWords + word_count), word_length, pWord);
我正在尝试从 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 = '[=11=]'; // 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
}
strcpy_s
在字符串末尾添加一个空字节。你需要 malloc(word_length+1)
.
在我看来,您好像忘记为 0 字符获取一个额外的字节。
尽管如此:您可以使用 SEEK_END 和偏移量 0 来使用 fseek 获取文件大小,而不是为您的文件分配固定的缓冲区大小,以分配那么多内存+1字节
这条线有两个问题:
fread(buf, BUF_LEN, 10, fP);
首先,当您读取 10 个元素时,缓冲区太小了 10 倍。
其次,它读取文件的距离不会超过 BUF_LEN(之前是 *10)。
此外,代码不处理 newline
个字符,因为我无法在 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
...
}
接下来按照其他人的评论,增加字符串space分配
*(pWords + word_count) = malloc(word_length+1);
此外,虽然您使用了"safe"字符串函数,但您没有检查argc
或fopen_s()
、fread()
、malloc()
、calloc()
、realloc()
,也没有关闭文件或释放内存。
我在这条线上有缓冲问题 strcpy_s(*(pWords + word_count), word_length, pWord); 我正在尝试从 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 = '[=11=]'; // 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
}
strcpy_s
在字符串末尾添加一个空字节。你需要 malloc(word_length+1)
.
在我看来,您好像忘记为 0 字符获取一个额外的字节。 尽管如此:您可以使用 SEEK_END 和偏移量 0 来使用 fseek 获取文件大小,而不是为您的文件分配固定的缓冲区大小,以分配那么多内存+1字节
这条线有两个问题:
fread(buf, BUF_LEN, 10, fP);
首先,当您读取 10 个元素时,缓冲区太小了 10 倍。
其次,它读取文件的距离不会超过 BUF_LEN(之前是 *10)。
此外,代码不处理 newline
个字符,因为我无法在 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
...
}
接下来按照其他人的评论,增加字符串space分配
*(pWords + word_count) = malloc(word_length+1);
此外,虽然您使用了"safe"字符串函数,但您没有检查argc
或fopen_s()
、fread()
、malloc()
、calloc()
、realloc()
,也没有关闭文件或释放内存。