Thread: Not reading the next line down in a text file.

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    13

    Not reading the next line down in a text file.

    Hi all,

    I wrote a function to handle file input/output.

    when reading from file using the function "File_IPOP(6,0)" fscanf does not want to read the next line in the file. why?

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<windows.h>
    #include<limits.h>  //INT_MAX equal to +2147483647 <<complier dependant
    
    File_IPOP(selection,in) 	//1=Write data to file >> return 0;
    							//2=set file pointer to start >> return 0;
    							//3=erase data from file >> return 0;
    							//4=set file pointer to end >> return 0; >>notworking??
    							//5=read size of file >> return int filesize;
    							//6=read integer from file >> return int ouput;
    							//7=read LAST integer from file >> return int last_prime;
    							
    							//"In" = Prime integer to add to end of file.
    							//"/cygdrive/c/data/PP.txt"<<FILE
    {
    int out,count,filesize,c,last_prime,line;
    char filename;
    												 	  /*r  - open for reading
    														w  - open for writing (file need not exist)
    														a  - open for appending (file need not exist)
    														r+ - open for reading and writing, start at beginning
    														w+ - open for reading and writing (overwrite file)
    														a+ - open for reading and writing (append if file exists)*/
    FILE *fw;
    fw=fopen("/cygdrive/c/data/PP.txt", "a+"); 
    FILE *fr;
    fr=fopen("/cygdrive/c/data/PP.txt", "r+"); 
    FILE *fa;
    fa=fopen("/cygdrive/c/data/PP.txt", "r"); 
    
    switch(selection)
    {
    case 1:
    	fprintf(fw,"%d\n",in); //"In" = Prime integer added to end of file.
    	fflush(fw);
    	fclose(fw);
    	return 0;
    break;
    case 2:
    /*
    Name 		Explanation
    SEEK_SET 	Seek from the start of the file
    SEEK_CUR 	Seek from the current location
    SEEK_END 	Seek from the end of the file
    
    fseek() returns zero upon success, non-zero on failure. You can use fseek() to move beyond a file, but not before the beginning. Using fseek() clears the EOF flag associated with that stream.
    */
    	fseek( fr, 0, SEEK_SET); // set fr file stream pointer to start
    	return 0;
    break;
    case 3:
    	fopen("/cygdrive/c/data/PP.txt", "w");
    	return 0;
    break;
    case 4:
    	fseek( fa, 0, SEEK_END); 					// set fr file stream pointer to start
    	return 0;
    break;
    case 5:
    /* ftell example : getting size of a file */
        fseek (fa, 0, SEEK_END);				// set fr file stream pointer to end
        filesize=ftell (fa);					// ftell read bytes from end to beginning
        fclose (fa);
    	if(filesize=!-1)
        {
    		printf ("Size of text file: %ld bytes.\n",filesize);
    		return filesize;
    	}
    	else
    	{
    		printf("error occurred when reading file size\n\n");
    	}
    	return 0;
    break;
    case 6:
    	fscanf(fa,"%d",&out);
    	return out;
    break;
    case 7:
    	while(1)
    	{
    		if(feof(fa)) //EOF
    		{
    			return last_prime;
    		}
    		else //not EOF yet
    		{
    			fscanf(fa,"%d",&last_prime);
    		}
    	}
    break;
    default:
    printf("no selection was specified");
    break;
    }
    
    return 1;
    }
    
    int main()
    
    {
    printf("%d\n", File_IPOP(6,0)); 
    printf("%d\n", File_IPOP(6,0)); 
    printf("%d\n", File_IPOP(6,0)); 
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    File_IPOP(selection,in)
    What is that supposed to be? A function definition? You're doing it wrong. You aren't even doing it old school, you are just flat out not doing it right.

    A function needs:

    1. A return type.
    2. A function name.
    3. An argument list, complete with types for each argument.
    4. A function body.

    You need something like:
    Code:
    void File_IPOP( int selection, int in )
    {
        ...
    }
    Your arguments don't have a type, and your function doesn't have a return type.

    You use fseek, but you aren't using binary mode. You don't fseek text files.
    You never check the return value of fscanf to see if it worked or not.

    All of the *scanf functions expect exact formatting. If you want it to be skipping to the next line, then you need to make sure you tell it to read the newline/whitespace, and not just "go get an integer".


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

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    13
    Alright, i've fixed the function. Added the code to check if the file can actually be loaded, if not then prints error message.

    and got rid of fseek since i'm not using a binary file.

    Would i be correct to use "fscanf(fa, "%d[^\n]\n", &store);"?

    with %d[^\n]\n been the formatting to tell fscanf to read '\n'
    Tho it still doesn't like to skip down to the next line after reading the first line.


    Code:
    #include<stdio.h>
    #include<string.h>
    #include<windows.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<limits.h>  //INT_MAX equal to +2147483647 <<complier dependant
    
    int File_IPOP(int selection, int in) 	
    							//1=Write data to file >> return 0;
    							//2=erase data from file >> return 0;
    							//3=read size of file >> return int filesize;
    							//4=read LAST integer from file >> return int last_prime;
    							//5=read FIRST integer from file >> return int first_prime;
    							//6=read NEXT integer from file >> return int prime;
    							//"In" = Prime integer to add to end of file.
    							//"/cygdrive/c/data/PP.txt"<<FILE
    {
    int out,count,filesize,c,last_prime,line;
    char filename;
    FILE *fp;
    int store,ret;
    												 	  /*r  - open for reading
    														w  - open for writing (file need not exist)
    														a  - open for appending (file need not exist)
    														r+ - open for reading and writing, start at beginning
    														w+ - open for reading and writing (overwrite file)
    														a+ - open for reading and writing (append if file exists)*/
    FILE *fw;
    fw=fopen("/cygdrive/c/data/PP.txt", "a+"); 
    FILE *fr;
    fr=fopen("/cygdrive/c/data/PP.txt", "r+"); 
    FILE *fa;
    fa=fopen("/cygdrive/c/data/PP.txt", "r"); 
    
    switch(selection)
    {
    case 1:
    {
    if ((fw=fopen("/cygdrive/c/data/PP.txt", "a+")) == NULL) 
    {
    	fprintf(stdout, "Error: Can't open file !\n");
    	return -1;
    }
    else
    {
    	fprintf(fw,"%d\n",in); //"In" = Prime integer added to end of file.
    	fflush(fw);
    	fclose(fw);
    	return 0;
    }
    
    return 0;
    }
    break;
    case 2:
    {
    if ((fw=fopen("/cygdrive/c/data/PP.txt", "a+")) == NULL) 
    {
    	fprintf(stdout, "Error: Can't open file !\n");
    	return -1;
    }
    else
    {
    	fopen("/cygdrive/c/data/PP.txt", "w");
    	return 0;
    }
    }
    break;
    case 3:
    {
    	/* ftell example : getting size of a file */
    if ((fa=fopen("/cygdrive/c/data/PP.txt", "r")) == NULL) 
    {
    	fprintf(stdout, "Error: Can't open file !\n");
    	return -1;
    }
    else
    {
    	while(1)
    		{
    			if(feof(fa)) //EOF
    			{
    				filesize=ftell (fa);					// ftell read bytes from end to beginning
    				fclose (fa);
    				if(filesize=!-1)
    				{
    					printf ("Size of text file: %ld bytes.\n",filesize);
    					return filesize;
    				}
    				else
    				{
    					printf("error occurred when reading file size\n\n");
    				}
    			}
    			else //not EOF yet
    			{
    				fscanf(fa,"%d",&last_prime);
    			}
    		}
    		return 0;
    }
    }
    break;
    case 4:
    {
    	while(1)
    	{
    		if(feof(fa)) //EOF
    		{
    			return last_prime;
    		}
    		else //not EOF yet
    		{
    			fscanf(fa,"%d",&last_prime);
    		}
    	}
    }
    break;
    case 5:
    {
    
    // Open a file ("test.txt")
    if ((fa) == NULL) 
    {
    	fprintf(stdout, "Error: Can't open file !\n");
    	return -1;
    }
    else
    {
    	ret = fscanf(fa, "%d[^\n]\n", &store);
    	if(ret != EOF) 
    	{
    		// Print line
    		printf("%d\n", store); 
    		return store;
    	}
    }
    	// Close file
    	fclose(fa);
    	return 0;
    }
    break;
    case 6:
    {
    	if ((fa) == NULL) 
    	{
    		fprintf(stdout, "Error: Can't open file !\n");
    		return -1;
    	}
    	else
    	{
    		fscanf(fa, "%d[^\n]\n", &store);
    		return store;
    	}
    }
    break;
    default:
    printf("No selection was specified");
    break;
    }
    
    return -1;
    }
    int main()
    
    {
    /*int pp,prevprime;
    
    while(pp%File_IPOP(6,0)==0)//logical check
    {
    	printf("PP not prime") //if yes
    	PP=PP+2;
    	File_IPOP(2,0); //set pointer to start
    }
    else
    {
    	
    	check against all Prevprimes before looping again
    }
    
    */
    
    /*File_IPOP(2,0); 
    File_IPOP(1,10); 
    File_IPOP(1,20); 
    File_IPOP(1,30); 
    File_IPOP(1,40);
    */
    printf("%d\n",File_IPOP(5,0));
    printf("%d\n",File_IPOP(6,0));
    printf("%d\n",File_IPOP(6,0));
    
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You could just use fgets to read the line into a buffer, and then use sscanf to pull what you want from each line.


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

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    You could do a lot to make your functions FAR simpler...

    First of all, given what you are doing you really only need one fopen() statement.
    Secondly, you really only need to check once if the file opened, right after you open it.
    Third you could save yourself a ton of open/close activity (which is slowish) by making cases that open the file and close the file...

    Sort of like this...
    Code:
    #define myfile "/cygdrive/c/data/PP.txt"
    FILE *popfile
    
    int file_IPOP(int func, int *value)
      { switch (func)
          { case 0 : // close the file
               fclose(popfile);
               return 1;  // assume success
            case 1 :  // open the file
               popfile = fopen(myfile,"a+");
               return (popfile != NULL);
           case  2 : // get file size
               fseek(popfile,SEEK_END,0);
               *value = ftell(popfile);
               return 1;
    
    // and so on...
    This will allow you to open the file once at the beginning of where it's needed, then close it once when done. It also moves the error trapping back to whatever function is calling this one... so you can test results to know if a call failed or not.

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    13
    I've simplified the function a bit and using fgets.

    looking at case 6 in the function.
    I'm reading integers from a file. fgets first argument 'store', my compiler doesn't like it been an integer, only a char string for the first argument.

    I want the function to return the integer value read from file.
    I used a char string to store the integer from file(sounds wrong). Then use the function 'atoi()' to convert the stored string into an integer so i can return that integer from the function.

    I don't think you can actually return strings or arrays, from a function. so i need it as an integer.

    But all i get is a stackdump error upon running it.<< i assume cause i used the char string.

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<windows.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<limits.h>  //INT_MAX equal to +2147483647 <<complier dependant
    
    int File_IPOP(int selection, int in) 	
    							//0=Open file >> return 1;
    							//1=Close file >> return 1;
    							//2=Write data to file >> return 0;
    							//3=erase data from file >> return 0;
    							//4=read size of file >> return int filesize;
    							//5=read LAST integer from file >> return int last_prime;
    							//6=read NEXT integer from file >> return int prime;
    							//"In" = Prime integer to add to end of file.
    							//"/cygdrive/c/data/PP.txt"<<FILE
    {
    int out,count,filesize,c,last_prime,line,ret;
    char filename,store[200];
    												 	  /*r  - open for reading
    														w  - open for writing (file need not exist)
    														a  - open for appending (file need not exist)
    														r+ - open for reading and writing, start at beginning
    														w+ - open for reading and writing (overwrite file)
    														a+ - open for reading and writing (append if file exists)*/
    FILE *fw;
    FILE *fr;
    FILE *fa;
    
    switch(selection)
    {
    case 0: //Open file
    	fa=fopen("/cygdrive/c/data/PP.txt", "r"); 
    	fr=fopen("/cygdrive/c/data/PP.txt", "r+"); 
    	fw=fopen("/cygdrive/c/data/PP.txt", "a+");
    return 1;
    break;
    case 1: //Close File
    	fclose(fw);
    	fclose(fr);
    	fclose(fa);
    	return 1;
    case 2:
    	fprintf(fw,"%d\n",in); //"In" = Prime integer added to end of file.
    	return 0;
    break;
    case 3:
    	fopen("/cygdrive/c/data/PP.txt", "w");
    	return 0;
    break;
    case 4:
    	while(1)
    		{
    			if(feof(fa)) //EOF
    			{
    				filesize=ftell (fa);					// ftell read bytes from end to beginning
    				if(filesize=!-1)
    				{
    					return filesize;
    				}
    				else
    				{
    					return -1;
    				}
    			}
    			else //not EOF yet
    			{
    				fscanf(fa,"%d",&last_prime);
    			}
    		}
    		return 0;
    break;
    case 5:
    	while(1)
    	{
    		if(feof(fa)) //EOF
    		{
    			return last_prime;
    		}
    		else //not EOF yet
    		{
    			fscanf(fa,"%d",&last_prime);
    		}
    	}
    break;
    case 6:
    	while(fgets(store,sizeof store, fa) != NULL)
    	{
    		out = atoi(store); //atoi() function converts str into an integer, and returns that integer.
    		return out;
    	}
    break;
    default:
    	printf("No selection was specified");
    break;
    }
    
    return -1;
    }
    
    int main()
    {
    printf("%d\n",File_IPOP(6,0));
    printf("%d\n",File_IPOP(6,0));
    printf("%d\n",File_IPOP(6,0));
    }
    note: the code is just part of a bigger picture.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I look in horror at code like this:
    Code:
        while(1)
            {
                if(feof(fa)) //EOF
                {
                    filesize=ftell (fa);                    // ftell read bytes from end to beginning
                    if(filesize=!-1)
                    {
                        return filesize;
                    }
                    else
                    {
                        return -1;
                    }
                }
                else //not EOF yet
                {
                    fscanf(fa,"%d",&last_prime);
                }
            }
    Looking at your comments, I see that this was intended to read the size of the file. This is what the C standard has to say about ftell:
    The ftell function obtains the current value of the file position indicator for the stream pointed to by stream. For a binary stream, the value is the number of characters from the beginning of the file. For a text stream, its file position indicator contains unspecified information, usable by the fseek function for returning the file position indicator for the stream to its position at the time of the ftell call; the difference between two such return values is not necessarily a meaningful measure of the number of characters written or read.
    Since you appear to be using Cygwin, the stream may be a binary stream even though you did not open it as such, as if I recall correctly, I/O streams are in binary format on *nix even when not specified. Still, be careful.

    If you did want to use ftell like this, using fseek with SEEK_END and then using ftell probably makes more sense than the convoluted controlled infinite loop followed by feof test that you have now. But if you want to read and read all the way to the end, you should count characters rather than use fscanf so automatically. Finally, !-1 is 0, so in actual fact you are always returning -1.

    Anyway, back to the horror, somewhat repeated here:
    Code:
        while(1)
        {
            if(feof(fa)) //EOF
            {
                return last_prime;
            }
            else //not EOF yet
            {
                fscanf(fa,"%d",&last_prime);
            }
        }
    You could have simplified this to:
    Code:
    while (fscanf(fa, "%d", &last_prime) == 1);
    Generally, avoid controlled infinite loops if there is a sensible loop condition that you can use; avoid controlling loops with feof when you can use the return values of the I/O functions involved.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 12-13-2010, 02:13 PM
  2. Reading text file by line number
    By whiskedaway in forum C++ Programming
    Replies: 13
    Last Post: 06-16-2009, 10:09 AM
  3. Reading random line from a text file
    By helloamuro in forum C Programming
    Replies: 24
    Last Post: 05-03-2008, 10:57 PM
  4. Reading a line from a text file Please help
    By Blizzarddog in forum C++ Programming
    Replies: 7
    Last Post: 05-22-2003, 12:35 PM
  5. reading the next line in a text file
    By colorado_scott in forum C Programming
    Replies: 12
    Last Post: 03-31-2003, 04:38 PM