2

代码重写更清晰

void indexe(char * line, unsigned ref) {
  unsigned i = 0;
  char word[128];  //(1)
  //char * word;   //(2)
  while(*line) {
    if(isalpha(*line))
      word[i++] = *line;  //(1)
      //*word++ = *line;  //(2)
    *line++;
  }
}

int main(int argc, const char * argv[]) {
  char line[128];
  FILE * f = fopen(argv[1], "r");
  unsigned x = 0;
  while (fgets(line, 128, f)){
    indexe(line, ++x);
  }
  fclose(f);
  return 0;
}

您好,以上两种组合我都试过了:

  1. 单词[] -> 单词[i++]
  2. *单词-> *单词++

整个事情完美无缺,除非在达到 EOF 时,在这种情况下,指针语法因分段错误而失败,但不是数组语法。

我是一个 C 初学者,有人可以用初学者的术语解释这里发生了什么,也许可以提出一个解决指针语法的解决方案?(但请解释一下)

4

2 回答 2

1

正如发布的那样,这个版本很好:

void indexe(char * line, unsigned ref) {
  unsigned i = 0;
  char word[128];  //(1)
  //char * word;   //(2)
  while(*line) {
    if(isalpha(*line))
      word[i++] = *line;  //(1)
      //*word++ = *line;  //(2)
    *line++;
  }
}

但是,如果您建议代码改用标记为 //(2) 的行,您将得到:

char * word;   //(2
*word++ = *line;  //(2)

这只是写入您尚未使用分配的内存初始化的指针的一种情况。这是不允许的。您需要将其保留为数组,或使用类似malloc保留存储的东西。如果你想在不使用数组的情况下编写函数,代码将是:

char *word = malloc(128);    // reserve 128 bytes 
if (word == NULL) {          // these checks are important
   fprintf(stderr, "Cannot allocate memory!");
   exit(EXIT_FAILURE);
}
...other stuff...
free(word);

另请注意:

*line++;

increments line,但无缘无故地取消引用它(在它增加之前)。

于 2013-03-14T21:29:20.820 回答
0

指针语法失败,因为您已经定义了一个指针char * word;,但您没有将它设置为指向任何数据 - 您指向的内存可以在任何地方。因此,当您执行以下语句时:

*word++ = *line;

您将 指向的值存储在 指向line的值中word。不幸的是,你不知道word指向哪里。正如@teppic 指出的那样,您正在写入一个尚未初始化为分配内存的指针。

正如@teppic 之前指出的那样,您可以分配该内存。您还可以执行以下操作:

char reserve[128];
char * word = reserve;  // could also have used &reserve[0]

希望有帮助!

于 2013-03-15T00:33:42.783 回答