I have a file that contains string,int,int values in multiple lines.
Delhi,12,13
Mumbai,100 , 101
Kolkata,11, 12
The values are separated by commas but there can be stray whitespaces in between.My current code is this :
#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
int main()
{
FILE *f = fopen("input.txt","r");
int lines = 0;
char c = getc(f);
while(c != EOF)
{
if(c == '\n')
{
lines++;
}
c = getc(f);
}
lines++;
string arr[lines];
int t1[lines];
int t2[lines];
char s1[100],s2[100],s3[100];
int x,y;
fclose(f);
f = fopen("input.txt","r");
while (fscanf(f,"%99[^,],%99[^,],%99[^,]", s1, s1, s2)==3)
{
cout << s1 << s2 << s3 << endl;
}
}
This doesn't seem to quite properly read the values and display on the screen first of all. How do I read the string and the integer values here(which may have stray whitespaces) and store them into an array (three arrays to be precise) ?
The problem is on this line:
while (fscanf(f,"%99[^,],%99[^,],%99[^,]", s1, s1, s2)==3)
It tries to scan up to the next comma character ','
, which occurs on the next line. Replace with %99[^\n]
to fix this problem:
while (fscanf(f,"%99[^,],%99[^,],%99[^\n]", s1, s1, s2)==3)
Try doing this:
fscanf(f,"%[^, ]%*[ ,]%d%*[ ,]%d ", s1, &x, &y);
%[^, ]
=> searches for everything except ,
and <space>
and stores it in s1
%*[ ,]
=> searches for ,
and <space>
but does not store it anywhere (the *
ensures that)
%d
=> stores the number
Why are you using FILE*
and friends in C++?
The other answers specify the problem with your code, so I'm writing this answer to show you how to improve it.
std::ifstream file("input.txt");
std::string name, value0, value1;
while (std::getline(file, name, ',')) {
// Get the value strings from the stream.
std::getline(file, value0, ',');
std::getline(file, value1, ',');
// These will throw an exception when given invalid input.
int v0 = std::stoi(value0);
int v1 = std::stoi(value1);
// Do stuff with the strings
}
std::getline
can be used to extract a string from a stream up until a certain delimiter. Whitespaces are ignored here, so we don't have to care about them. The return value of std::getline
is the stream passed in, and it has an operator bool()
that allows us to use it as a boolean expression. The value will become false
when the stream is either empty or in some erroneous state.
Note that the above should be similar in behavior to:
while (file) {
std::getline(file, name, ',');
// ...
}
I'm pretty sure this must be a whole lot more readable than a string like "%99[^,],%99[^,],%99[^,]"
.
Cheers~
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.