【问题标题】:Reading from a text file that contains a list从包含列表的文本文件中读取
【发布时间】:2015-09-18 16:42:14
【问题描述】:

该程序的目的是读取一个文本文件,其中包含 55 位作者和书名的列表。列表格式为(作者姓名、书名)。我可以使用 malloc、strlen、strtok 和 strcopy。到目前为止,我让程序读出作者的姓名,但我一直坚持如何让程序读取书名。如何让程序从文本文件中读取书名?我知道这段代码有错误,所以请善待。

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

void loadBookName(char* filename, char* authorName[55], char* bookName[55]);

int main(int argc, char* argv[])
{
  //Create two arrays each with length 55
  char* authorName[55];
  char* bookName[55];

  //Ask the user for the name of the file
  char fileName[30];
  //Insert your code here
  printf("Please enter the name of the file\n");
  scanf("%s", fileName);

  //Call the method loadBookName
  loadBookName(fileName, authorName, bookName);

return 0;

//Print the two arrays to test if the two arrays were correctly loaded with the data
int i = 0;
printf("%-30s%-40s\n", "Author", "Book");
for (i = 0; i < 55; i++) {
    printf("%-30s%-40s\n", authorName[i], bookName[i]);
}

}

   /*
  loadBookName method
  This method is responsible for:
   1. Take a file containing a book name and the author name as input
   2. Open the file       
   3. Read the information in the file and store it in two arrays: authorName, bookName
   4. Return the two arrays to the main method.
   */
  void loadBookName(char* filename, char* authorName[55], char* bookName[55])
  {
   int i;
   char string_array[80];
   const char comma[2] = ",";
   //Open the file
   FILE *fp;
   fp = fopen(filename, "r");
   if (fp == NULL)
   {
       printf("Failed to open file\n");
       exit(1);
   }

   for (i=0; i<55; i++)
      {
       fgets(string_array, 80, fp);
       authorName[i] = strtok(string_array, comma);
       printf("%s\n", *authorName);
      }





      //Close the file
      fclose(fp);
      }

当我在终端中运行程序时,它要求我输入文件名(books.txt)。然后当我输入文件名时,程序会打印出 55 个作者的列表。

【问题讨论】:

  • 您能添加一个数据样本吗?
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建最小、完整和可验证的示例。
  • authorName[i] = strtok(string_array, comma);string_array(局部变量)的一部分地址设置为authorName[i]。你需要strdup(分配和复制)。
  • 您可能想检查一下,我认为这个确切的问题在过去几天已经得到了回答。见Memory allocation for char array
  • main() 函数,在正文中大约 10 行,具有语句:return 0;,因此以下行将永远不会被执行。请始终缩进代码。 (切勿使用制表符进行缩进,因为每个文字处理器/编辑器的制表位/制表符宽度设置不同。)建议在每个左大括号“{”之后缩进 4 个空格,并在每个右大括号“}”之前不缩进。建议的 4 个空格即使在可变宽度字体上也是可见的,并且在代码嵌套良好时不会占用整个页面宽度

标签: c


【解决方案1】:

我面前没有编译器,如果有编译错误,请原谅。但我认为您可以在现有代码中尝试以下操作:

更新:

在 cmets 之后,我更新了一行。这是编译和工作的。

假设:用户需要注意错误处理,例如文件不存在、文件无法打开、缓冲区溢出等

    char *token;

    for (i=0; i<55; i++)
    {
        //fgets(string_array, 80, fp);
        //This will take care in case if lines are less than 55
        if(!fgets(string_array, 80, fp))
            break;


        //Get the author
        token = strtokstring_array, comma);
        authorName[i] = token;  // or use string copy functions

        //Get book name
        while( token != NULL ) 
        {
            printf( " %s\n", token );    //this shall print author name
            token = strtok(NULL, comma);
            bookName[i] = token;
            printf( " %s\n", token );    //this shall print book name

            //EDIT: This is additional line after suggestions
            token = strtok(NULL, comma);
        }
    }

【讨论】:

  • 我尝试了代码但无法打开文件
  • 不能保证文件有55行,所以建议用while fgets( string_array, 80, fp) )替换for (i=0; i&lt;55; i++)并在循环内进行行数,所以如果输入文件大于55行,则bookName和authorName 数组不会溢出
  • 此代码假定输入文件已成功打开,但无法保存作者姓名。另外,所有的 authorName 和 bookName char 指针都会指向stringArray,所以除了最后一个之外都是错误的,并且 stringArray 是子函数堆栈上的局部变量,所以退出该函数后将无效。建议使用 strdup() 将唯一指针放入 authorName 和 bookName 数组
【解决方案2】:

用strlcpy分隔字符串的简单方法:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int 
main(void )
{
    size_t i = 1;
    char *authorName, *bookName;
    const char *a_line_in_a_file  = 
         "Lewis Carroll,The Hunting of the Snark";
    const char *title = a_line_in_a_file;
    while ( *title != ','){
        title++;
        i++;}
    authorName = malloc(i);
    bookName = malloc(strlen(title));
    title++;
#if __BSD_VISIBLE
    strlcpy(bookName, title, strlen(title) + 1);
    strlcpy(authorName, a_line_in_a_file, i);
#else
    snprintf(bookName, strlen(title) + 1, "%s", title);
    snprintf(authorName, i, "%s", a_line_in_a_file);
#endif 
    printf("%-30s%-40s\n", authorName, bookName);
   free(authorName);
   free(bookName);
   return 0;
}

【讨论】:

  • 在ubuntu linux 14.04系统上找不到函数:strlcpy()
  • 用更便携的 snprintf 替换可能修复如下: snprintf(bookName, strlen(title) + 1, "%s", title); snprintf(authorName, i, "%s", a_line_in_a_file);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
相关资源
最近更新 更多