了解 C 中的结构指针 编辑:feof() 的不当使用

Understanding struct pointer in C EDIT: Improper use of feof()

我很难理解为什么我的 C 程序会收到错误。主函数调用 readFile() 函数,该函数将文本文件的内容复制到 'Text' 结构的二维字符数组,然后是 returns 结构。当我遍历结构数组时,我毫无问题地打印了数组的内容。但是,当尝试使用指向结构的指针并打印数组的内容时,它在某些情况下会打印垃圾。

我的 text.txt 文件的内容是:

Hello world.
Hello galaxy.
Hello universe.
Goodbye.

而且,这是代码:

#include <stdio.h>
#include <stdlib.h>

struct Text {
  char array[10][50];
};

struct Text readFile(char*); 

int main(int argc, char *argv[]) {
  
  int i, j;
  char * file = argv[1];
  struct Text text = readFile(file);  // init Text struct w/call to readFile
  struct Text * ptr_text = &text;     // declare and init a ptr to struct
  // print contents of 2D text array
  for (i=0; i<sizeof(text.array) / sizeof(text.array[0]); i++) {
    for (j=0; j<sizeof(text.array[0]); j++) {
      printf("%c", text.array[i][j]);
      if (text.array[i][j] == '\n') {
        break;  // breaks inner for loop & goes to next column in array
      }
    }
  } 
  // same logic, but, w/ using a pointer to reference struct's array 
  for (i=0; i<sizeof(ptr_text->array) / sizeof(ptr_text->array[0]); i++) {
    for (j=0; j<sizeof(ptr_text->array[0]); j++) {
      printf("%c", ptr_text->array[i][j]);
      if (ptr_text->array[i][j] == '\n') {
        break;  // breaks inner for loop & goes to next column in array
      }
    }
  }   
  return 0;
}

// readFile function definition--
// reads text file, asigns contents to a 'Text' 
// struct with a char array and returns its ptr
struct Text readFile(char* file) {
  
  FILE *fp = NULL;
  int col = 0;
  int row = 0;
  char c;
  // declare Text struct & init w/ null chars
  struct Text t = {{'[=11=]'}};
  
  fp = fopen(file,"r");
  if (fp == NULL) {
    exit(99);
  }
  
  printf("Reading File: %s\n", file);  
  // while loop assigns chars from file to Text struct's 2D array
  while (1) {
    if (feof(fp)) {   
      break;
    }
    c = getc(fp);
    t.array[row][col] = c;
    // if newline char, increment to next row in array, reset col to 0
    if (c == '\n') { 
      row++;
      col = 0;        
      continue;
    }
    // else, increment column in array
    col++;
  }  
  fclose(fp); 
  return t; // return Text struct
}


Program Output: 
[cabox@Centos7-2 c]$ ./read_file1.o ./text.txt
Reading File: ./text.txt
Hello world.
Hello galaxy.
Hello universe.

Goodbye.
�Hello world.
Hello galaxy.
Hello universe.

Goodbye.
�

从上面可以看出,在尝试使用指针打印结构数组的内容时存在无效(内存错误?)符号。所以,很明显,这与我没有 understanding/incorrect 使用指针有关。很抱歉,如果这是重复的,我搜索了很长时间没有找到答案。

编辑:

事实证明,这毕竟与指针无关。如前所述,我显然不理解 feof() 的正确使用。除了建议,我还必须将以下行添加到嵌套打印循环中:

  if (ptr_text->array[i][j] == '[=12=]') {
    break;
  }

制作打印循环的完整代码:

  for (i=0; i<sizeof(ptr_text->array) / sizeof(ptr_text->array[0]); i++) {
    for (j=0; j<sizeof(ptr_text->array[0]); j++) {
      if (ptr_text->array[i][j] == '[=13=]') {
        break;
      }
      printf("%c", ptr_text->array[i][j]);
      if (ptr_text->array[i][j] == '\n') {
        break;  // breaks inner for loop & goes to next column in array
      }
    }
  } 

这样,当到达数组中的空字符时,程序将继续中断打印循环(最终直到 main 终止),而不打印最初未通过调用 readFile 复制到数组中的任何内容().

感谢大家的快速回复!

对于初学者而不是这个声明

char c;

你必须写

int c;

还有这个 while 循环

  while (1) {
    if (feof(fp)) {   
      break;
    }
    c = getc(fp);
    //...

还尝试在您的数组中写入 EOF 值。

你需要像这样重写条件

while ( ( c = getc(fp) ) != EOF )

虽然结构中的数组是零初始化的

struct Text t = {{'[=14=]'}};

尽管如此,最好在每一行中明确地附加终止零字符 '[=15=]'。这将使您的代码更清晰。