0

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??

Lance Roberts
  • 22,383
  • 32
  • 112
  • 130
Lazer
  • 90,700
  • 113
  • 281
  • 364
  • By "number" I think you mean "digit." – Chris Lutz Sep 06 '09 at 04:16
  • 1
    people who suggest using strings, please say how do I declare the string, if the size of the file (assuming that it is known) is something like ~10^8 numbers? – Lazer Sep 06 '09 at 04:27
  • You might try asking a question like 'How do I declare an array of size larger than maxint?' or something like that. Instead of dwelling on things you already know, like reading the characters in, ask specific questions on the hard stuff. – Lance Roberts Sep 06 '09 at 04:44

8 Answers8

2

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
  • 854,459
  • 170
  • 1,222
  • 1,395
2

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
  • 124,830
  • 17
  • 198
  • 235
1

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
  • 2,202
  • 18
  • 20
  • the size of the file might not always be known :( – Lazer Sep 06 '09 at 04:22
  • 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 Sep 06 '09 at 04:25
  • 2
    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 Sep 06 '09 at 04:38
  • 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 Sep 06 '09 at 04:58
1

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
  • 73,191
  • 16
  • 130
  • 183
  • 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 Sep 06 '09 at 05:01
0

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

Aziz
  • 20,065
  • 8
  • 63
  • 69
  • 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 Sep 06 '09 at 04:26
  • 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 Sep 06 '09 at 04:42
  • 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 Sep 06 '09 at 04:53
  • yeah, i need it in memory... i cant exactly say.. like do some statistics on the data – Lazer Sep 06 '09 at 05:48
0

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
  • 880
  • 11
  • 21
0

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.

Community
  • 1
  • 1
Isaac
  • 2,332
  • 6
  • 33
  • 59
0

To create a string of a large size you need to create a Link List. A link list is a set of structs where the last section is a pointer to another struct. This will allow you to store larger strings that will reside in both memory and hard drive space, so you won't run out of space due to memory problem.

Paul
  • 1
  • A "linked list" (not "link list") is one possible solution. However, having one node for each character would have *a ton* of overhead. Perhaps each node could hold N digits. However, a linked list has no special traits that have anything to do with memory/hard drive space. Simply `malloc()`-ing a bunch of large blocks could also end up using virtual memory greater than the physical memory of the system. – Jonathon Reinhart Nov 05 '12 at 06:11