Thread: I was wondering if anyone could help me with a read and write function

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    2

    Unhappy I was wondering if anyone could help me with a read and write function

    I have been trying to write a program to extract data from a list, but I seem to be having trouble with the last part which seems to be the write and extract functions.


    Here is my program.


    "'
    Code:
    /*
       Description: This program reads two files, stores each in its own array, sorts them and merge both sorted arrays;
       then, writes the content in an output file.
       The program then extracts names of people that live in 2 cities and write them in another output file. 
     */
    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    # include <assert.h>
    void readFile(char** store, char* file);
    void sort(char **array1, int count);
    char ** merge(char **store1, char ** store2, int count1, int count2);//merge page 508
    void extract(char **store);
    void writeFile(char **store, char *file); 
        
      
    
    int main()
    {
        char * array1[200];
        char * array2[200]; 
    
        char buffer[100];
        int i;
        int numLine = 0;
        int numLine2 = 0;
        
        FILE * handle2 = fopen("FILE2.TXT", "r");
        FILE * handle = fopen("FILE1.TXT", "r");// r is for read
    
        if( handle == NULL )//if does not exist will not open 
        {
          printf( "Cannot open input file" );
        return -1;
        }
        if( handle2 == NULL ) {
          printf( "Cannot open input file" );
        return -1;
        }
    
       while (fgets(buffer,100, handle) != NULL) 
       {
    	if (strchr(buffer, '\n') != NULL)
    	   *strchr(buffer, '\n') = '\0';  /* get rid of the '\n' */
    	array1[numLine] = (char *) malloc(strlen(buffer) + 1);
    
    	assert(array1[numLine] != NULL);//if condition is true continue
            strcpy(array1[numLine++], buffer);//copy content of buffer into array1
       }
       fprintf(stdout, "These are the %d strings that were read from the input file\n", numLine);
    /*
       for (i = 0; i < numLine; i++) {
    	printf("%s\n",array1[i]);
        }
    */
       while (fgets(buffer,100, handle2) != NULL) 
       {
    	if (strchr(buffer, '\n') != NULL)
    	   *strchr(buffer, '\n') = '\0';  /* get rid of the '\n' */
    	array2[numLine2] = (char *) malloc(strlen(buffer) + 1);
    
    	assert(array2[numLine2] != NULL);
            strcpy(array2[numLine2++], buffer);
       }
       fprintf(stdout, "These are the %d strings that were read from the input file\n", numLine2);
      /*
       for (i = 0; i < numLine2; i++)
       {
    	printf("%s\n",array2[i]);
        }
       */
        sort(array1, numLine);
        sort(array2, numLine2);
    
        merge(array1,array2, numLine,numLine2);
    
       //fillArray(personArray_1, fpin_1, &count1);
       //fillArray(personArray_2, fpin_2, &count2);
    
       //sort(personArray_1, count1);
       //sort(personArray_2, count2);
    
       //merge(personArray_1, count1, personArray_2, count2, mergedArray);
       //writeToOutputFile(mergedArray, count1+count2, fpout_1);
    
       //filterArray(mergedArray, count1+count2, filteredArray, &filteredCount, "Leominster");
       //writeToOutputFile(filteredArray, filteredCount, fpout_2);
    
       //filteredCount = 0;
       //filterArray(mergedArray, count1+count2, filteredArray, &filteredCount, "Worcester");
      // writeToOutputFile(filteredArray, filteredCount, fpout_2);
    
       /*fclose(fpin_1);
       fclose(fpin_2);
       fclose(fpout_1);
       fclose(fpout_2);
      */
    
       return 0;
    
        printf("The sorted array has these: \n");
    
        for(i = 0; i < numLine; i++)
    	printf("%s", array1[i]);
    
        fclose(handle);
        fclose(handle2);
       
        return 0;
    }
    //function to sort - iterate over the array
    void readFile(char** store, char* file)
    {
        
     }
    void sort(char **words, int count)  {
        int ii, jj, min_index;
        char *temp;
    
    for (ii = 0; ii < count; ii++)
       {
    	printf("%s\n",words[ii]);
        }
    
        for (ii = 0; ii < count; ii++) {
    	min_index = ii;
    	for (jj = ii + 1; jj < count; jj++) {
    	    if (strcmp(words[jj], words[min_index]) < 0 )//if jj < 2nd element switch
    		min_index = jj;
    	}
    
    	/* now swap the pointers at locations ii and min_index */
    	temp = words[min_index];
    	words[min_index] = words[ii];
    	words[ii] = temp;
        }
    
    }
    
    char ** merge(char **store1, char **store2, int count1, int count2)//merge page 508
    {
    char ** temp = malloc(sizeof(char * ) * (count1 + count2));
    
        int i = 0;
        int j = 0;
        int k = 0;
    
        int shortLength = count1 > count2 ? count2:count1;// looks at condition (count1>count2) - if true, shortlenght get value of count2 - if not, then get count1
    
        while(j < shortLength)
        {
          if(strcmp(store1[i],store2[k]) < 0)//comparing one element of 1 array to the element of the other array
          {
    	temp[j] = malloc(strlen(store2[k]) + 1);
    	strcpy(temp[j],store2[k]);
    	k++;
        
          }
          else{
    	temp[j] = malloc(strlen(store1[i]) + 1);
    	strcpy(temp[j],store1[i]);
    	i++;
          }
    	j++;
    
        }
        if(count1 > count2)
        {
          while(i < count1) {
    	temp[j] = malloc(strlen(store1[i]) + 1);
    	strcpy(temp[j],store1[i]);
    	i++;
    	j++;
    	}
        }
         if(count1 < count2)
        {
          while(k < count2){
    	temp[j] = malloc(strlen(store2[k]) + 1);
    	strcpy(temp[j], store2[k]);
    	k++;
    	j++;}
        }
        return temp;
    
    }
    void extract(char **store)
    {
    
    
    
    
    
    }
    
    void writeFile(char **store, char * file)
    {
    
    
    
    
    
    }
    
    "
    Here is my input data

    "Wilson 122461 46 Blossom Street Lowell 50
    Meszaros 347006 81 River Street Ashby 30
    Hicks 617432 101 Grant Avenue Pepperell 31
    Chu 724731 233 Maple Street Leominster 42
    Brown 750977 21 Central Street Ballard Hill 21
    Latona 100854 105 University Avenue Hubbardson 24
    Blake 191553 112 Bay Street Lancaster 23
    Checchi 452759 10 Young Street Sterling 56
    Ratta 826660 106 Seagram Drive Westminster 58
    Chen 767944 212 King Street Boston 65
    Gervasoni 633911 200 Queen Street Cambridge 66
    McMillan 230469 345 Hickory Heights Cr. Worcester 44
    Kong 274170 2345 Westmount Road Lexington 17
    Nash 136108 1 Nelson Road Groton 25
    Wilder 768189 23 Manitoba Avenue Arlington 56
    Planansky 462402 567 Winnipeg Street Cambridge 57
    Mao 411499 34 Kennedy Street Littleton 44
    Chiasson 355591 54 Gardner Street Worcestor 31
    DiNardo 867554 112 Swan Avenue Westford 58
    Dinsmore 134033 56 Bicentennial Avenue Lancaster 43
    Patridge 126953 121 Willard Street Still River 40
    Patterson 650269 2 Old Mill Road Ayer 32
    Carrion 576904 108 Ball Hill Road Worcester 21
    Willey 836548 235 Brookside Road Orange 22
    Carkin 671387 47 Woodside Avenue Hubbardston 24
    Shufelt 597900 750 Riceville Road Templeton 26
    Jolley 236450 181 Rolling Acres Road Northfield 27
    Archambeault 543945 21 Pine Road Otter River 28
    Murray 825073 1 West Main Street Leominster 29
    Munro 697022 136 Harvard Street Acton 30
    Dindal 889771 30 Alice Avenue Lunenburg 32


    Zinkus 539795 59 Hall Road Leominster 78
    Botha 519043 4 Zenith Drive Chesterfield 67
    Welesa 327515 139 Appleton Drive Worcester 78
    Martens 383057 74 Tower Street Belchertown 89
    LeGacy 865356 50 Bay State Road Heath 87
    Zapisek 628784 390 Sheridan Avenue Granby 67
    Maruca 891480 161 Mountain Street Chester 65
    Maruoka 357178 6 E. Princeton Road Granville 54
    Lowe 193384 44 Riley Drive Montague 43
    Zalocha 842285 7D Goldthwaite Road Conway 32
    Plomproy 158569 41 Milk Porridge Drive Leominster 23
    Hanger 909424 38 Cricklewood Drive Warren 34
    Ziemba 774536 44 Singletry Road Pitsfield 45
    Legere 266602 1 Lashaway Drive Charlemont 76
    Nutter 511230 171 Monroe Road Leominster 58
    Pizzarello 132202 18 Ashburnham Drive Allston 70
    Qualigere 795044 21 Park Road Kingston 17
    Kaleskas 508789 30 Barre-Paxton Road Lynn 26
    Hagberg 946167 38 Sunderland Drive Cambridge 38
    Strople 724365 56 Fruit Road Somerville 48
    Marple 273071 80 Murray Avenue Marblehead 59
    Hagopian 334473 90 Hancock Circle Arlington 60
    Parr 463257 20 Leramie Circle Norwell 54
    Polan 526611 45 Whitney Street Melrose 43
    Fox 204224 122 Water Street Worcester 62
    Shubert 488281 123 Second Street Winchester 72
    Giampa 746094 171 Chapel Street Williamstown 56
    Abbott 183472 146 Third Avenue Hingham 37
    Cawley 406982 156 Dolan Road Leominster 37
    Parker 188501 134 Pleasant West Road Holbrook 47
    Taylor 470215 110 Reservoir Road Sharon 56
    Qidwai 500244 20 Knight Road Nahant 19

    "


    I think I need to pass extract with a string, and filter out other elements. I think I also need to loop over the array and check to see if the character in colum x to y are equal to whatever string they pass and if there are add it to another array and then return that array. I am just not sure how to do that.


    I am basically trying to separate the names of the people who live in Worcester,and Leominster from the list.

    If anyone could help me with two last two functions, I would certainly appreciate it.
    Last edited by Wolfman; 04-17-2009 at 10:13 AM. Reason: Change of words.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I think you're building a piano here, Wolfman!

    If you really needed to do some detailed work with this data, the norm and ez way to do it would be to make a struct for it, and load them all into one array of those structs.

    Instead, you have dual arrays, that each need to be malloc'd, sorted, and their contents merged. If you're going to sort and merge them anyway, why not just put them all in one array, and you can then avoid the second call to the sort function, and all of the merge?

    It's not that you're not going to get next door, it's that you're walking around the whole block, to do it.

    The string function strstr() is what you want, I believe. It searches for substrings, inside larger strings, and returns a pointer to the first letter of the substring that it finds.

    Code:
    char * ptr;
    ptr = strstr(BIGstring, littlestring);
    So for each row of the array, you'll have two strstr() calls - one for one town, and one for the other.

    And please, no more piano building. It's true that accuracy is the first patron of programmers, but clarity is the second patron, I do believe. What we have to remember is that the initial code work for a program will be much smaller than the work needed to fix minor bugs, adjust it for changing standards (like wide char sets), add new features to it, decrease it's resources or run-time, etc.

    Throughout it's lifetime, the clarity of the code, and the comments and doc's that are made up to assist you, have to be your guide. Without that clarity and guidance, you can *really* get neck deck in poo.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You really should be doing the sort and the duplicate check at the same time as you read the data in, which will be much more efficient, and also way less code.

    Since both the sort and the duplicate check are based on the name which is the first word in each string, you don't need a struct as Adak claims, but you only need one array.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Apr 2009
    Posts
    2

    Unhappy Could you visually show that?

    Thanks for the help, I really appreciate it.


    Since I am somewhat new to programming in c, I was wondering if you could show me visually in the code exactly what you are talking about.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Did you actually write that code? If so, you should know where it's reading in the data. If not, it's those blocks in main with the fgets calls. Here's a tip: Standard library functions beginning with f usually refer to file operations.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Wolfman View Post
    Since I am somewhat new to programming in c, I was wondering if you could show me visually in the code exactly what you are talking about.
    Oops, I forgot what a pain it is to reorder an array in C. So the BEST WAY might be to use a linked list -- which means a struct, as Adak mentioned. But if you haven't done that before, it will probaly take you at least a few hours to figure it out.

    So, you could still stick with a single array (just read in one file, then the other, and sort it as you are doing (presuming your sort works, of course). You can find the duplicates during the sort because they will be ties (eg, does Parker go before, or after Parker?)

    However, if you are doing this partially to learn C programming, I would really very strongly recommend finding a linked list tutorial that you like (there's lots of them, and also people here every day asking about them) and doing it that way. This is EXACTLY what they are for.

    Actually, since you are using pointer, it might not be so hard to sort as you go. Here's the pseudo code
    Code:
    while (read line from file)
         start at the first element, 
         and keep going until you hit one where this name should be before that one
         then move all the pointers down and insert your name
         if there is a match, print the name to the second file
    I guess that's not even pseudo-code! But you get the point.
    Last edited by MK27; 04-17-2009 at 03:20 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Here's a function that will insert a string into a pointer array:
    Code:
    void insert (char *string, char **list, int len, int pos) {
    	int i;
    	char *tmp=list[pos], *tmp2;
    	list[pos]=string;
    	for (i=pos+1; i<=len; i++) {
    		tmp2 = list[i];
    		list[i]=tmp;
    		tmp = tmp2;
    	}
    }
    where string is the item to insert, **list is the array, len is the current length of the array (not including the new item), and pos is which element to bump down. It does not allocate memory.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. read write lock in C#
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 04-16-2008, 08:49 AM
  2. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Creating a student grade book-how?
    By Hopelessly confused in forum C Programming
    Replies: 5
    Last Post: 10-03-2002, 08:43 PM
  5. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM