Thread: New programmer - reading in a large expression

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    9

    New programmer - reading in a large expression

    Hi i need to read an expression that is very large and stuff it in a string. I dont know how long the expression is but it can be over 1 million characters.
    I need to use an array based solution. Here is what I have so far:

    Code:
    #include <stdio.h>
    #include <string.h>
    int main(int argc, char **argv) {
      char* a; int i=0; int c;
      while ( (c = getchar()) != '\n' ) {
        a[i] = c;
        i++;
      }
      a[i]='\0';
      int N = strlen(a);
      printf("&#37;d",N);
      return 0;
    }
    I get a segmentation fault. I also tried:

    Code:
    #include <stdio.h>
    #include <string.h>
    int main(int argc, char *argv[]) {
      char* a;
      scanf("%as", &a); 
      int N = strlen(a);
      printf("%d",N);
      return 0;
    }
    This way only reads the first character when there is a very large expression. Any help would be good.
    Last edited by 9988776655; 12-08-2007 at 05:46 AM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You need to allocate memory with malloc or calloc and store it in a char* pointer before using it. Don't overwrite more memory than you requested.
    Also, scanf can be unsafe to read strings with. Read my signature for more information.
    Also note that you're using a while loop and i = 0, and never increases, so you're overwriting the same data in the memory all the time.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    9
    I am still unsure of why there is a segmentation fault in my first program. How do I use malloc when I cant count how many characters are meant to be in my string? I looked at the information in your signature and it was unhelpful to me. I tried:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #includd <string.h>
    int main(int argc, char **argv) {
      char* a; int i=0; int c; int N;
      while ( (c=getchar()) != '\n') {
        a = malloc(sizeof(int));
        a[i] = c;
        i++;
      }
      N = strlen(a);
      printf("&#37;d",N);
      return 0;
    }
    Nothing ever goes into my string
    Last edited by 9988776655; 12-08-2007 at 06:42 PM.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Of course not. Think about what you're doing.
    On every loop you...

    malloc memory to a, overwriting old memory (for ONE int, that is element 0).
    assign to a[0, 1, 2, 3, etc...]
    Increment I.

    See the problem?
    You allocate memory for ONE int and yet you write SEVERAL int, writing to unowned memory.
    And since you keep overwriting the value of the old pointer without freeing it first, you're creating several memory leaks. Congratulations.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    ...you're creating several memory leaks. Congratulations.
    Is it me or was this sarcastic ?

    You can try using realloc. And you should check if it returns NULL before making any operation on the pointer returned (else, you'll have something you know well, a segmentation error)

    But this will be rather slow if you use realloc every time you read a character. Would be better to realloc memory every 100 characters (or more) you read in. Or you could start by allocating a certain amout of memory, let's say for X characters, than if the number of characters you read is bigger, you reallocate some, etc...

    But why do you need those characters to be stored in a string, ie what's the problem you are trying to resolve ?

    Another solution would be to use a file to store the characters, since you can acces elements in file quite the "same way" (ie. direct acces) than in memory. Can be useful in some situations where you don't need all the elements at a time in memory. But you need somehow a good knowledge if you want to do something who makes sense.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    9
    This is my latest try: I dont know if its right though
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char **argv) {
      int i; int c; int N; char* temp;
      char* a = malloc(sizeof(char) * 100);
      if(!a) {
        printf("Allocation Error\n");
        exit(1);
      }
      for (i = 0; (c=getchar()) != '\n'; i++) {
        a[i] = c;
        if (i &#37; 100 == 0) { //every 100 characters realloc memory
          temp = realloc(a, strlen(a) + 101);
          if(temp != NULL){
             a = temp;
          }
        }
      }
      a[i] = '\0';
      N = strlen(a);
      printf("%d",N);
      return 0;
    }
    Last edited by 9988776655; 12-08-2007 at 08:20 PM.

  7. #7
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    That code dosn't give you want you want. perhaps that wont even compile. What you have to do allocate memory using malloc. And fi you want to extend the allocated memory then use realloc not just staright way using it.

    So go and allocate memory for temp using malloc
    Code:
    char *temp = malloc(sizeof(char) * 100);
    And now if your want 100 more bytes do this
    Code:
    char temp1 = realloc(temp, strlen(temp) + 101);
    if(temp != NULL)
       temp = temp1;
    Please make sure u check the return vallue of malloc.

    ssharish

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    9
    I made the changes to the previous post. Am I creating any memory leaks now?
    Previously, Elysia said:

    you're creating several memory leaks. Congratulations.
    The program itself seems to work alright. Can anyone suggest improvements?
    Last edited by 9988776655; 12-08-2007 at 06:03 PM.

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    9
    I found out why my second program wont work.
    Code:
    scanf("&#37;as", &a);
    It stops reading when there is a space!
    Will gets work with my large input?
    Last edited by 9988776655; 12-08-2007 at 06:46 PM.

  10. #10
    Beautiful to C Aia's Avatar
    Join Date
    Jun 2007
    Posts
    124
    Use fgets() for string or fgetc() for a single character
    Last edited by Aia; 12-08-2007 at 08:17 PM. Reason: Adding fgetc option

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    242
    scanf is dangerous.
    Your program can be overflowed and this way you can arrange, without even knowing, a really big mess.
    As Aia said, use fgets.
    fgets works this way.
    Code:
    fgets(var, maximumNum, stdin); // This is an example how to get the user's input;
    e.g:
    Code:
    char name[10];
    printf("Enter your name please:\n");
    fgets(name, 10, stdin);
    printf("&#37;s", name); // or fputs(name, stdout); or many other ways, lol
    EDIT: Ahh! fgets & fputs works only for strings.

    and just for the record, gets is also dangerous.

  12. #12
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    I'm curious to know...

    1. Where does the input come from? Is it from the keyboard ? Is it from a file ?
    2. When you say "a very large expression", what does that means exactly. What kind of input your program is suposed to work on ? What are those "expression" ?
    3. Which treatment do you have to do on that expression, ie why do you need absolutely an array.

    Maybe we'll be able to give you more help knowing that. Because if your only goal is to take input from keyboard, store it in an array, well, here's some working code

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define NB_ELEM_INI 100000
    #define INCREM 1000
    
    int main()
    {
        char c;
        char *tab;
        size_t tailleTab = NB_ELEM_INI;
        size_t cardTab = 0;
    
        tab = malloc(tailleTab * sizeof(char));
        if (tab == NULL)
        {
            printf(" Error: not enough memory\n");
        }
    
        else
        {
            while (((c = getchar()) != '\n') && (tab != NULL))
            {
                if (cardTab == tailleTab)
                {
                    tailleTab = tailleTab + INCREM;
                    tab = realloc(tab, tailleTab);
                    if (tab == NULL)
                    {
                        printf(" Error: not enough memory\n");
                    }
    
                    else
                    {
                        tab[cardTab] = c;
                        cardTab++;
                    }
                }
    
                else
                {
                    tab[cardTab] = c;
                    cardTab++;
                }
            }
    
            // Append the zero
            if (tab != NULL)
            {
                if (cardTab == tailleTab)
                {
                    // Insert the '\0' on the last character read since i'm lazy
                    cardTab--;
                }
    
                tab[cardTab] = '\0';
            }
    
            // You might think freeing the memory here
            free(tab);
        }
    
        return 0;
    }
    Didn't test. Should work. Variables name are mostly in french. By the way this should be somehow inefficient, but it should work. There's better way to do so.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by 9988776655 View Post
    I made the changes to the previous post. Am I creating any memory leaks now?
    Previously, Elysia said:
    The program itself seems to work alright. Can anyone suggest improvements?
    A memory leak happens when you ovewrite a pointer where you've allocated memory without freeing it. Since you allocate 100 bytes at the beginning and reallocate it later, and if it didn't fail, assign the new memory block to the a pointer. So now there's no danger of overwriting the boundary.
    Still, you aren't freeing the memory after the loop, so you do have a subtle memory leak bug left. Call free to release any memory allocated with malloc when you don't need it anymore.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by 9988776655 View Post
    Hi i need to read an expression that is very large and stuff it in a string. I dont know how long the expression is but it can be over 1 million characters.
    Over 1 million characters!? Holy crap!
    Do you have a million monkeys sitting infront of a million keyboards or something?

    Most programs aren't even a million characters, let alone a single expression... What on earth could you possibly be doing?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [Large file][Value too large for defined data type]
    By salsan in forum Linux Programming
    Replies: 11
    Last Post: 02-05-2008, 04:18 AM
  2. Optimizing large file reading
    By Enahs in forum C++ Programming
    Replies: 2
    Last Post: 11-19-2005, 03:51 AM
  3. Computing Large Values
    By swbluto in forum C++ Programming
    Replies: 8
    Last Post: 04-07-2005, 03:04 AM
  4. Help! Program to evaluate expression...
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 02-19-2002, 06:20 AM
  5. Reading Large Files!!!
    By jon in forum Windows Programming
    Replies: 1
    Last Post: 09-09-2001, 11:20 PM