Thread: Need some help to read from a file

  1. #1
    Registered User
    Join Date
    Jun 2012
    Location
    Madrid
    Posts
    9

    Need some help to read from a file

    I am a bit lost trying to read stuff from a file which has been written before.
    I want my program to open an already existing file which has my friends ‘names and numbers written like this:

    friend1-7372384729
    friend2-9374628202

    The input to the program will be my friend´s name and the output after searching in the file will be his number.
    I have studied these functions: fscanf, fgetc, and fgets and tried to use them but it isn’t working , I must be doing something wrong.
    Here is the code: I hope it isnt as awful as I think it is
    Code:
    #include <stdio.h>
    #include <string.h>
    #define d 25
    
    
    int main(){
    char nom[d],*a; int i=0,n;
    FILE *f;
    printf("\nIntroduce your friend´s name: ");
    gets(nom);
    if((f=fopen("telefonos.txt","r"))==NULL) printf("\nError oppening the file");
    
    while((i!=EOF)&&(a!=nom))   i=fscanf(f,"%s",a); 
    if(i==EOF) {printf("\nIt seems you haven´t got %s number registered",nom);return 0;}
    printf("\n%s number is: %d", *a, n);
    fclose(f);
    return 0;}

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    you can practice how fscanf works by writing a simple test program that declares a string "friend1-7372384729" and using sscanf on it to extract the data you are looking for. sscanf works the same way fscanf works except on a string. doing it that way gets rid of the file reading stuff that is a separate problem.

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You're doing a few things wrong.
    1. You can't compare strings like a != nom. You must use
    Code:
    strcmp(a, nom) != 0
    2. You can't read a string into a pointer with no memory allocated to it. Instead of declaring char *a it should be
    Code:
    char a[d] = {0}
    (Initializing it to zeros makes the first strcmp work properly.)
    3. You're reading the whole string (e.g., friend1-7372384729) into 'a' whereas you want only the name in 'a' and the number in 'n'. It may be best to declare 'n' as char n[d] instead of an int (since it may overflow an int). You could then read 'a' and 'n' something like this:
    Code:
    i = fscanf(f, "%[^-]-%s", a, n);
    Other points:
    * We generally discourage the use of gets in favor of fgets. gets can lead to buffer overflows since it puts no restriction on the size of the string read. What would happen if the user entered a 100 characters where your char array has room for only 25? fgets allows you to limit the number of chars read.
    * If the fopen doesn't work you don't just want to print an error message and then continue normal processing; you want to exit the program (or deal with the error in some other way).
    * 'd' is a bad name for a defined constant. How about SIZE. Obviously some of your other names are not good, like 'a' and 'n'.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Jun 2012
    Location
    Madrid
    Posts
    9
    thanks for taking the time to look at it, I´ve changed a few things you told me but some things are new and I don´t really understand how they work foe example what kind of format is %[^-]
    I´ve done changes but still isn´t working:
    Code:
    #include <stdio.h>
    #include <string.h>
    #define SIZE 25
    
    
    int main(){
    char str1[SIZE]={0},str2[SIZE]={0},n[8]={0}; int i=0,j=0;
    FILE *f;
    printf("\nIntroduce your friend´s name: ");
    gets(str1); puts(str1);
    if((f=fopen("telefonos.txt","r"))==NULL)  {printf("\nError oppening the file. The program has finished"); return 0;}
    while((i!=EOF)&&((strcmp(str1, str2)) != 0))  {i=fscanf(f,"%[^-]-%s", str2[j], n[j]);
    											   ++i; ++j;} 
    if(i==EOF) {printf("\nIt seems you haven´t got %s number registered",str1);return 0;}
    printf("\n%s number is: %d", str2, n);
    fclose(f);
    return 0;}
    I have also tried this:
    Code:
    i=0; strname{0};
    while (strname[i]!='-') {strname[i]=fgetc(f);++i;}
    if((strcmp(a, nom)) != 0)
    {
      j=0; strnumber={0};
      while(strnumber[j]!='\n'){strnumber[j]=fgetc(f);++j;}
    }
    but I think that has to be done for every line in the file but I don´t know how to express that in C.
    Anyway I´ll be glad if you can keep on helping me

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Oh man, your code is horrendous to look at. It's very difficult to see what's going on with everything squashed together. Can you format it a bit better? You'd get more people willing to help out if you did so.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    Registered User
    Join Date
    Jun 2012
    Location
    Madrid
    Posts
    9
    Quote Originally Posted by hk_mp5kpdw View Post
    Oh man, your code is horrendous to look at. It's very difficult to see what's going on with everything squashed together. Can you format it a bit better? You'd get more people willing to help out if you did so.
    Quite true.
    Code:
    #include <stdio.h>
    #include <string.h>
    #define SIZE 25
    
    
    int main(){
    char str1[SIZE]={0},str2[SIZE]={0},n[8]={0}; 
    int i=0,j=0;
    FILE *f;
    
    
    printf("\nIntroduce your friend´s name: ");
    gets(str1);
    
    
    if((f=fopen("telefonos.txt","r"))==NULL) 
    {
        printf("\nError oppening the file. The program has finished");
    	return 0;
    }
       
       /*This loop is where the problem must be*/
    while((i!=EOF)&&((strcmp(str1, str2)) != 0))  
    {
       i=fscanf(f,"%[^-]-%s", str2[j], n[j]);
       ++i;
       ++j;
    } 
    
    
    if(i==EOF)
    {
       printf("\nIt seems you haven´t got %s number registered",str1);
       return 0;
    }
    printf("\n%s number is: %s", str2, n);
    fclose(f);
    return 0;}

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    1. %[^-] means 'match any characters except a '-' but that will copy the first field, which in your example is a name, to str2. fscanf and sscanf copy the data in order of the field specs.
    2. 'n' need to have enough room for the entire number and a zero delimiter. right now you only have room for 8 characters in 'n'.

    try this
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main()
    {
            const char *s = "friend1-7372384729";
            char a[32];
            char b[11];
            sscanf(s,"%[^-]-%s",a,b);
            printf("%s %s\n",a,b);
        return 0;
    }

  8. #8
    Registered User
    Join Date
    Jun 2012
    Location
    Madrid
    Posts
    9
    Thanks to all of you. After playing around a bit with dmh2000 example I started to undestand how it works, but I think there still is a problem when I use this:
    Code:
    while((i!=EOF) && ((strcmp(str1, str2)) != 0))  
    {
            i=fscanf(f,"%[^-]-%s",str2,n);
            printf("In str2:%s   In n:%s\n",str2,n);
    }
    the problem is that for the all my friend´s names except the first, str2 is reading and saving in str[0] a '\n' character that makes it jump a line and makes the strcmp(str1,str2) not work.
    So after tried a few things I thought of this, that works but it isn´t very elegant:
    Code:
    while((i!=EOF) && ((strcmp(str1, str2)) != 0))  
    {
            i=fscanf(f,"%[^-]-%s",str2,n);
            if(c>=1)
                    { 
                       for(j=1;j<strlen(str2);++j) str2[j-1]=str2[j];
                      str2[strlen(str2)-1]='\0';
                    }
            printf("In str2:%s   In n:%s\n",str2,n);
            c=c+1;
    }
    does anyone know an easier way to make str2 so as not to read a '\n' character ?

  9. #9
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Instead of
    Code:
     i = fscanf(f, "%[^-]-%s", str2, n);
    use
    Code:
    i = fscanf(f, " %[^-]-%s", str2, n);
    Note the space before the first % in the format string. %[ (and also %c and %n) doesn't skip whitespace before the input item and so you have to explicitly add it.

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 06-18-2012, 08:23 AM
  2. Open a file, read it ... and ... read it again
    By Tiago in forum C Programming
    Replies: 1
    Last Post: 04-17-2010, 03:32 AM
  3. How can I know the actual bytes read in a file read
    By pliang in forum C++ Programming
    Replies: 1
    Last Post: 06-08-2005, 04:23 PM