【问题标题】:fscanf overwriting next bytes in memory (C)fscanf 覆盖内存中的下一个字节 (C)
【发布时间】:2013-10-08 00:01:40
【问题描述】:

基本要点是,我从文本文件中读取单词,将它们存储为字符串,运行一个函数,然后循环多次,每读取一个新行就重写该字符串。这个循环完成后,我需要处理一个不同的字符串。问题是,第二个字符串的字节,即使我在声明时将它们设置为 0,也会被比我分配给第一个字符串的空间更长的单词中的额外字母覆盖:

char* currDictWord = malloc(9*(sizeof(char));
char* currBrutWord = malloc(9*(sizeof(char));
memset(currBrutWord, 0, 9);
memset(currDictWord, 0, 9);

...

while (stuff) {

fscanf(dictionary, "%s", currDictWord);

}

...

printf("word: %s\n", currBrutWord);

currBrutWord 将不再为空。我处理此问题的两种方法是确保 currDictWord 比字典文件中最长的单词长(一种贫民窟解决方案),并在循环后对 currBrutWord 执行新的 memset。有没有办法告诉 C 停止将内容写入我专门为不同变量分配的内存中?

【问题讨论】:

  • 分配更多空间?使用比fscanf更明智的功能?只需编写符合您要求的代码即可。

标签: c memory malloc overwrite scanf


【解决方案1】:

是的:停止使用fscanf(最好是整个scanf-family),改用fgets,它可以让您传递要读入变量的最大字节数。

编辑:(回应评论)

fgets 将停止读取,直到读取了 count 字节或找到了字符串中的换行符。因此,在fgetsing 字符串之后,检查它的末尾是否有换行符(必要时删除)。如果文件中的字符串fgetc 中没有换行符,直到您找到一个,如下所示:

fgets(currDictWord, 9, dictionary);
if(currDictWord[strlen(currDictWord) - 1] != '\n'){
    while(fgetc(dictionary) != '\n'); /* no body necssary */
    /* the stream-pointer is now a the beginning of the next line */
}

【讨论】:

  • 这似乎不起作用,因为它会在 9 个字符后继续读取当前行。我希望它在 9 个字符后丢弃该行的其余部分,而不是从它停止的地方开始。此外,我还有一些错误,它甚至没有击中正确的字符串。 fgets(currDictWord, 9, 字典);
  • 谢谢!我最终发现没有使用正确字符串的问题与最后包含不可见 \n 的字符串有关,所以我也不得不用 \0 替换它,但是您的代码为此提供了结构。
  • 不客气,如果它解决了问题,不要忘记“接受”答案!
【解决方案2】:

不正确的字符串分配和不验证从文件中读取的数据。

currBrutWord 被溢出,因为太多的chars 被写入currBrutWord。如果你这样做了,也会发生同样的事情:

strcpy(currBrutWord, "123456789");  // Bad as this copy 9+1 char into currBrutWord

当使用fscanf()时,可以限制通过以下方式读取的数据:

fscanf(dictionary, "%8s", currDictWord);

防止 fscanf() 将过多数据放入currDictWord。那部分很好,但是您仍然有来自文件的意外数据。您需要挑战来自外部世界的任何数据。

if (NULL == fgets(bigbuf, sizeof bigbuf, dictionary)) {
  ; handle EOF or I/O error
}
// now parse and validate bigbuf using various tools: strtok(), sscanf(), etc.
int n;
if ((sscanf(bigbuf, "%8s%n", currDictWord, &n) < 1) || (bigbif[n] != '\n')) {
  ; handle error
}

【讨论】:

    猜你喜欢
    • 2018-04-27
    • 2015-06-12
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多