tags:

views:

504

answers:

7

I have a text file that might contain thousands and thousands of numbers(0-9 --> single digit)/characters, like: 13612371029301276312357829031029352131265309182765236728726355263789120938728...(goes on like this)

In C, how do I read them into an array such that each number gets stored separately? I mean after storing, array[0]=1 array[1]=3 array[2]=6... and so on [each number is read individually, this is not a big number but a collection of numbers, entered without any kind of spaces]

I think you get my point by now... How do I store them, if the numbers have no separators??


Here is a rewording:

I have a file that has a very large number of digits in it: ~10^8 digits which do not have any seperators:

the file would look like this: 127389472397413417398410274812371972398748263718238421389410923409234109329413413413241341... and goes on and on

I would like to read the file sequentially - digit by digit. How do I do that in C??

A: 

Just read it as string. Strings in C are basically arrays of characters.

Aziz
I know I can read it as a string... but I cannot possibly declare a string of that size (size == huge). What do you suggest? malloc?malloc fails if the file is, say ~10^8 numbers!!
Lazer
do you need all data to be in the memory at the same time? you can read a segment and process it, then read the next segment .. etc
Aziz
can you explain what type of processing you're doing on this data to see if it's possible to segment it into smaller chunks
Aziz
yeah, i need it in memory... i cant exactly say.. like do some statistics on the data
Lazer
+1  A: 

I'm assuming you don't want the characters but the real values in which case I would do it like this:

  1. Decide on how many numbers you need to read (if the file is all numbers it is just the size of the file).
  2. Create a char array of that size.
  3. read file content into char array.
  4. use a for loop to adjust all values ot their numerical counterpart (i.e. do array[i] = array[i] - '0' in the loop)

Enjoy your new array with all numbers stored in an array as numerical values.

Cellfish
the size of the file might not always be known :(
Lazer
and if the size is known,i know I can read it as a string... but I cannot possibly declare a string of that size (size == huge). What do you suggest? malloc?malloc fails if the file is, say ~10^8 numbers!!
Lazer
If you need all of it in-memory then you are going to have to declare an array of that size. If it is too large to fit in memory, then you need to figure out how you can process the data piece-by-piece and load it in chunks that size as described.
jerryjvl
Right. As Jerryjvl says, you have to "decide" how many numbers to read. Either the complete file or part of it.If you were more specific in what you want to accomplish it might be easier for us to give you advice.
Cellfish
A: 

If you want to get the value of the the first number, you just do

int firstNumber = myString[0] - '0' ;

To get the 5th one you do

int number5 = myString[4] - '0' ;

toto
+1  A: 

To get one character at a time, see fgetc. To put a lot of digits together into a single huge integer, see e.g. GMP. What is it exactly, that you DO want to accomplish?!

Alex Martelli
+2  A: 

Edit: output array of digits ((char)0 to char(9)).

#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>

char* read_file_into_array(char* filename, size_t *array_size)
{
  char *array;
  struct stat st;
  FILE *f;
  size_t i;

  if (stat(filename, &st) != 0) {
    printf("Error reading %s\n", filename);
    return NULL;
  }
  array = malloc(st.st_size+1);
  if (!array) {
    printf("Error allocating memory\n");
    return NULL;
  }
  f = fopen(filename, "rb");
  if (!f) {
    printf("Error opening file\n");
    return NULL;
  }
  if (fread(array, 1, st.st_size, f) != st.st_size) {
    printf("Error reading file\n");
    return NULL;
  }
  fclose(f);
  /* Put numeric value into each field */
  for(i=0; i<st.st_size; i++)
    if (array[i] >= '0' && array[i] <= '9')
      array[i] = array[i]-'0';
    else /* end of digits */
      break;

  /* Provide size to caller */
  *array_size = i;

  return array;
}
Martin v. Löwis
Note that `stat` is non-portable. I would have used `seek()` and `tell()` for portability.
Chris Lutz
Nice. I think he wants the array to contain the numeric value of the char read, not it's ASCII value due.
Liran Orevi
may i ask what you did here? thanks for the code... but I need to know what you did! how exactly this thing would work?
Lazer
@Chris: well, stat(3) is defined by POSIX, so it is portable across "portable systems" :-) It works on Windows as well, so it's probably portable enough for the OP.
Martin v. Löwis
@Liran: ok, I put conversion to digit values into it as well.
Martin v. Löwis
I didn't know `stat()` worked on Windows. I could nitpick and say that `stat(3)` doesn't exist because my stat manpage is in section 2, but it doesn't really matter.
Chris Lutz
eSKay: can you please be more specific? What is the first line in this code that you don't understand?
Martin v. Löwis
Shouldn't the assignment `array[i] = array[i];` actually be `array[i] = array[i] - '0';`?
Jonathan Leffler
If stat fails, you should { perror( filename ); return NULL; } Error messages should be useful, and they belong on stderr.
William Pursell
@Jonathan: thanks, fixed. @William: -1. This is nitpicking, and besides the point.
Martin v. Löwis
+1  A: 

EDIT: What do you mean, "what functions do I use for such large inputs?" The same ones you use for any inputs. Several answers have given you some very nice functions. fgetc() reads characters one-at-a-time from a filehandle - the common trick to convert a digit (stored as a char) to a numeric value is x - '0', where x is the digit character. malloc() can make a dynamically-allocated array of whatever size you want for you, but you'll have to free() it when you're done. To get the file size, use stat() on most Unix-like systems, or for a more portable approach use fseek() and ftell() to find it. These are all standard and fairly common functions, and I don't know what your trouble is if you know C and know these functions.

Chris Lutz
i am afraid your feelings are not correct this time..just tell me the functions you use for such large inputs? fair enough?a) this is not homework.b) i never told you to write any code, you telling me which function to use does not exactly make my application work.Now, can you help?
Lazer
A: 

According to This post, you can allocate really big memories by malloc.

But if the file is really huge and you cannot allocate such a big memory, you can just simply use File Mapping APIs if the OS is Windows.

With File Mapping you can just map a file to memory. After it, you just have a pointer (a char* for example) that points to file data.

Isaac