从文件中读取数据,只读取字母字符

时间:2014-09-29 21:35:04

标签: c

我现在正在研究一个学校的课程,我无法从文件中读取文字。我以前只用过Java,所以我还没有完全熟悉c,这让我彻底难过,尽管我确信这很简单。

以下是如何在我们必须阅读的文件中格式化文本的示例:

boo22 $ Book5555bOoKiNg#BOO#TeX123tEXT(JOHN)

我必须接受每个单词并将其存储在数据结构中,并且单词只是字母字符,因此没有数字或特殊字符。我已经有了正确的数据结构,所以我只需要将每个单词放入一个char数组中,然后将其添加到我的结构中。它必须继续读取每个char,直到它达到非alpha char值。我已经尝试了从文件中扫描的不同方法,我不确定什么对我的方案最好。

以下是我现在输入的代码:

char str[MAX_WORD_SIZE];
char c;
int index = 0;

while (fscanf(dictionaryInputFile, "%c", c) != EOF) //while not at end of file
{   
    if (isalpha(c)) //if current character is a letter
    {
        tolower(c); //ignores case in word
        str[index] = c; //add char to string
        index++;
    }
    else if (str[0] != '\0') //If a word
    {
        str[index] = '\0'; //Make sure no left over characters in String
        dictionaryRoot = insertNode(str, dictionaryRoot); //insert word to dictionary
        index = 0; //reset index
        str[index] = '\0'; //Set first character to null since word has been added
    }
}

我的想法是,如果它没有点击第一个if语句,那么我必须检查str是否是一个单词,这就是为什么它检查str的0索引是否为空的原因。我猜测其他if语句虽然不对,但是我无法找到一种方法来结束我正在构建的当前单词,然后在将str添加到我的数据结构时将str重置为null。现在,当我运行此操作时,如果我将txt文件作为参数传递,则会出现分段错误。

我只是想知道我是否在正确的轨道上,如果没有,可能会对我如何阅读这些数据提供一些帮助。

这是我第一次在这里发帖,所以我希望我能提供你所需要的一切,如果不是让我知道,我很乐意添加更多信息。

1 个答案:

答案 0 :(得分:2)

最大问题:fscanf()使用不正确。 @BLUEPIXY

// while (fscanf(dictionaryInputFile, "%c", c) != EOF)
while (fscanf(dictionaryInputFile, "%c", &c) != EOF)

无法防止溢出。

// str[index] = c; //add char to string
if (index >= MAX_WORD_SIZE - 1) Handle_TooManySomehow();

'\0'也是非alpha版时,不确定为什么要对'\0'进行测试。

当一个签名的isalpha()通过时,char很有问题。当代码知道它不是unsigned char时,最好传递is...((unsigned char) c))值:EOF。或者,使用int ch = fgetc(stream)保存输入并使用is...(ch))

轻微:最好将size_t用于数组索引而不是int,但要注意size_t是无符号的。如果数组变为 large ,则size_t非常重要,与此情况不同。

此外,当收到EOF时,str中的所有数据都会被忽略,即使它包含一个单词。 @BLUEPIXY。

在大多数情况下,OP走在正确的轨道上。


Follows是一个未经测试的示例方法,用于说明不会溢出缓冲区。

测试完整缓冲区,然后根据需要读入char。如果发现非alpha,则在累积非零长度工作时添加到字典中。

char str[MAX_WORD_SIZE];
int ch;
size_t index = 0;

for (;;) {
  if ((index >= sizeof str - 1) ||
      ((ch = fgetc(dictionaryInputFile)) == EOF) ||
      (!isalpha(ch))) {
    if (index > 0) {
      str[index] = '\0';
      dictionaryRoot = insertNode(str, dictionaryRoot);
      index = 0;
    }
    if (ch == EOF) break;
  }
  else {
    str[index++] = tolower(ch);
  }
}