【问题标题】:Understanding struct pointer in C EDIT: Improper use of feof()理解 C 编辑中的结构指针:不正确使用 feof()
【发布时间】:2022-01-25 12:41:26
【问题描述】:

我很难理解为什么我的 C 程序出现错误。主函数调用 readFile() 函数,该函数将文本文件的内容复制到“Text”结构的 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() 复制到数组的内容.

感谢大家的快速回复!

【问题讨论】:

  • if (feof(fp)) {...} c = getc(fp); stackoverflow.com/q/5431941/905902
  • 仅供参考,您的while(1) if (feof(fp)) 并不比while (!feof(fp)) 好,这是总是错误的。 See here for why。与正确修复的概念相关,c 应该是 int,而不是 char

标签: c pointers struct eof getc


【解决方案1】:

对于初学者而不是此声明

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-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多