C语言 输出和/或终止字符串时出现问题

cu6pst1q  于 2023-03-07  发布在  其他
关注(0)|答案(1)|浏览(141)

编辑:strtok()证明成功地解决了我的问题,谢谢Barmar。
我对C编程还是个新手,现在我已经花了几个小时来完成一项大学作业。我们要做的是从一个包含食物可用性的文本文件中获取输入,然后根据它们的可用性输出这些项目。本质上,程序应该从用户输入中获取文件名,读取文件,将信息存储到四个预定义的字符串数组中,然后按以下格式输出可用的食物:
名称(类别)--说明。
文本文件中的每一行都按以下顺序排列:类别、名称、描述和可用性。类别、名称、描述和可用性由“\t”字符分隔,我们应该省略这些字符。
我遇到的问题是,我似乎不知道如何正确打印输出。当我运行程序时,输出如下混乱:
b'Ham sandwich\x04 (Sandwiches\xec\x9dO\x7f) -- Classic ham sandwich\nCaesar salad\x10 (Salads\xff\xff) -- Chunks of romaine heart lettuce dressed with lemon juice\nWater\x96\x19 (Beverages) -- 16oz bottled water\nBeef tacos\x0f\x9eO\x7f (Mexican food) -- Ground beef in freshly made tortillas\n'
我相信这个混乱是由于打印时某个预定义字符串没有终止,几乎可以肯定是因为它缺少一个'\0'字符。我还相信这个问题源于我将每一行文本放入各自数组中的方式。真正的问题是什么,以及如何解决它,是我一直没能弄明白的事情。我已经给我的教授发了电子邮件寻求帮助,他们说他们会给我回复,但是我还没有得到他们的回复。
说了这么多,下面是我当前的任务代码:

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

int main(void) {
   const int MAX_LINES = 25;   //Maximum number of lines in the input text file
   const int MAX_STRING_LENGTH = 100;  //Maximum number of characters in each column of the input text file
   const int MAX_LINE_LENGTH = 200;  //Maximum number of characters in each line of the input text file 
   
   // Declare 4 string arrays to store the 4 columns from the input text file
   char column1[MAX_LINES][MAX_STRING_LENGTH];
   char column2[MAX_LINES][MAX_STRING_LENGTH];
   char column3[MAX_LINES][MAX_STRING_LENGTH];
   char column4[MAX_LINES][MAX_STRING_LENGTH];
   
   //get name of file, then open it
   FILE* inputFile;
   char fileName[MAX_STRING_LENGTH];
   scanf("%s", fileName);
   inputFile = fopen(fileName, "r");
   
   //string variable to take in each line
   //int variable to keep track of / count each line for the column arrays
   char fileLine[MAX_LINE_LENGTH];
   int countLine = 0;
   
   //when skipping the '\t' character, remember that there is also a null character
   //being skipped over in the array being copied too.
   
   while(!feof(inputFile)){
      fgets(fileLine, MAX_LINE_LENGTH, inputFile);
      
      if(feof(inputFile)){ //I have found that if I don't check for end-of-file again, 
         break;            //it would duplicate the last line.
      }
      
      int i = 0;
      int k = 0;
      int tabCount = 0; //tabCount to account for skipping over \t characters
      //while loop to take file input and put it in respective columns
      while( i < strlen(fileLine) ){
         if( fileLine[i] == '\t' ){
            k = 0;
            i++;
            tabCount++;
         }
         ///////////////////////////////////////////////
         if( tabCount == 0 ){
            
            column1[countLine][k-tabCount] = fileLine[i];
            
         } else if( tabCount == 1 ){
            
            if( !(k >= 1) ){
               k = 1;
            }
            column2[countLine][k-tabCount] = fileLine[i];
            
         } else if( tabCount == 2 ){
            
            if( !(k >= 2) ){
               k = 2;
            }
            column3[countLine][k-tabCount] = fileLine[i];
            
         } else if( tabCount == 3 ){
            
            if( !(k >= 3) ){
               k = 3;
            }
            column4[countLine][k-tabCount] = fileLine[i];
            
         }
         ///////////////////////////////////////////////
         
         i++;
         k++;
      }
      
      countLine++;
   }
   
   /* Attempt at adding NULL character to strings */
   /////////////////////////////////////////////////
   /*for(int i = 0; i < countLine; i++){
      
      if( ( column1[i][strlen(column1[i])]) != '\0'){
         column1[i][strlen(column1[i])] = '\0';
      }
      
      if( ( column2[i][strlen(column2[i])]) != '\0'){
         column2[i][strlen(column2[i])] = '\0';
      }
      
      if( ( column3[i][strlen(column3[i])]) != '\0'){
         column3[i][strlen(column3[i])] = '\0';
      }
      
   }*/
   /////////////////////////////////////////////////
   
   /* Second attempt at adding NULL character to strings */
   /////////////////////////////////////////////////
   /*for(int i = 0; i < countLine; i++){
      for(int k = 0; k < strlen(column1[i]); k++){
         if(column1[i][k] == '\0'){
            column1[i][k] = ' ';
         }
      }
      
      for(int k = 0; k < strlen(column2[i]); k++){
         if(column2[i][k] == '\0'){
            column2[i][k] = ' ';
         }
      }
      
      for(int k = 0; k < strlen(column3[i]); k++){
         if(column3[i][k] == '\0'){
            column3[i][k] = ' ';
         }
      }
      
   }*/
   /////////////////////////////////////////////////
   
   //output
   int b = 0;
   while( b < countLine ){
      if( strcmp(column4[b], "Available\n") == 0 ){
         printf("%s (%s) -- %s\n", column2[b], column1[b], column3[b]);
      }
      
      b++;
   }
   
   fclose(inputFile);

   return 0;
}

这是初始txt文件:

Sandwiches  Ham sandwich    Classic ham sandwich    Available
Sandwiches  Chicken salad sandwich  Chicken salad sandwich  Not available
Sandwiches  Cheeseburger    Classic cheeseburger    Not available
Salads  Caesar salad    Chunks of romaine heart lettuce dressed with lemon juice    Available
Salads  Asian salad Mixed greens with ginger dressing, sprinkled with sesame    Not available
Beverages   Water   16oz bottled water  Available
Beverages   Coca-Cola   16oz Coca-Cola  Not available
Mexican food    Chicken tacos   Grilled chicken breast in freshly made tortillas    Not available
Mexican food    Beef tacos  Ground beef in freshly made tortillas   Available
Vegetarian  Avocado sandwich    Sliced avocado with fruity spread   Not available

我将非常感谢任何帮助。

wrrgggsh

wrrgggsh1#

这是我调整过的循环,它解决了我的问题:

while( fgets(fileLine, MAX_LINE_LENGTH, inputFile) != NULL){
  
  token = strtok(fileLine, delimiter);
  strcpy(column1[countLine], token);
  
  token = strtok(NULL, delimiter);
  strcpy(column2[countLine], token);
  
  token = strtok(NULL, delimiter);
  strcpy(column3[countLine], token);
  
  token = strtok(NULL, delimiter);
  strcpy(column4[countLine], token);
  
  if( strcmp(column4[countLine], "Available\n") == 0){
     printf("%s (%s) -- %s\n", column2[countLine], column1[countLine], column3[countLine]);
  }
  
  countLine++;
}

分隔符变量是一个常量,包含“\t”字符。令牌变量是一个字符指针。这两个变量都是在进入while循环之前声明的。
出于赋值的目的,保留了四列数组,而不是像克雷格Estey建议的那样压缩成一个数组。

相关问题