简体   繁体   中英

Reading lines from a text file into a pointer array of strings.

I've been all over Stack Exchange and I haven't seen any threads that answer my question, but please direct me to one if I missed it.

I'm using C.

So I've got a text file where the first nine lines are labels (with spaces), and each line after that is nine pieces of data that correspond to those labels. I've declared a pointer array:

char * cp_labels[9];

And I'm trying to read each of the first 9 lines from the text file into each element of the array.

The text file looks like this:

Et jet 1
Et jet 2
Et jet 3
Eta 1
Eta 2
Eta 3
Met
Ht
Njet
(double) (double) (double) (double) (double) (double) (double) (double) (double)
(double) (double) (double) (double) (double) (double) (double) (double) (double)
(double) (double) (double) (double) (double) (double) (double) (double) (double)
...

And so on. Right now I'm just trying to make sure the strings are storing in the array correctly. I'm working with this:

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

int main ()
{
  FILE *fp_data;
  fp_data = fopen("data.dat", "r");
  char *cp_labels[9];

  for (int l=0;l<9;l++)
    {
      fscanf(fp_data, "%s", cp_labels[l]);

      printf("%s\n", cp_labels[1]);
    }

  return 0;
}

The problem I'm running into is that

fscanf

is treating each string as a string (as it should) and I'm trying to get it to treat each line as a string.

fgets 

is an option I'm aware of, but I can't seem to get it to work with a pointer array of strings. Any ideas? I'm doing it this way because I want to be able to use the elements of this array as labels later.

This code does the job:

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

int main(void)
{
    const char filename[] = "data.dat";
    FILE *fp = fopen(filename, "r");
    if (fp == 0)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", filename);
        return 1;
    }

    char *cp_labels[9];
    char buffer[4096];

    for (int i = 0; i < 9 && fgets(buffer, sizeof(buffer), fp) != 0; i++)
    {
        buffer[strcspn(buffer, "\n")] = '\0';
        cp_labels[i] = strdup(buffer);
    }

    for (int i = 0; i < 9; i++)
        printf("%d: [%s]\n", i, cp_labels[i]);

    for (int i = 0; i < 9; i++)
        free(cp_labels[i]);

    fclose(fp);
    return 0;
}

Sample output (from your data file):

0: [Et jet 1]
1: [Et jet 2]
2: [Et jet 3]
3: [Eta 1]
4: [Eta 2]
5: [Eta 3]
6: [Met]
7: [Ht]
8: [Njet]

This uses fgets() because it is easy to use and get right. Using getline() is equally easy:

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

int main(void)
{
    const char filename[] = "data.dat";
    FILE *fp = fopen(filename, "r");
    if (fp == 0)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", filename);
        return 1;
    }

    char *cp_labels[9];
    char *buffer = 0;
    size_t buflen = 0;

    for (int i = 0; i < 9 && getline(&buffer, &buflen, fp) != -1; i++)
    {
        buffer[strcspn(buffer, "\n")] = '\0';
        cp_labels[i] = buffer;
        buffer = 0;
        buflen = 0;
    }
    free(buffer);

    for (int i = 0; i < 9; i++)
        printf("%d: [%s]\n", i, cp_labels[i]);

    for (int i = 0; i < 9; i++)
        free(cp_labels[i]);

    fclose(fp);
    return 0;
}

That produces the same output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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