Thread: Reading in select chars from a file

  1. #1
    Registered User
    Join Date
    Sep 2012
    Posts
    3

    Reading in select chars from a file

    Basically what I'm trying to do is prompt the user for an input file and read in all of the characters in that file (assume <10000 chars), with the rule that all uppercase be converted to lowercase and all non-letter characters (! ^, ?, @) be excluded. What I have done so far is read in all the characters to a file (including non-letters and uppercase) and now I am trying to figure out how to modify that array so that I have only what I need left. Here is the code for this (used file test.txt for this and only <30 chars but the principle is the same I think. Also output the ascii values to a seperate file to check, files attached):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include<conio.h>
    #include<ctype.h>
    
    
    
    
    int main () {
    
    
        FILE *ifp = fopen("test.txt", "r");
        FILE *ofp = fopen("testvals.txt", "w");
    
    
        int i, size, count;
        char chars[30];
    
    
        //This if statement I don't really understand, it was something I picked up from the internet
        //and it seems to work
    
    
        if (fseek (ifp, 0, SEEK_END) == 0) {
            size = ftell(ifp);
            fseek (ifp, 0, SEEK_SET);
    
    
          }
    
    
        int ascii[size];
    
    
        //Scan all the characters into an array
    
    
       for (i=0; i<size; i++) {
    
    
            fscanf(ifp, "%c", &chars[i]);
    
    
        }
        printf("\n");
    
    
        //convert all chars in arraay to thier ASCII values
    
    
        for (i=0; i<size; i++) {
    
    
        ascii[i] =toascii(chars[i]);
    
    
        }
    
    
            for (i=0; i<size; i++) {
    
    
            fprintf(ofp, "ASCII value %c= %d\n", chars[i], ascii[i]);
    
    
        }
    
    
    
    
    
    
    
    
    /*   This is my idea if what I might need to do next, but I dont know how
        to "skip" an array index without leaving it blank, is it possible to
        delete an index?
    
    
    
    
        for (i=0; i<size; i++) {
            if (ascci[i] >= 0 && ascii[i]<=64) {
            count+=1;
    
    
            }
            else if (ascii[i] >= 91 && ascii[i]<= 96) {
    
    
            count+=1;
            }
    
    
            else {
    
    
            ascii[i] = final[i];
    
    
            }
    
    
    
    
    
    
        }
    */
    
    
    
    
    //   printf("size = %d", size);
    
    
    
    
        fclose(ifp);
        fclose(ofp);
    
    
        system("PAUSE");
        return (0);
    
    
    }
    I included in the code comments my ideas about where to go next, but there could be a much better way to do this (hence why I'm here haha) and I'm stuck where I'm at. Thanks in advance for the help!
    test.txt
    testvals.txt
    test.c

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    Easier than deleting an index is skipping an index. It's easier to understand with two different arrays, but you can do it in-place. Instead of focusing on getting rid of what you don't want, verify that the character is something that you want to keep. If you do, then copy it to the destination array. If not then you will skip that character in the source string and leave the destination array alone. As you proceed through the source string, you thus "remove" what you don't want. To do it in-place, you need to overwrite characters that you don't want, and terminate or resize the array when you are done.
    Last edited by whiteflags; 09-30-2012 at 03:04 PM.

  3. #3
    Registered User
    Join Date
    Sep 2012
    Posts
    3
    Quote Originally Posted by whiteflags View Post
    Easier than deleting an index is skipping an index. It's easier to understand with two different arrays, but you can do it in-place. Instead of focusing on getting rid of what you don't want, verify that the character is something that you want to keep. If you do, then copy it to the destination array. If not then you will skip that character in the source string and leave the destination array alone. As you proceed through the source string, you thus "remove" what you don't want. To do it in-place, you need to overwrite characters that you don't want, and terminate or resize the array when you are done.
    But how do I know how large to make the destination array? That was sort of my idea with the "count+=1;" code in the if statement (int count tracks how many non-letter chars you have). As for keeping only the characters you want to keep, would you use a double for loop or something for this?

  4. #4
    Registered User
    Join Date
    Sep 2012
    Posts
    357
    You don't need to keep the data around.

    Imeagine I had a bag full of balls of assorted colors and I wanted to put all red and pink balls in another bag and discard all balls of different colors.
    I only need the original and destination bags ... and one hand

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    The resulting array cannot be larger than the original array, because you are removing characters. So "size" would actually be excellent for both arrays.

    Only one loop is required. The code needs to check each character once, and decide to copy or not as a result. That can be done with an if-else.

  6. #6
    Registered User
    Join Date
    Sep 2012
    Posts
    3
    Quote Originally Posted by qny View Post
    You don't need to keep the data around.

    Imeagine I had a bag full of balls of assorted colors and I wanted to put all red and pink balls in another bag and discard all balls of different colors.
    I only need the original and destination bags ... and one hand
    Sorry I'm not sure I follow, am I on the right track with this peice of code?

    Code:
    for (i=0; i<size; i++) {        if (ascci[i] >= 0 && ascii[i]<=64) {
            count++;
    
    
            }
            else if (ascii[i] >= 91 && ascii[i]<= 96) {
    
    
            count++;
            }
    
    
            else {
    
    
            ascii[i] = final[i];
    
    
            }
    


    This will traverse array ascii[], check if the ascii val is between 0 and 64 (non-letter vals), increment count if it is then continue. The else if's check for ascii vals between 91 and 96 (incrementing count again if it is) as well as vals between 123 and 255, accounting for all possible assci vals. Then the else statment tells it to assign final[i], but i think there is an error in that logic somewhere

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    >> ascii[i] = final[i];

    To assign to final[i], you need to switch that around. The destination variable should always be on the left-hand side.

    I think you are on the right track.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem Reading from console using select
    By 86.mahendra in forum Networking/Device Communication
    Replies: 1
    Last Post: 11-25-2011, 11:12 PM
  2. Reading chars from file into array
    By AJOHNZ in forum C++ Programming
    Replies: 1
    Last Post: 08-19-2009, 03:37 PM
  3. reading in chars from file
    By AJOHNZ in forum C++ Programming
    Replies: 2
    Last Post: 08-16-2009, 12:50 AM
  4. reading and writing unsigned chars from a file
    By yahn in forum C++ Programming
    Replies: 17
    Last Post: 02-20-2006, 09:42 PM
  5. reading from pts's by select
    By fnoyan in forum Linux Programming
    Replies: 0
    Last Post: 12-16-2005, 04:02 AM