首页 > 解决方案 > 如何将文件中的行读入字符串数组?

问题描述

#define LINES 4
#define LENGHT 30

typedef struct
{
  char *name;
  char *phoneNumber;
  char *location;
  char *traveltype;
} Client;

int main(int argc, char *argv[])
{
  char *filename = argv[1];
  char clientData[LINES][LENGHT];
  readClientData(filename, clientData);

  /* How to do this client struct */
  Client *client = createClient(clientData[0], clientData[1], clientData[2], clientData[3]);
  return 0;
}

void readClientData(char *filename, char clientData[LINES][LENGHT])
{
  FILE *file = fopen(filename, "r");
  if (file == NULL)
  {
    perror("Error while opening file!");
    exit(1);
  }

  char line[LENGHT];
  int i = 0;
  while (fgets(line, LENGHT, file) != NULL)
    clientData[i] = line; /* How to do this */ 
    i++;
  fclose(file);
}

来自 pythonista 世界,我有点困惑这里的工作方式。很明显,我不能只在列表中添加行,也不能像初始化客户端结构那样访问这些行。

也许我应该只使用 a char *clientData[],但不知道如何。

标签: carraysdynamic-arrays

解决方案


要复制 C 字符串,您需要使用:

char * strcpy ( char * destination, const char * source );

来自标准 C 字符串库,string.h.

但是,请注意,与 Python(您的背景)不同,缩进没有定义循环的主体,您需要使用大括号!

所以,你需要这样做:

while (fgets(line, LENGHT, file) != NULL)
{
  strcpy(clientData[i], line);
  i++;
}

没有大括号,只有第一行代码将被视为循环体。所以,在上面的例子中,循环体——如果我们使用大括号——将只是对复制字符串方法的调用,计数器的增量不会是循环的一部分!


您需要在使用它之前定义或仅声明一个方法,而您在示例中没有这样做。


由于您只需要一个客户端,因此不需要指针,您可以简单地创建一个,通过Client client;.

为了简单起见,请使用您到目前为止从阅读此答案中收集的知识,并定义字符串的最大长度(即结构的每个字段所具有的字符数组的大小)。请记住,C 字符串必须以 NULL 结尾,因此它们的最大长度实际上是LENGTH - 1.

如果将结构的字段保留为指向 的指针char,则需要动态分配内存,或将指针指向clientData数组的相应字符串(类似于您对文件名所做的操作)。我建议你先获得一些 C 方面的经验,然后尝试实现这两种方法。

现在,您已准备好执行以下操作:

strcpy(client.name, clientData[0]);
...
strcpy(client.traveltype, clientData[3]);

完整的工作示例:

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

#define LINES 4
#define LENGTH 30

typedef struct
{
  char name[LENGTH];
  char phoneNumber[LENGTH];
  char location[LENGTH];
  char traveltype[LENGTH];
} Client;

void readClientData(char *filename, char clientData[LINES][LENGTH]);
void printClient(Client client);

int main(int argc, char *argv[])
{

  char *filename = NULL;
  if(argc > 1)
    filename = argv[1];
  else
  {
    printf("Usage: %s <filename>\n", argv[0]);
  }
  char clientData[LINES][LENGTH];
  readClientData(filename, clientData);

  Client client;
  strcpy(client.name, clientData[0]);
  strcpy(client.phoneNumber, clientData[1]);
  strcpy(client.location, clientData[2]);
  strcpy(client.traveltype, clientData[3]);

  printClient(client);

  return 0;
}

void readClientData(char *filename, char clientData[LINES][LENGTH])
{
  FILE *file = fopen(filename, "r");
  if (file == NULL)
  {
    perror("Error while opening file!");
    exit(1);
  }

  char line[LENGTH];
  int i = 0;
  while (fgets(line, LENGTH, file) != NULL)
  {
    line[strcspn(line, "\n")] = 0;
    strcpy(clientData[i], line);
    i++;
  }
  fclose(file);
}

void printClient(Client client)
{
    printf("%s, %s, %s, %s\n", client.name, client.phoneNumber, client.location, client.traveltype);
}

输出:

Georgioss-MBP:Desktop gsamaras$ cat test.txt 
MegasAlexandros
3335632320
Greece
Cosmos
Georgioss-MBP:Desktop gsamaras$ gcc main.c
Georgioss-MBP:Desktop gsamaras$ ./a.out test.txt 
MegasAlexandros, 3335632320, Greece, Cosmos

PS:我在我的例子中使用了这个:Removing trailing newline character from fgets() input


推荐阅读