0

我很难理解为什么我的 C 程序出现错误。主函数调用 readFile() 函数,该函数将文本文件的内容复制到“文本”结构的 2D 字符数组,然后返回该结构。当我遍历结构数组时,我打印数组的内容没有问题。但是,当尝试使用指向结构的指针并打印数组的内容时,它在某些情况下会打印垃圾。

我的 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 = {{'\0'}};
  
  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.
�

从上面可以看出,在尝试使用指针打印结构数组的内容时,存在无效(内存错误?)符号。因此,显然这与我对指针的理解/不正确使用有关。抱歉,如果这是重复的,我搜索了很长时间以无济于事。

编辑:

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

  if (ptr_text->array[i][j] == '\0') {
    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] == '\0') {
        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() 复制到数组的内容。

感谢大家的快速回复!

4

1 回答 1

4

对于初学者而不是此声明

char c;

你必须写

int c;

而这个while循环

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

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

您需要重写条件,例如

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

尽管结构中的数组初始化为零

struct Text t = {{'\0'}};

然而,最好在每一行'\0'明确地附加终止零字符。这将使您的代码更清晰。

于 2022-01-25T12:52:15.560 回答