Thread: Newbie facing file management

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    6

    Newbie facing file management

    Hi guys,
    I approached the programming world only a week ago, so bear with me for the "stupidity" of my problem.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define M 100
    
    main()
    {
          char str[M],nomef[M];
          FILE *input;
          FILE *temp;
          FILE *output;
          char sep,check;
          int numpar=1,i;
          
          printf("Inserisci il separatore di stringhe:\n");
          scanf ("%c",&sep);
    
          printf("Inserisci il nome del file da aprire:\n");
          scanf ("%s",&nomef);
    
          input=fopen(nomef,"r");
          if (input==NULL) printf("Errore apertura file\n");
    
          temp=fopen("temp.txt","w+");
          if (temp==NULL) printf ("Errore creazione temp\n");
          check=getc(input);
    
          while (check!=EOF)
          {
                if(check==sep) 
                {putc ('\n',temp);
                numpar=numpar+1;}
                else putc(check,temp);
                check=getc(input);
                }     
                      fclose(input);
                      fflush(temp);
    
     for (i=0;i<numpar;i++) fscanf(temp,"%s",&str[i]);
          printf("%s",str[2]);
         
        
          system("PAUSE");
    }
    This code is supposed to create a string-array from a file formatted like so:
    Code:
    string#string1#string2#string3
    Where '#' may by any user-given character. To create the array, I copied the content of the txt file in a temporary "temp.txt", replacing every istance of '#' with a '\n'. Then I used the fscanf procedure to copy the string from temp.txt to str[], using "numpar" as an indicator of how many strings are present in the files.
    The code compiles and executes fine but if I try to access the 'str' array (with a printf procedure, as in the code I posted), the program crashes, and I really can't figure out why.
    I tried using an external function, closing and opening the file (thinking that using "w+" or "r+" mode could lead to collaterals) and using the fgets procedure instead of fscanf, but with no result.
    The temp.txt file is created, and its content are exactly what they should be, so I'm assuming that I either got something wrong with the fscanf, or I messed something up with the file management.
    Thanks for helping out a "newbie" like me

  2. #2
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    1) You should seek to the start of temp.txt before reading it back in the for loop.

    2)
    Code:
    char str[M];
    This is an array of char, str[i] represents a character in the array. I think what you were going for is an array of strings, ie
    Code:
    char str[M][M]; //"str is an array of [arrays of type char]"
    Now str[i] represents a string.

    This makes the printf("%s", str[2]) valid now, as "%s" expects a string (you were passing a char before, which is why the program crashed). The fscanf should be changed to match str's new type as well.
    Consider this post signed

  3. #3
    Registered User
    Join Date
    Jan 2012
    Posts
    6
    Quote Originally Posted by bernt View Post
    1) You should seek to the start of temp.txt before reading it back in the for loop.

    2)
    Code:
    char str[M];
    This is an array of char, str[i] represents a character in the array. I think what you were going for is an array of strings, ie
    Code:
    char str[M][M]; //"str is an array of [arrays of type char]"
    Now str[i] represents a string.

    This makes the printf("%s", str[2]) valid now, as "%s" expects a string (you were passing a char before, which is why the program crashed). The fscanf should be changed to match str's new type as well.
    Thank you for your help
    I used rewind to reset the seeker position, and I added the extra dimension to the str array, but the program still crashes, even if I change the printf type to %c or anything else (just to check if that is the problem),
    I used the same fscanf syntax as before
    Code:
     for (i=0;i<numpar;i++) fscanf(temp,"%s",&str[i]);
    because it should put an "%s"-type string in each 'i' array of the str[M][M] array of string, is that right?
    Thanks

    EDIT: It seems like the compiler had some issues, starting the compiled .exe manually made it work...strange things...now the code reads and prints all the strings properly, but I'm having some trouble creating a procedure to reverse the order of the strings:
    Code:
    void inversione (char vet[M][M],char inv[M][M],int dim)
    {    int i;
         for (i=0;i<dim;i++)
         {
             dim=dim-1;
             strcpy(inv[i],vet[dim]);
             }
    This works only for the first 3 string, afterwards it spits 3 random character instead of strings...thanks again for your help!
    Last edited by Flashgun; 01-15-2012 at 06:01 AM.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Nope.

    stri[i] is now a pointer, not a char. Remove the & from the fscanf() line of code.

    Unless you're going to malloc each strings row of chars for the 2D array, I don't see the point of counting the strings before hand. You could just process them.
    Last edited by Adak; 01-15-2012 at 06:01 AM.

  5. #5
    Registered User
    Join Date
    Jan 2012
    Posts
    6
    Quote Originally Posted by Adak View Post
    Nope.

    stri[i] is now a pointer, not a char. Remove the & from the fscanf() line of code.

    Unless you're going to malloc each strings row of chars for the 2D array, I don't see the point of counting the strings before hand. You could just process them.
    Well, that sure is true...still the code compiled fine with the "&", I guess it is a little flexibile for newbies like me :P. Thanks for the heads up

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is an example of one way to do this, depending on what you want done with the comma (which I use here as the string separator).

    Code:
    #include <stdio.h>
    
    int main(void) {
       FILE *fp;
       int i,r,c,ch;
       char str[100][100];
       char end=',';
       fp=fopen("Edelweiss.txt", "r");
       if(!fp) {
          fprintf(stderr, "Error: file not found or not opened!\n");
          return 1;
       }
       while((c=fgetc(fp)) != EOF) { //show the text in the file
          printf("%c", c);
       }
       rewind(fp);
       printf("\n\n"); 
       r=c=0;                    //now separate each string between the end char, into strings
       while((ch=fgetc(fp)) != EOF) {
          if(ch==end) {
             str[r][c]='\0'; //C's end of string char
             r++;
             c=0;
          }
          str[r][c++]=ch;
       }
       for(i=0;i<=r;i++)
          printf("%s\n",str[i]);
    
       fclose(fp);
       printf("\n\n");
       return 0;
    }
    This is the content of Edelweiss.txt, if you want to use it (it's full of comma's).

    Edelweiss, edelweiss, every morning you greet me.
    Small and white, clean and bright, you look happy to meet me.
    Blossom of snow may you bloom and grow, bloom and grow forever.
    Edelweiss, edelweiss, bless my homeland forever.

    Edelweiss, edelweiss, every morning you greet me.
    Small and white, clean and bright, you look happy to meet me
    Blossom of snow, may you bloom and grow, bloom and grow forever.
    Edelweiss, edelweiss, bless my homeland forever.

  7. #7
    Registered User
    Join Date
    Jan 2012
    Posts
    6
    Thanks for the example, it was very useful, the program now works like a charm .

    I hope it's not a problem if I use this thread to ask another question about a different code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define M 300
    
    int partedec(float f);                                                            /*dichiarazione funzioni*/
    void ordinadec(float v[],int dim);
    
    
    main()
    {
          FILE *input;
          char nomefile[M];
          float array[M],gruppo1[M],gruppo2[M],gruppo3[M];
          
          printf("Inserici il nome del file:\n");
          scanf("%s", &nomefile);
          
          input=fopen(nomefile,"r");
          int i=0,numfloat=0;
          while((fscanf(input,"%f",&array[i]))!=EOF) i++;                           /*creazione array*/
          numfloat=i;                                                              
          printf ("Il vettore letto presenta %d elementi:\n",numfloat);
          for (i=0;i<numfloat;i++) printf("%.2f\n", array[i]);
          
          ordinadec(array,numfloat);
        
          printf("Il vettore ordinato e':\n");
          for(i=0;i<numfloat;i++)
          printf("%.2f\n",array[i]); 
          int j,p,k;
          j=0;k=0;p=0;
          for(i=0;i<numfloat;i++)
          {                                /*divides the array in three groups based on the decimal component of the float numbers*/
                                 if (partedec(array[i])>=0 && partedec(array[i])<=39)         /*.00<=decimal part<=.39*/
                                 {
                                                           gruppo1[j]=array[i];
                                                           j++;
                                 }
                                 if (partedec(array[i])>39 && partedec(array[i])<=69)         /*.39<decimal part<=.69*/
                                 {
                                                           gruppo2[p]=array[i];
                                                           p++;
                                 }
                                 if (partedec(array[i])>69 && partedec(array[i])<=99)         /*.69<decimal part<=.99*/
                                 {
                                                           gruppo3[k]=array[i];
                                                           k++;
                                 }
          }
          
          printf ("Stampa per gruppi:\n");
          printf("-------------------");
          
          printf("Gruppo 1 (parte decimale compresa tra .00 e .39)\n");                       /*prints out the different groups*/
          for (i=0;i<j;i++) printf("%f\n",gruppo1[j]);
          
          printf("Gruppo 2 (parte decimale compresa tra .40 e .69)\n");
          for (i=0;i<p;i++) printf("%f\n",gruppo2[p]);
          
          printf("Gruppo 3 (parte decimale compresa tra .70 e .99)\n");
          for (i=0;i<k;i++) printf("%f\n",gruppo3[k]);
          system("PAUSE");
    }
    int partedec(float f)                                                            /*returns the decimal component of a float number*/
    { int dec;
      f=f*100;
      dec=f;
      do dec=dec-100;
      while (dec>=100);
      return(dec);
    }
    void ordinadec(float v[],int dim)                                                /*sort element by their decimal part*/
    {
         int i, ordinato;
         float temp;
         
         ordinato=0;
         
         while(ordinato==0)
         {
                           ordinato=1;
                           for(i=1;i<dim;i++)
                           {
                                             if(partedec(v[i])<partedec(v[i-1]))
                                             {
                                                    temp=v[i];
                                                    v[i]=v[i-1];
                                                    v[i-1]=temp;
                                                    ordinato=0;
                                             }
                           }
         }
    }
    The code compiles and works fine, but the assignment "gruppo1[j]=array[i]" creates some problem:the numbers are plain wrong, gruppo1 and gruppo2 contains only 0.00 numbers, and gruppo3 contains some crazy random number. The number of elements in each 'gruppo' array is right. What did I mess up this time?
    Thanks for helping out a newbie (again )

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Check the array[i] contents, by printing it out, just before the assignments. Are the values there, OK?

    Next, look at the if() statement to see if it's correct. Add a printf("* ") next to the assignment line of code, to check whether the assignment code is actually being executed.

    Partedec() is returning good values?

  9. #9
    Registered User
    Join Date
    Jan 2012
    Posts
    6
    Quote Originally Posted by Adak View Post
    Check the array[i] contents, by printing it out, just before the assignments. Are the values there, OK?

    Next, look at the if() statement to see if it's correct. Add a printf("* ") next to the assignment line of code, to check whether the assignment code is actually being executed.

    Partedec() is returning good values?
    The array[i] is printed just before, and the values are right. The if statement also seems to work fine, since the j,k and p counters reflects the right number of values (ie,if I have 3 float with the decimal part included between .00 and .39, the j counter will be equal to 3). The printf("*") next to the 3 assignments also returns a number of '*' equal to the numbers of elements of array[i].
    The partedec() function also works, since it is used to sort the array by its decimal parts, and to be sure of it I also did a print cycle of partedec(array[i]), which returned the right values.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Error is in print statements. All three should be using i as the index, not j,p,or k.

    Code:
          printf("Gruppo 1 (parte decimale compresa tra .00 e .39)\n");                       /*prints out the different groups*/
          for (i=0;i<j;i++) printf("%f\n",gruppo1[j]); //use gruppo1[i]
    
    
           
          printf("Gruppo 2 (parte decimale compresa tra .40 e .69)\n");
          for (i=0;i<p;i++) printf("%f\n",gruppo2[p]); //use i not p
           
          printf("Gruppo 3 (parte decimale compresa tra .70 e .99)\n");
          for (i=0;i<k;i++) printf("%f\n",gruppo3[k]);  //use i not k

  11. #11
    Registered User
    Join Date
    Jan 2012
    Posts
    6
    Quote Originally Posted by Adak View Post
    Error is in print statements. All three should be using i as the index, not j,p,or k.

    Code:
          printf("Gruppo 1 (parte decimale compresa tra .00 e .39)\n");                       /*prints out the different groups*/
          for (i=0;i<j;i++) printf("%f\n",gruppo1[j]); //use gruppo1[i]
    
    
           
          printf("Gruppo 2 (parte decimale compresa tra .40 e .69)\n");
          for (i=0;i<p;i++) printf("%f\n",gruppo2[p]); //use i not p
           
          printf("Gruppo 3 (parte decimale compresa tra .70 e .99)\n");
          for (i=0;i<k;i++) printf("%f\n",gruppo3[k]);  //use i not k
    That sure was a stupid mistake, thank you very much, again :P

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Happens to us all, from time to time. You're welcome.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. file management in c help
    By coklat91 in forum C Programming
    Replies: 1
    Last Post: 12-19-2011, 09:23 PM
  2. file management in c
    By Animesh Gaitond in forum C Programming
    Replies: 4
    Last Post: 09-20-2011, 10:28 AM
  3. facing problem with multiple source file porgram.
    By learning"c" in forum C Programming
    Replies: 10
    Last Post: 05-15-2011, 12:08 PM
  4. File Management in C
    By Figen in forum C Programming
    Replies: 6
    Last Post: 01-31-2011, 03:14 PM
  5. need help for file management
    By edesign in forum C Programming
    Replies: 5
    Last Post: 02-08-2008, 11:29 PM