Thread: How to read from a sequential txt file

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

    How to read from a sequential txt file

    Hi,

    I want to read in two char[] and a int from txt file then print them to the screen.

    The problem is when output to the screen, the space is missing and get extra iput at the end of file.

    The input file (e:\\text.txt) consists of

    Hong Kong, China, 1\n
    Tokyo, Japan, 2\n
    Szhen, China, 3\n

    Code:
    #include <stdio.h>
    
    int main()
    {
        FILE *fp=fopen("e:\\text.txt", "r");
    
        char city[256];         /*city name: 256 long */
        char country[256];  /*country name: 256 long*/
        int  pop;                  /*Country population*/
    
        while(!feof(fp))
        {
            fscanf(fp, "%s%s%d", city,country, &pop);
    
            printf("%s%s%d",city,country, pop);
        }
    
        fclose(fp);
    
        getchar();
        return 0;
    }
    ---------------------------------
    Output
    HongKong,256China,1256Tokyo,Japan,2Szhen,China,3Szhen,China,3

    --------------------------------

    I have noted
    1. number 256 add to it, does it mean a space?
    2. why Szhen,China,3 input twice?

    --------------------------------

    Question
    1. Does the output of sequential file output always look like
    data1data2..........datan
    If yes

    2. How to print add a new line to the input int, ie. after input 1, 2, 3
    3. How to get rid of extra input?

    ---------------------------------------------------
    I have seen on some tutorial, they use %[^\n] to delimit the input, what does it mean?
    ------------------------------

    Can anyone please help.
    Thanks
    Henry

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Read the FAQ on why using feof() to control a loop is bad (for this very reason).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by hen_ry
    The problem is when output to the screen, the space is missing

    ...

    2. How to print add a new line to the input int, ie. after input 1, 2, 3
    The program prints what you tell it to print. If the output is not what you expect, then you must deal with that. In these cases, your print function does not contain spaces or a newline so there is no space between the city/country/pop values and no newline at the end of the pop value. You must put those there:
    Code:
    printf("%s %s %d\n",city,country, pop);
              ^  ^ - Note spaces here
    Quote Originally Posted by hen_ry
    I have seen on some tutorial, they use %[^\n] to delimit the input, what does it mean?
    In this case it means to read up to (but not including) the newline character. In your case, given the expected input you've described, I'd make the fscanf line like this:
    Code:
    fscanf(fp, " %[^,], %[^,], %d", city,country, &pop)
    Quote Originally Posted by hen_ry
    2. why Szhen,China,3 input twice?
    This relates to what Salem has mentioned. Avoid using feof to control you loops. It would be better to use the return result from the fscanf call in place of the feof call to control this loop. The fscanf function returns the number of values it successfully converted/stored. In your case, since you're reading in 3 values, you'd expect the return value to be equal to 3. You can test this in the loop instead of the feof call. The reason this is getting output twice is that the end-of-file flag does not get set to true until after an attempt is made to read past the end of the file. When you've read the last line in the file, feof still returns false and you wind up going through the loop another time in error trying to process data that isn't there. The read operation fails - which this time sets the end-of-file flag to true - and the data that was read in from the previous loop is still in your variables and gets output a second time.

    [edit]Understand the difference between input/output. You seem to be confusing them here many times.[/edit]
    "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

  4. #4
    Registered User
    Join Date
    Apr 2009
    Posts
    10
    Hi,

    Thanks for your help. The result print correctly.

    Henry

  5. #5
    Registered User
    Join Date
    Apr 2009
    Location
    Russia
    Posts
    116
    Code:
        fscanf(fp, "%255[^,]%*c%255[^,]%*c%10d\t", city, country, &pop);
    it is for limitation of a data and for clearing space character after line when you use a %[^,] format specifier

  6. #6
    Registered User
    Join Date
    Apr 2009
    Posts
    10
    Hi,

    Thank you for your help, problem solve.

    Now I want to ask user to enter a city name to see if in the file. If it is print its population.

    The problem is there are two city name with similar length, my program can't disguish between the two cities and print them on screen.

    I have use if(strncmp(city, cityName, strlen(cityName)==0) to compare the string.

    --------------------------------
    Part of input file:
    Code:
    Abidjan,C?te d'Ivoir
              *
              *
    
    St. Louis,USA,2825000
    St. Petersburg,Russia,4775000
    Stockholm,Sweden,1910000
    
              *
              *
    ----------------------------------

    My code
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    /*Purpose: get city name from user
               See if cityname is in the file.
               If it is print population
    
       Problem occur when type in a city there are two cities with similar name
       it will print both out.
    
       e.g INPUT : St. Louis
           OUTPUT: St. Petersburg
    */
    
    int main()
    {
        FILE *fp=fopen("e:\\city.txt", "r");
    
        char city[256];
        char country[256];
        int  pop;
    
        char cityName[256];
        int i;
    
        printf("Which city do you want to search for? ");
        scanf("%s", cityName);
    
        /*Read three items per line*/
        while(fscanf(fp," %[^,], %[^,], %d", city, country, &pop)==3)
        {
               /*Compare the whole cityName[] with city[] in the file.*/
    
               if(strncmp(city, cityName,strlen(cityName))==0)
    
               {
                   printf("%s %s %d\n",city, country, pop);
               }
        }
    
        fclose(fp);
    
        fflush(stdin);
        getchar();
        return 0;
    }
    ---------------
    Is my logic correct?

    Are there any method to solve the problem?

    -----------------------
    OUTPUT
    Code:
    Which city do you want to search for? St. Louis
    St. Louis USA 2825000
    St. Petersburg Russia 4775000
    Thanks
    Henry

  7. #7
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    printf("Which city do you want to search for? ");
    scanf("%s", cityName);
    Using scanf with a straight %s format specifier will mean that you'll only store up to the first whitespace into cityName. If you type in "St. Louis" for example, only the "St." part is going to be stored because of the space between the two parts. This plus the way you do the comparison based on the length of the cityName string instead of the city string, means that you are finding anything in the file that begins with "St.". To deal with this, your read of the city to search for must include everything up to the newline so you get "St. Louis" instead of just "St.". Using something like fgets instead and then removing the trailing newline from the read string before doing you comparison would work... alternately, you could use something like scanf("%255[^\n]%*c",city) instead which would read up to the newline. The %*c will eat and ignore the newline so that your later getchar call will work by pausing things on screen. This would then get the whole city name "St. Louis" instead of just "St." and the comparison should then work.

    Code:
    fflush(stdin);
    fflush is undefined for input streams, it should only be used for output streams. Read the FAQ for the "why".
    "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

  8. #8
    Registered User
    Join Date
    Apr 2009
    Location
    Russia
    Posts
    116
    %255[^,] will not clear spaces before the name (they will be read as a part of a name, so I suggest you two-steps read, one for read ...,...,... and second for read names without spaces before them)

  9. #9
    Registered User
    Join Date
    Apr 2009
    Posts
    10
    Hi,

    Thanks all for your help, problem solved.

    My modified code.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    int main()
    {
        FILE *fp=fopen("e:\\city.txt", "r");
    
        char city[256];
        char country[256];
        int  pop;
    
        char cityName[256];
        int i;
    
        printf("Which city do you want to search for? ");
        scanf("%[^\n]", cityName);
    
        /*Read three items per line, i.e. city name, country name, population*/
        while(fscanf(fp," %[^,], %[^,], %d", city, country, &pop)==3)
        {
               if(strncmp(city, cityName,strlen(cityName))==0)
               {
                   printf("%s %s %d\n",city, country, pop);
               }
        }
    
        fclose(fp);
    
        fflush(stdin);
        getchar();
        return 0;
    }
    Sample run
    Code:
    Sample run 00
    
    Which city do you want to search for? A
    
    Abidjan C?te d'Ivoire 4225000
    Accra Ghana 3350000
    Adana Turkey 1360000
    Addis Abeba Ethiopia 3100000
    Adelaide Australia 1150000
    Agra India 1700000
    Ahmedabad India 5650000
    Ahvaz Iran 1030000
    Aleppo Syria 2850000
    Alexandria Egypt 5100000
    Algiers Algeria 4275000
    Allahabad India 1230000
    Alma-Ata Kazakhstan 1230000
    Amman Jordan 2850000
    Amritsar India 1270000
    Amsterdam Netherlands 1910000
    Ankara Turkey 3875000
    Anshan China 2200000
    Antananarivo Madagascar 1760000
    Antwerp Belgium 1110000
    Arbil Iraq 1240000
    Asansol India 1580000
    Asunci?n Paraguay 2025000
    Athens Greece 3725000
    Atlanta USA 5500000
    Auckland New Zealand 1260000
    Austin USA 1560000
    
    ------------------------------------------------------
    Sample run 01
    
    Which city do you want to search for? St.
    
    St. Louis USA 2825000
    St. Petersburg Russia 4775000
    
    ---------------------------------------------------------
    Sample run 02
    
    Which city do you want to search for? St. L
    
    St. Louis USA 2825000
    
    --------------------------------------------------------
    Sample run 03
    
    Which city do you want to search for? St. Louis
    
    St. Louis USA 2825000
    Henry

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. read from file problem
    By Martin Kovac in forum C Programming
    Replies: 1
    Last Post: 04-13-2009, 08:33 AM
  2. Replies: 21
    Last Post: 06-16-2008, 02:44 PM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. read values from a txt file
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 08-30-2002, 01:37 PM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM