CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: Fread on file

  1. #1
    Join Date
    Apr 2009
    Posts
    116

    Fread on file

    I am trying to read and store a txt file with format below:

    2.5;abc;2,4000
    2.5;bef;3,2000
    2.5;ref;3,1000

    I try the fscanf( pFile, "%d;%s;%d,%d", buffer,buffer2,buffer3,buffer4 ); to store 2.5 to buffer, abc to buffer2, 2 to buffer 3 and 4000 to buffer 4 on first line.
    However, it doesn't work.
    How can I achieve this? I want to read the 2nd line and so on.
    Code:
    			char buffer[100]="";
    			char buffer2[100]="";
    			char buffer3[100]="";
    			char buffer4[100]="";
    			FILE * pFile=NULL;
    			pFile = fopen("C:\\test\\test.txt", "r");
    			if (pFile!=NULL)
    			{
    				printf("file is open");
    
    				      // Set pointer to beginning of file:
    				  fseek( pFile, 0L, SEEK_SET );
    
    				  // Read data back from file:
    				  fscanf( pFile, "%d;%s;%d,%d", buffer,buffer2,buffer3,buffer4 );   
    				fclose (pFile);
    			}
    Last edited by PHChang; February 12th, 2014 at 04:25 PM.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Fread on file

    Define "doesn't work".
    Did you try to debug to find out what and where works wrong?
    Victor Nijegorodov

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Fread on file

    Code:
    fscanf( pFile, "%d;%s;%d,%d", buffer,buffer2,buffer3,buffer4 );
    %d means read a decimal number so the corresponding var in the arg-list needs to be of type int - not of type char[]. %s means read a string and will read all the remaining chars on the line including the 2,4000. If you just want to read a few chars then you need to specify the number of chars to be read or end the chars with a white-space char. In your data file, the chars are of length 3 delimited by ';'. Given your data, one way to read the file is

    Code:
    #include <stdio.h>
    
    int main()
    {
    char buffer[100] = {0};
    
    float d1;
    int i1, i2;
    
    FILE *pFile = NULL;
    
    	//pFile = fopen("C:\\chang\\fanControl\\fanControl.txt", "r");
    	if (!(pFile = fopen("fancontrol.txt", "r"))) {
    		printf("File cannot be open\n");
    		return 1;
    	}
    
    	// Set pointer to beginning of file:
    	fseek( pFile, 0L, SEEK_SET );
    
    	// Read data back from file:
    	while ((fscanf(pFile, "%f;%3s;%i,%i", &d1, buffer, &i1, &i2)) > 0)
    		printf("%.1f  %s  %i  %i\n", d1, buffer, i1, i2);
    
    	fclose (pFile);
    
    	return 0;
    }
    This produces the output
    Code:
    2.5  abc  2  4000
    2.5  bef  3  2000
    2.5  ref  3  1000
    If the ';' following the text in the data file can be replaced by a ' ' then the fscanf can be replaced by
    Code:
    	while ((fscanf(pFile, "%f;%s%i,%i", &d1, buffer, &i1, &i2)) > 0)
    If the number of chars can vary from 3, then either terminate them with a space or you will need to read the whole line and then have code to parse the data read.

    Are you using c or c++?
    Last edited by 2kaud; February 12th, 2014 at 02:46 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    Apr 2009
    Posts
    116

    Re: Fread on file

    Thanks I will try it out and see how.
    I am using visual C++ 2010 compiler.

  5. #5
    Join Date
    Apr 2009
    Posts
    116

    Re: Fread on file

    Thanks 2kaud.
    Let say the 2nd field is not limited to 3 chars, it can vary from 3 to 10 (or any number), how can resolve it?

    Code:
    	while ((fscanf(pFile, "%f;%3s;%i,%i", &d1, buffer, &i1, &i2)) > 0)
    		printf("%.1f  %s  %i  %i\n", d1, buffer, i1, i2);
    Example:
    2.5;abc;2,4000
    2.5;beeef;3,2000
    2.5;refs;3,1000

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Fread on file

    If you can use c++, then a possible way to read the file would be
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    const int bufsize = 100;
    
    int main()
    {
    char buffer[bufsize];
    
    float d1;
    int i1, i2;
    char ch;
    
    ifstream ifs("fancontrol.txt");
    
    	if (!ifs.is_open()) {
    		cout << "File cannot be opened\n";
    		return 1;
    	}
    
    	// Read data back from file:
    	while (ifs >> d1 >> ch) {
    		ifs.get(buffer, bufsize, ';');
    		ifs >> ch >> i1 >> ch >> i2;
    		cout << d1 << "  " << buffer << "  " << i1 << " " << i2 << endl;
    	}
    
    	ifs.close();
    
    	return 0;
    }
    This is preferable to the c solution of post #3 as you can keep the format of the data file and have a variable number of chars (less than the defined const) for the second element.
    Last edited by 2kaud; February 12th, 2014 at 05:13 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Apr 2009
    Posts
    116

    Re: Fread on file

    This looks complicated to me.

    Mind to explain what it is doing?
    Code:
    	// Read data back from file:
    	while (ifs >> d1 >> ch) {
    		ifs.get(buffer, bufsize, ';');
    		ifs >> ch >> i1 >> ch >> i2;
    		cout << d1 << "  " << buffer << "  " << i1 << " " << i2 << endl;
    	}

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Fread on file

    This looks complicated to me.
    Its simpler than doing variable length string extration using 'c' library routines!

    Code:
    ifs >> d1 >> ch
    extracts from the ifs file stream the first real number and stores it in the float d1 and then reads the following ';'.

    Code:
    ifs.get(buffer, bufsize, ';');
    gets chars from the file stream and stores them in the char array buffer until either bufsize-1 chararacters have been read or a ';' is found. This will read the text in your file until it finds the terminating ';' assuming it is no longer than bufsize-1 chars.

    Code:
    ifs >> ch >> i1 >> ch >> i2;
    this will read from the ifs file stream the text terminating ';' followed by the integer into i1, the terminating , and the final integer into i2.

    These three statements just obtain the data from a line of the file into variables d1, buffer, i1 and i2.

    This is standard simple c++ stream extraction code. For more info see http://www.cplusplus.com/reference/fstream/ifstream/

    Code:
    while (ifs >> d1 >> ch) {
    when the state of the input stream is not good, stream extraction returns a NULL. So while the state of the input stream ifs is good, the loop extracts the data. When the state of the input stream is not good, the while loop terminates.

    The cout statement just displays for info the data extracted from the file.
    Last edited by 2kaud; February 13th, 2014 at 06:34 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    Join Date
    Apr 2009
    Posts
    116

    Re: Fread on file

    Sorry to bother again.
    If change to format below (separated by commas), there will be blank for some fields. How to read it?

    2.5,abc,2,4000
    2.5,,3,2000
    2.5,,3,1000

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Fread on file

    Try this
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    const int bufsize = 100;
    
    int main()
    {
    char buffer[bufsize];
    
    float d1;
    int i1, i2;
    char ch;
    
    ifstream ifs("fancontrol.txt");
    
    	if (!ifs.is_open()) {
    		cout << "File cannot be opened\n";
    		return 1;
    	}
    
    	// Read data back from file:
    	while (ifs >> d1 >> ch) {
    		ifs.getline(buffer, bufsize, ',');
    		ifs >> i1 >> ch >> i2;
    		cout << d1 << "  " << buffer << "  " << i1 << " " << i2 << endl;
    	}
    
    	ifs.close();
    
    	return 0;
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  11. #11
    Join Date
    Apr 2009
    Posts
    116

    Re: Fread on file

    Thanks.
    Assume if it is a non-numbers for all fields? How to read it? Some could be blank.

    2.5a,abc,2d,40e00
    2.5c,,3e,20e00
    2.5d,,3e,1e000

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Fread on file

    Your wish..... but what is your level of c++ knowledge as this sort of task is fairly trivial? You would probably learn more by having a go yourself and then asking for help if you got problems. From the code provided earlier I would have expected at least some attempt as the revised code is less than a dozen lines.

    Code:
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    using namespace std;
    
    typedef vector<string> vs;
    
    const int MaxBuf = 100;
    const int NoFields = 4;
    const char delimit = ',';
    
    int main()
    {
    ifstream ifs("fancontrol.txt");
    
    	if (!ifs.is_open()) {
    		cout << "File cannot be opened\n";
    		return 1;
    	}
    
    	// Read data back from file:
    	while (ifs.good()) {
    		vs fields;
    		char buffer[MaxBuf];
    
    		for (int f = 1; f <= NoFields; ++f) {
    			ifs.getline(buffer, MaxBuf, (f == NoFields) ? '\n' : delimit);
    			fields.push_back(buffer);
    		}
    
    		//Display fields
    		copy(fields.begin(), fields.end(), ostream_iterator<string>(cout, "  "));
    		cout << endl;
    	}
    
    	ifs.close();
    
    	return 0;
    }
    This assumes that there are always 4 fields per line (of which any can be blank - ie each line always contains 3 commas). It puts the fields for each line into a vector of type string so that they can be easily used and then displays the fields for each line.

    If you don't know how many fields there will be per line or if the number is variable then you could read them by something like this

    Code:
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    using namespace std;
    
    typedef vector<string> vs;
    
    const char delimit = ',';
    
    int main()
    {
    ifstream ifs("fancontrol.txt");
    
    	if (!ifs.is_open()) {
    		cout << "File cannot be opened\n";
    		return 1;
    	}
    
    string buffer;
    
    	// Read data back from file:
    	while (getline(ifs, buffer)) {
    		vs fields;
    		for (size_t pos1 = 0, pos2 = 0; (pos2 = buffer.find(delimit, pos1)) != string::npos; pos1 = pos2 + 1)
    			fields.push_back(buffer.substr(pos1, pos2 - pos1));
    
    		fields.push_back(buffer.substr(pos1));
    
    		//Display fields
    		copy(fields.begin(), fields.end(), ostream_iterator<string>(cout, "  "));
    		cout << endl;
    	}
    
    	ifs.close();
    
    	return 0;
    }
    Where again it puts the fields for each line into a vector of string.
    Last edited by 2kaud; February 20th, 2014 at 03:28 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured