简体   繁体   English

如何将文件中的行读入字符串数组?

[英]How to read lines from file into an array of strings?

#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);
}

Coming from a pythonista world I'm a bit confused how things are working here.来自 pythonista 世界,我有点困惑这里的工作方式。 It is clear that I can't just add lines to the list, nor can acces the lines the way I do to initialize the client struct.很明显,我不能只向列表中添加行,也不能像初始化客户端结构那样访问这些行。

Maybe I should just use a char *clientData[] , but don't know how.也许我应该只使用char *clientData[] ,但不知道如何。

To copy C strings, you need to use:要复制 C 字符串,您需要使用:

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

from the Standard C String Library, string.h .来自标准 C 字符串库string.h

However, notice, than unlike Python (your background), indentation does not define the body of the loop, you need to use curly brackets!然而,通知,比Python的不同(你的背景),压痕没有定义的循环体,你需要使用大括号!

So, you need to do this:所以,你需要这样做:

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

Without the curly brackets, only the first immediate line of code will be considered to be the body of the loop.如果没有大括号,只有第一行代码会被认为是循环体。 So, in the example above, the body of the loop - if we did not use curly brackets - would be only the call to the method for copying strings, and the increment of the counter would not be part of the loop!所以,在上面的例子中,循环体——如果我们使用大括号——将只是对复制字符串方法的调用,并且计数器的增量不会成为循环的一部分!


You need to define, or just declare a method before using it, which you didn't do in your example.您需要在使用之前定义或声明一个方法,而您在示例中没有这样做。


Since you only need one client, you do not need a pointer, you can simply create one, by doing Client client;既然你只需要一个客户端,你就不需要指针,你可以简单地创建一个,通过做Client client; . .

In order to keep it simple, use the knowledge you gathered from reading this answer so far, and do define the maximum length of the strings (that is the size of the arrays of characters every field of your struct gets to have).为了简单起见,请使用到目前为止从阅读此答案中收集到的知识,并定义字符串的最大长度(即结构的每个字段所具有的字符数组的大小)。 Remember, that C strings have to be NULL terminated, so, the maximum length of them is actually LENGTH - 1 .请记住,C 字符串必须以 NULL 结尾,因此,它们的最大长度实际上是LENGTH - 1

If you keep the fields of the struct as pointers to char , then you'd need to dynamically allocate memory, or set the pointer point to corresponding string of the clientData array (similarly to what you did for the file name).如果将结构的字段保留为指向char指针,则需要动态分配内存,或将指针设置为指向clientData数组的相应字符串(类似于您对文件名所做的操作)。 I suggest you get some experience in C first, and then try implementing these two approaches.我建议您先获得一些 C 方面的经验,然后尝试实现这两种方法。

Now, you are ready to do:现在,您已准备好执行以下操作:

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

Complete working example:完整的工作示例:

#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);
}

Output:输出:

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: I used this in my example: Removing trailing newline character from fgets() input PS:我在我的例子中使用了这个: Removing trailing newline character from fgets() input

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM