堆栈粉碎和使用malloc
我正在制作一个程序,计算文件中包含的字数。我的代码适用于包含少于一定数量单词/字符的文件的特定测试用例……但当我使用以下单词进行测试时: “OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO,它给了我这个错误:堆栈粉碎和使用malloc,c,C,我正在制作一个程序,计算文件中包含的字数。我的代码适用于包含少于一定数量单词/字符的文件的特定测试用例……但当我使用以下单词进行测试时: “OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
*** stack smashing detected ***: ./wcount.out terminated
Abort (core dumped)
我知道错误的含义,并且我必须实现某种malloc代码行才能分配正确的内存量,但我不知道在我的函数中放在哪里或如何做:
int NumberOfWords(char* argv[1]) {
FILE* inFile = NULL;
char temp_word[20]; <----------------------I think this is the problem
int num_words_in_file;
int words_read = 0;
inFile = fopen(argv[1], "r");
while (!feof(inFile)) {
fscanf(inFile, "%s", temp_word);
words_read++;
}
num_words_in_file = words_read;
printf("There are %d word(s).\n", num_words_in_file - 1);
fclose(inFile);
return num_words_in_file;
}
int NumberOfWords(char*argv[1]){
文件*infle=NULL;
char temp_word[20];正如您通过使源代码无效(未来提示:/*将箭头放在注释中*/
)正确识别的那样,问题在于temp_word
只能容纳20个字符(其中一个必须是终端空字符)
此外,您应该检查fopen
的返回值。我将把它作为练习留给您。我已经在其他问题(例如)中回答了这个问题,但我不认为将代码塞进您的脸上会对您有所帮助
在这种情况下,我认为更好地分析您遇到的问题,看看您是否真的需要存储单词来计数。当我们将单词(由scanf(“%s”)读取的类型)定义为一个非空白字符序列,后跟一个(零或更多)字符序列时空白字符,我们可以看到像您这样的计数程序需要遵循以下步骤:
尽可能多地阅读空白
尽可能多地阅读非空白
如果全部成功,则递增“word”计数器
你不需要像存储空白一样存储非空白,因为一旦你读了它,你就再也不会访问它了。因此你可以把它写成嵌入其中的两个循环:一个循环读取尽可能多的空白,另一个循环读取非空白,然后递增,然后外部循环重复e整批……直到达到EOF
这最好使用%*s
指令来实现,该指令告诉scanf
相关函数不要尝试存储单词。例如:
size_t word_count = 0;
do {
fscanf(inFile, "%*s");
} while (!feof(inFile) && ++word_count);
您受到数组大小的限制。一个简单的解决方案是增加数组的大小。但是如果有人输入一个长单词,您总是容易受到堆栈崩溃的影响
单词由空格分隔
只需存储一个初始化为零的计数器变量和一个记录当前字符的变量即可。每次使用fgetc(infle,&temp)读入字符时
这是一个空格,您可以增加计数器。在当前代码中,您只需计算单词数。因此,您对单词本身不感兴趣。您可以使用可选的*
字符抑制赋值:
fscanf(inFile, "%*s");
不确定是否要标记或什么,但这与完全无关。因此,您正在将未知长度的字符串读入20个字节,并想知道为什么要在堆栈上跺脚?使用20多个?读取20(可能是19)一次字符。许多可能的方法。代码中有几个错误。在fopen
之后未测试infle
。请参阅char temp\u-word[20]
无法容纳您试图用无限制的fscanf(infle,“%s”,temp\u-word)读取的247长度字符串
等等。如果你想数一数文件中的字数,那么抛出“oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
at这很愚蠢。只有很少的单词包含20个或更多字符,因此将数组长度增加到100,并限制输入长度。重新编辑:您需要输入的“实际测试用例”应该是有效的单词,还是您应该拒绝的测试用例?