3

I have a very simple problem. I need to read in the contents of a file into a char array in C. The file will always be formatted as two columns of letters, e.g.:

A B
B C
E X
C D

Each letter represents a vertex on a graph, which I'll be dealing with later. I've learned programming using C++ and Java, but I'm not extraordinarily familiar with C specifically.

What's causing the problem that I can't figure out is the fact that the file is multiple lines long. I need each letter to occupy a slot in the array, so in this case it'd be: array[0] = 'A', array[1] = 'B', array[2] = 'B', array[3] = 'C' and so on.

Eventually I'll need the array to not include duplicates, but I can handle that later. I wrote a program earlier this semester that read in a single line of ints from a file and it worked fine, so I copied most of that code, but it's not working in this case. Here's what I have so far:

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

int main (int argc, char *argv[])
{
   int i;
   int count = 0;
   char * vertexArray;
   char ch = '\0';

// open file
   FILE *file = fopen( argv[1], "r" );

// count number of lines in file
   while  ((ch=fgetc(file)) != EOF)
        if(ch == '\n') count++;

// numbers of vertices is twice the number of lines
   int size = count*2;

// declare vertex array
    vertexArray = (char*) calloc(size, sizeof(char));

// read in the file to the array
   for(i=0; i<size; i++)
        fscanf(file, "%c", &vertexArray[i]);

// print the array
   for(i=0; i<size; i++)
        printf("%c\n", vertexArray[i]);

   fclose( file );
}

I know I need to be testing for the file opening and being read properly and whatnot, but I'll add that in later. Just trying to read in the array for now. My output in this case is 8 blank lines. Any help would be great!

Echilon
  • 10,064
  • 33
  • 131
  • 217
DaBurto
  • 43
  • 2
  • 5

4 Answers4

1

When you loop through the file to count the number of lines, the file pointer is already sitting at EOF, so you won't be reading anything into your array. At best it'll be the same value as your last character, but it'll probably show you a segmentation fault.

What you want to do is

rewind(file);

before you

//read file into the array

then you'll be starting at the beginning of the file. Also, I'm not sure how fgetc handles end of lines, since there's usually a trailing '\0' sitting there. Another way you could do this is to use fscanf like so

i = 0;
while (!feof(file)){
   fscanf(file, "%c %c", &vertexArray[i], &vertexArray[i+1]);
   i++;
}

The function feof(FILE *) checks if the EOF flag has been set, and stops once you hit EOF.

UPDATE: I think if you define ch as int ch, it should work. Have a look at this thread.

This is the code that worked for me :

int main (int argc, char *argv[])
{
    int i;
    int count = 0;
    char * vertexArray;
    int ch, size;

    FILE *file;
    file = fopen(argv[1], "r");

    while ((ch = fgetc(file) != EOF))
       count++;

    size = count*2;
    vertexArray = (char*) calloc(size, sizeof(char));
    rewind(file);

    for(i=0; i<size; i++)
       fscanf(file, "%c ", &vertexArray[i]);

    for(i=0; i<size; i++)
       fprintf(stderr, "%c\n", vertexArray[i]);

    fclose(file);

}

NEW EDIT Notice the space after fscanf(file, "%c ", &vertexArray[i]);. That tells C that you want to skip all the white spaces after reading the character. Without the space, it'll read the whitespace as a character as well. This should fix it.

Community
  • 1
  • 1
Kitchi
  • 1,874
  • 4
  • 28
  • 46
  • Your suggestion seems like it should work, but when I try it I get a segmentation fault. It seems to do with rewind(file). I also tried fseek(file, 0, SEEK_SET) but same thing. I can't see why I'm getting this. – DaBurto Nov 15 '12 at 16:13
  • Sorry, I haven't actually tried this to tell you if it worked, I should've mentioned that. I'll _actually_ try it out and let you know. – Kitchi Nov 15 '12 at 16:21
  • For some reason it seems to be reading extra lines? With this code my count = 20 making size = 40, where they should be 4 and 8 (or 9? to include NULL terminator? not sure) respectively. – DaBurto Nov 15 '12 at 17:41
  • YES! That worked perfect, thank you so much for the excellent help!! I was getting beyond frustrated, haha – DaBurto Nov 15 '12 at 19:03
0

fgetc advance the file position indicator. You need to seek back to 0 with your current code, or read lines without caring about the number of lines.

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
0

When you start reading in the data, you've already exhausted the file with the counting of the lines. You must rewind or re-open the file.

unwind
  • 391,730
  • 64
  • 469
  • 606
0

You need to add fseek(file, 0, SEEK_SET);

Your code have to look:

//Some stuff

// declare vertex array
vertexArray = (char*) calloc(size, sizeof(char));

fseek(file, 0, SEEK_SET);
// read in the file to the array
   for(i=0; i<size; i++)
        fscanf(file, "%c", &vertexArray[i]);

//Some stuff
ST3
  • 8,826
  • 3
  • 68
  • 92