【问题标题】:Adding and Printing elements of an array in C在 C 中添加和打印数组的元素
【发布时间】:2020-12-17 05:40:59
【问题描述】:

这是一个函数,它试图通过将 0->S 作为规则添加到规则列表的末尾来执行将 CFG 转换为 Chromsky Normal From 的第一步。我的规则是一个字符数组。出于某种原因,它只会第一次打印数组,之后不会打印。我希望它打印输入,然后在编辑数组后生成结果。我无法弄清楚为什么它不会打印。输出只是原始输入,然后是空格。

更新:它现在将打印两次,但第二次打印的输出与第一次相同。它没有注册我将 ',','0','>','S' 作为元素添加到数组中。我添加的元素有错吗?

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

//global variables
char stringCFG[200];

//a program to convert CFG to Chromsky Normal Form
int main(int argc, char *argv[]){
  //intialize instance variables
  FILE *CFG;
  FILE *output;
  char ch;
  int RHS= 0;
  int isThereS= 0;
  int howManyItems= 0;

  CFG= fopen(argv[1], "r");
  output= fopen(argv[2], "w");
  
  for (int i=0; i<200; i++){
      fscanf(CFG, "%c", &stringCFG[i]);
      howManyItems++;
      fprintf(output,"%c", stringCFG[i]);
  }
  printf("\n");

  for(int i=0; i<200; i++){
    if(stringCFG[i] == '>'){
      RHS= 1;
    }
    if(stringCFG[i] == ','){
      RHS= 0;
    }
    if(RHS== 1){
      if(stringCFG[i] == 'S'){
        isThereS=1;
      }
    }
  }

  if(isThereS==1){
    stringCFG[howManyItems]= ',';
    howManyItems++;
    stringCFG[howManyItems]='0';
    howManyItems++;
    stringCFG[howManyItems]='>';
    howManyItems++;
    stringCFG[howManyItems]='S';
    howManyItems++;
  }
 for(int i=0; i<200; i++){
   fprintf(output,"%c",stringCFG[i]);
  }
  fclose(CFG);
  fclose(output);
}

【问题讨论】:

  • 查看while((ch = fgetc(CFG)) != EOF){ stringCFG[i]= ch;。它将ch 分配给while 循环内的相同数组元素,因为i 未更改。这真的是故意的吗?
  • 我将 while 循环更改为 fscanf,但仍未打印我添加到数组中的新元素
  • 发布 CFG 文件的示例输入。该文件的大小是多少?

标签: arrays c printing


【解决方案1】:

问题似乎出在这里:

  for (int i=0; i<200; i++){
      fscanf(CFG, "%c", &stringCFG[i]);
      howManyItems++;
      fprintf(output,"%c", stringCFG[i]);
  }

无论文件中有什么,这个循环总是执行 200 次。换句话说 - 当循环完成时,howManyItems 的值将是 200。

您可以通过在循环后打印howManyItems 来检查,即

printf("After loop, howManyItems=%d\n", howManyItems);

因为你有:

char stringCFG[200];

然后

stringCFG[howManyItems]= ',';  // bad.. writing to stringCFG[200]
howManyItems++;
stringCFG[howManyItems]= '0';  // bad.. writing to stringCFG[201]
howManyItems++;
...

将写入数组之外。那是未定义的行为。

读取整个文件后,您需要停止第一个循环。比如:

  for (int i=0; i<200; i++){
      if (fscanf(CFG, "%c", &stringCFG[i]) != 1)
      {
          // No more data
          break;
      }
      howManyItems++;
      fprintf(output,"%c", stringCFG[i]);
  }

接下来的所有循环都必须使用howManyItems作为上限。

喜欢

  for(int i=0; i<howManyItems; i++){
    if(stringCFG[i] == '>'){
      RHS= 1;
    }
    ...
  }

顺便说一句:由于您希望能够添加 4 个额外的字符,您可能应该这样做:

char stringCFG[200]; --> char stringCFG[200 + 4];

顺便说一句:一遍又一遍地硬编码值 200 是不好的做法。而是使用如下定义:

#define MAX_CHARS 200

并将所有硬编码的200 替换为MAX_CHARS。然后你可以通过编辑一行而不是多行来调整最大值。

【讨论】:

  • 我添加了您的建议,现在正在打印将字符添加到数组并打印!谢谢你!出于某种原因,它正在下一行打印添加的字符,知道为什么会发生这种情况吗?
  • @maliaLikesCoding 可能您从文件中读取了换行符
猜你喜欢
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
相关资源
最近更新 更多