Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm creating a simple directory program that allow user to enter a file name and search that file by name, address, or phone number. I'm having trouble properly reading the file.
If someone could give me suggestions on how to fix my getFirstName function. The function should read the first word of the file.
Example file:
Bob Smith 123456789
123 Main Street
Susan Smith 1224445555
543 Market Street
Here is part of my code so far.
string file;
string first;
int main() {
ifstream inFile;
cout<<"Enter file name: ";
cin>> file;
inFile.open(file);
if(inData.fail()) {
cout<<"INVAILD";
}
getFirstName(first);
}
void getFirstName(string f, inFile file) {
file.open(f);
while(file.good(f)) {
file>>f;
}
if (file.bad()) {
cout<<"Name not found";
}
}
i will not write you the program, but let me point you in a direction.
first of all: please format your code better. maybe its just because stackoverflow, but there should be consistent and sensefull formatting of your code, otherwise you and others cant read it well and have trouble finding problems. (plz google clang-format for a tool, maybe an ide would do it as well).
split your programm in different logical parts. my approach would be:
open file, if not possible give warning, end program
read file content into a string IN: filename, OUT: string of content
split the string into line, IN: string, OUT: std::vector
for each line, split the line into parts(3 elements?) IN: linestring, OUT: name, street, ...
You can that in proper datastructures, plz see the STL for good ones
Access your datastructure for the wanted information.
Proposal for your data.
istream for file, you have that
std::string for file content
std::vector for line wise filecontent
std::unordered_map map the name to information.
this should give you a googling start. each subproblem can be solved independent (and tested) and is easier to find on SO :)
Good luck.
I agree with the comments. Yet to answer your issue "The function should read the first word of the file." below is a general idea how you can read the first word from file:
...
ifstream inFile; // define your input stream
string firstwrd; // first word
inFile.open("yourfile"); // open your file
inFile>> firstwrd; // this will read the first word
inFile.close(); // close the file
...
And please consider reading through Jonas`s comments.
Edit: Please note my answer by no means is the definitive tutorial of best practices of reading from file. It applies your specific case.
HTH!
Before you can even begin to start programming, you have to identify the exact format of the file you want to read. That format gives you the order of operations for how you intend to read from the file.
In your example, you give:
Bob Smith 123456789
123 Main Street
Susan Smith 1224445555
543 Market Street
Which is broken down into a by-line format of:
[First Name] [Last Name] [User ID (I assume)]\n
[Address]
So now that we have that established, the first thing we do is open the file stream.
ifstream file("path\\to\\file");
When it comes to retrieving information from a file stream, there are 2 standard methods: the >> operator and getline().
The >> operator returns the very next block of text in a given fstream up to any whitespace character such as space, newline or return characters. The syntax for this is file >> var where file is the fstream you intend you read from and var is the variable you want to write to.
The getline() function will return the entire line, including spaces, but will stop at return and newline characters. The actual syntax of the function is std::getline(read, write); where read is the file stream or string you intend to actually read from and write is the variable you intend to copy the real line to.
For example:
ifstream file("file.txt");
string firstname, lastname, id, address;
file >> firstname; //get the first word of the file.
file >> lastname; //get the second word of the file.
file >> id; //get the third word of the file.
getline(file, address); //Get the next whole line of the file, regardless of how many words.
A funny quirk is that you don't have to worry about manually telling C++ where in the file you're wanting to look for the data. As the file is read a pointer is automatically kept inside of the file stream of where to begin reading from next. When you get one word, the pointer automatically starts at the beginning of the next word, so you just keep pulling data linearly until you reach the end of the file.
void getFirstName(string f, inFile file); should be void getFirstName(string f, ifstream inFile);.
And remember, put an ampersand (&) between the type of the variable and the name to avoid creating a copy of the file (that consumes more ram), not putting the ampersand is only reasonable to use if you want to make changes to the variable that should not stick around.
And where is string f defined? You call the function without passing f but it's used in the function. That is a serious problem.
The ifstream.good() function if I remember correctly can't take parameters.
If you're trying to find f (you didn't tell us what it is so I can't be more precise) then you should first understand that f should be a file (since you used file.open(f);), pass the value to a string, and after doing inFile >> name_of_your_string; do if (name_of_your_string == f) { /* the last word read corresponds to f */}.
The type is ifstream, and the variable's name is inFile.
Also since getFirstName is defined after main, you got to put this before main void getFirstName(string f, ifstream inFile); this is called a prototype, and it tells the compiler that the function is after main.
Obviously don't remove the rest of the function. If that's a problem for you move main under it. Also if someone puts a space in the input everything before the last space will be lost, remove cin >> file; and use getline (cin, file);
Remember to update the answer with more details on what f is and what exactly you want it to do.
EDIT: Remember to use inFile.close(); after you stop reading the file to avoid subtle errors.
I'm trying to read some data out of a text file. One of the data names is Chamber temperature [°C]. I read the file with the command: getline(myfile, tab, '\t'); out.
The problem is that the degree sign is formatted into "Chamber temperature [�C]".
How can I prevent c++ from deformatting the degree sign?
P.S. : In the text file the sign is formatted correctly
Code:
//just create a txt file on your desktop which only stores "Chamber Temperature [°C]
myfile.open("C:\\Users\\user\\Desktop\\test.txt");
string tab = "";
getline(myfile, tab, '\t');
cout << tab << endl;
When you have the same setting as i described below you should have the same problem, well it is not a Problem just a language difference. UTF-8 just cant interpret the signs as ANSI.
There are solutions in which I can look for the substring and then replace the format as I wish, but I would like to have a foolproof and safe way to use this code in any case. So I'm looking for a conversion between these 2 languages.
Additional Information about my environment:
I use eclipse with a MinGW compiler and the accent c++11. I use default text file encoding UTF-8 and the new Text file delimiter UNIX.
I opened the file in notepad++ and it gives me the estimation of the file format "ANSI".
I use a simple ifstream to read the data into a 3D vector (first dimension: file; second dimension: row data; third dimension:columns). I use the getline to read each sequence delimited by a tab into a variable ... and in the end into my matrix.
Now after I have stored the data into my matrix I so some data searching and here comes my problem. Because the file is formatted in ANSI I cant compare the string Chamber Temperature [°C] with the stored data, since it will never find it.
I need to convert the text file into UTF-8 format and then store it into my 3D matrix. Is this possible? I new into coding, so could you please provide me with an example code or pseudo code?
I want to do this:
I have created
vector<string> inputStates;
vector<string> finalStates;
I want to get the values of inputStates and finalStates by parsing the following two lines. They are read from a .txt file using getline(). How should I write the codes? Thank you.
Initial State: 1
Final States: {3,14,20,29,30}
The result should be
inputStates={"1"};
finalStates = {"3","14","20","29","30"}.
I think I should get element and then use finalStates.push_back() to append. But I really don't know how to get the elements from the strings.
You need to include an "fstream" to read the data from the text file and then create an input stream (ifstream)
#include <fstream>
ifstream myFile;
and then use the myFile stream to open your text file and read from it.
More information can be found here.
http://www.cplusplus.com/doc/tutorial/files/
When you read the string using the ifstream you can read it one word at a time and then push the appropriate numbers into your vector.
I have an assignment from school and have to read a comma delimited file and put each value in to a char*.
Ex)
File contains:
5,Justin,19,123-4567,etc..
char * firstValue = 5;
char * secondValue = Justin;
char * thirdValue = 123-4567; etc..
I cannot use std::string since we haven't learned it yet. I am supposed to do it with ifstream or other file streams. I have no idea how to do this
For homework assignments iterating over the char array in a for loop and every time a comma is encountered splitting the string will work (I won't give the code because it is a good exercise to try to work out yourself). But for real world use you should be aware that the CSV format is considerably more complex. Consider multiline entries or entries with an escaped comma and how they break the above solution. I strongly recommend using libcsv for any real world CSV parsing.
I am trying to run a program to replace certain data within a file. The relevant parts of the file attempting to be replaced look like the following:
1 Information 15e+10
2 Information 2e+16
3 Information 6e+2
And so on.
The files in question can be very large in the multiple gigabyte range and to my understanding because of this using a buffer of the whole file and rewriting the whole file is impossible/unreasonable. Well that is all fine I just want to replace the values (ex. the 15e+10).
This all works fine with simple ios::in|ios::out and tellp() if I am replacing the value with a similar sized value (15e+10->12e+12) or even if its a smaller size as I can simply add an extra space which can be ignored down the line (ex. 15e+10->4e+10 ). But I am running into the problem if I need to replace the value with a value whose length is longer than already in the file (ex. 6e+2->16e+10) it will write over the new line character or start writing over the information in the next line.
I have searched on the forums and everyone says you can either overwrite in the file, you can append to the end of the file, or you can buffer and recreate the whole file. Is there anyway I can achieve my goal of overwriting the value correctly without having to recreate the file?
If not then how can I have 2 files open (1 input 1 output) to do this if multiple files in question are too large for the memory?
Note: I would also like to avoid using boost:: as I need to be able to run this on a system without the boost library.
Open a stream to read from the input (IN) file and a second stream (OUT) to write to a new output (tmp) file.
Read from IN and write to OUT. When you get a value from IN that you want to replace write the replacement to OUT instead of the value you got from IN.
When parsing is complete replace the first file with the second (tmp) file.
Would this work for you?
Use lseek()/fseek() for "jump" to a given position in a file.
You can use seekp to go to the location and rewrite it with <<
Example:
example.txt ( |?| = 1 byte of data )
|A|B|C|\n|1|2|3|D|E|F|\n|4|5|6|
//Somewhere in the code
fstream file;
open("example.txt");
//Somehow find the character distance and store it into "distance"
seekp(distance);//If distance = 0, it will go to "A" like rewind() but easier for me
If the distance is 4, the next character will be overwritten is 1
file << "987";
And the file will be
|A|B|C|\n|9|8|7|D|E|F|\n|4|5|6|
BUT the only problem here is when you need to increase/decrease the size:
Increase:
You will overwrite the other character so you need to create a temp string to store it the rest of data or separate it into smaller chunk if the data is too large like
|A|B|C|\n|9|8|7|D|E|F|\n|4|5|6|
string tempstring;
seekp(distance);
file >> tempstring;
seekp(distance);
file << content << tempstring; //content is the data
Decrease:
The easiest solution is to write NULL character \0 to the excess space like
|A|B|C|\n|1|\0|\0|D|E|F|\n|4|5|6|
The only side-effect is the file size is the same as before