-
February 12th, 2014, 01:41 PM
#1
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.
-
February 12th, 2014, 02:26 PM
#2
Re: Fread on file
Define "doesn't work".
Did you try to debug to find out what and where works wrong?
Victor Nijegorodov
-
February 12th, 2014, 02:43 PM
#3
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)
-
February 12th, 2014, 04:29 PM
#4
Re: Fread on file
Thanks I will try it out and see how.
I am using visual C++ 2010 compiler.
-
February 12th, 2014, 05:09 PM
#5
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
-
February 12th, 2014, 05:11 PM
#6
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)
-
February 12th, 2014, 09:22 PM
#7
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;
}
-
February 13th, 2014, 06:19 AM
#8
Re: Fread on file
This looks complicated to me.
Its simpler than doing variable length string extration using 'c' library routines!
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)
-
February 19th, 2014, 06:31 PM
#9
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
-
February 19th, 2014, 06:42 PM
#10
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)
-
February 19th, 2014, 08:00 PM
#11
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
-
February 20th, 2014, 06:16 AM
#12
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|