C++ Simple File I/O: Tips & Solutions

  • C/C++
  • Thread starter DivGradCurl
  • Start date
  • Tags
    C++ File
In summary, the problem is that you are trying to read a string with spaces in it. You can do this by using C style strings which means that you have to use "str[0]".
  • #1
DivGradCurl
372
0
I'm trying to come up with a C++ program that reads input from a text file. Each line of this text file has a different variable. I have different data types (int, string, char). I'm having difficulty to read strings with spaces and read char's. The rest seems to work fine. If possible, I'd like to hear some tips on how to improve my work. I've already searched the web several times, but I haven't been able to find a solution. The programs (one that creates 20 blocks of inputs and the other which reads each block) are attached.

Any help is highly appreciated.
 

Attachments

  • MakesData.txt
    513 bytes · Views: 405
  • ReadsData.txt
    946 bytes · Views: 421
Technology news on Phys.org
  • #2
Do you have to use ifstream? Could you use fscanf?

The syntax would be something like this:

FILE *fp ;

fscanf(fp "%d %s %s %f %s %s", &id, name, description, &cost, department, color);

This is the way I like to do it. It is a much cleaner approach.
 
Last edited:
  • #3
yah fscanf/fprintf are so much better. but can you have those spaces in theredduardo? %d %s or is it %d%s?
 
  • #4
You can have whatever you want. Tabs, newlines, spaces, characters, etc.
 
  • #5
It seems that the approach suggested is from C. I don't know whether or not that can be used as if it were C++ code. There are no compilation errors, but I don't get output from the program. I've uploaded a text file with what I have now. I'm a bit lost.

Thanks for your help, folks.
 

Attachments

  • ReadsData.txt
    395 bytes · Views: 412
  • #6
You have to use C style strings, which means:

char mystring[n] ; //Use this if you know the size of the field

or

char **mystring ; //Use this if you don't know the size of the field
 
Last edited:
  • #7
Processing user input in both C and C++ can give you a headache because of little details. Reading a string with "scanf" or "cin <<" will only read one word at a time, stopping at any whitespace. C function "gets" reads a whole line but does not check for overflow so you get subtle errors that mysteriously happen once in a while, not always. Function "fgets" does not remove the trailing '\n' from the input buffer so you have to remember to do it manually. Reading pretty much anything with "cin <<" in C++ can cause the same problem: the '\n' remains in the buffer so when you read a test line with "getline" after an integer then all you get is an empty one (from the newline chatracter); then the next call to read an integer causes an input error. All sort of annoying little details like this.

Here's my approach to resolve these annoyances. Whenever you have separate data items on separate lines, read each line as plain text first. In C++ you can use the "getline" function for this:

string str;
while (getline(cin, str)) {
// Do something with str.
}

You can replace "cin" with any other stream if you're reading from a file instead of the console. Once you have a line of data into a string, if you know what is in it then use an appropriate conversion function to convert it. It's not a sin to use some of the C functions for this (with str.c_str() to get a C char*), so use "atoi" to convert alpha to integer, use "atof" to convert alpha to float, leave the string as is if a string is what you need, use str[0] if all you want is the first character. It's simple and it works consistently.
 
  • #8
Sorry for the delay. I've been trying to figure out the code...

Thank you so much, my program is beginning to function!

I am just having a problem reading the char datatype. I cannot pass it to a c++ char variable without using a conversion trick. Is there a way to accomplish this?
 
  • #9
I've just found a way to incorporate Orefa's suggestion to the char problem. It does work! Now I just get a strange "0" in my last line of the final output file. Maybe it's just simpler to picture this by looking at the files attached. The first c++ code (see GenerateInputFile.txt) generates the input txt file whereas the other c++ code (see InOut.txt) reads it and writes an output txt of what has been read. That's where the '0' appears. :confused:
 

Attachments

  • InOut.txt
    1.6 KB · Views: 491
  • GenerateInputFile.txt
    557 bytes · Views: 447
  • #10
If your data file ends with a redundant newline character then the loop will repeat one time too many and your first IF clause will convert an empty line (caused by this lone '\n' character) into an integer. This will generate the 0 you're seeing.

What you should do is check for an empty line at the top of the loop. If the line length is zero then break out of the loop.

By the way, you know that you can simplify your code a great deal. Now that you've done all the work... :smile: No need for an array of strings, you can reuse only one. You can also eliminate a lot of repetitious code. Consider this simplified version (which I didn't try to compile and run, I hope it isn't too buggy):
Code:
int main() {
    int      count = 0;
    string   line;
    ifstream in("myProducts.txt");
    ofstream out("OUTPUT.txt");

    while (getline(in, line) && line.length() > 0) {
        switch (count % 5) {
            case 0: out << atoi(line.c_str());  break;  // ID
            case 1: out << line;                break;  // Name
            case 2: out << atof(line.c_str());  break;  // Cost
            case 3: out << line[0];             break;  // Department
            case 4: out << line;                break;  // Color
        }
        cout << endl;
        ++count;
    }
    out << "# LINES READ = " << count << endl;
    in.close();
    out.close();
    system("pause");
    return 0;
}

Edit: I realize that the above code does away with many variables you may need to keep. It is just to illustrate possible simplification methods.
 
Last edited:
  • #11
Thanks, Orefa!

Indeed, your approach greatly simplifies the problem. I managed to get something working the way it was supposed to! The purpose of these programs is to simply ensure that the inputs I read from a text file are accurate. Now I can play with the data, and hopefully have some fun. :smile:

I have a lot to learn. Thanks for your support, guys.
 
  • #12
dynamic objects

I'm wondering if any of you know how to dynamically create instances of a class. I've been trying, but all that I can do is read one single block of input from a text file. I've attached my work.

Any help is highly appreciated.

Thanks!
 

Attachments

  • item (dot h).txt
    1.4 KB · Views: 386
  • ListIN.txt
    96 bytes · Views: 422
  • Main (dot cpp).txt
    2.2 KB · Views: 448
Last edited:
  • #13
You can dynamically create instances of a class using the new operator.

However, i guess you would also like to keep access to all the objects that you have created, which is not that simple unfortunately, but its not very hard either.

Since we need to keep reference to all the objects created, we will maintain them in a linked list. The nodes of the linked list will have the following members,

1. A pointer of type <class>
2. Next node pointer

Basic node step creation would be as follows,
1. Create an instance of linked list node
newnode = new LinkedListNode()

2. Connect the newly created node to previously maintained Linked List,
tail->nextnode = newnode
tail = newnode
**tail is a pointer which is maintained so as to always point at the tail of the linked list. Correspondingly, we need also to maintain a head pointer which points to start of the linked list.

3. Assign memory to the <class> pointer inside the new instance just created.
tail->classptr = new <class>()

Thus, you have dynamically created a new instance of class and at the same time you have maintained all the objects you have created so far. You can access each of these objects by traversing the list from head to tail.

-- AI
P.S -> Linked List is a form of data structure that helps you maintain "things" (in your case "things" were class objects) in the form of a list. This is not the only data structure that you can use. You can use anything from stack, queues, hashtables etc etc. to meet your needs and is most efficient as per your requirements.
 

What is the purpose of C++ Simple File I/O?

C++ Simple File I/O, or input/output, allows a program to read from and write to files on a computer. This is useful for storing data, accessing external resources, and creating permanent records of program output.

How do I open a file for reading or writing in C++?

In order to open a file for reading, you can use the ifstream class, and for writing, you can use the ofstream class. Both of these are derived from the fstream class. You can use the open() function to specify the file name and the mode (read, write, append) that you want to open the file in.

What is the difference between a text file and a binary file?

A text file is a file that contains human-readable characters, such as letters, numbers, and symbols. A binary file, on the other hand, contains data in a format that is not necessarily human-readable, such as machine code or compressed data. Text files are usually easier for humans to work with, while binary files are more efficient for computers to process.

How do I read data from a file in C++?

To read data from a file, you can use the getline() or >> operators. The getline() function reads a line of text from the file and stores it in a string variable, while the >> operator extracts data from the file into a variable of the appropriate data type. You can also use the get() function to read a single character at a time.

How do I handle errors when working with files in C++?

When working with files, it is important to handle errors that may occur, such as a file not being found or not being able to open a file for writing. You can use the fail() function to check for errors and the clear() function to clear any existing errors. You can also use the eof() function to check if you have reached the end of the file. It is important to handle these errors to ensure the smooth execution of your program.

Similar threads

  • Programming and Computer Science
Replies
4
Views
3K
  • Programming and Computer Science
Replies
8
Views
877
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
34
Views
2K
  • Programming and Computer Science
Replies
2
Views
2K
  • Programming and Computer Science
Replies
6
Views
1K
  • Programming and Computer Science
Replies
8
Views
2K
  • Programming and Computer Science
Replies
8
Views
5K
  • Programming and Computer Science
Replies
4
Views
5K
  • Programming and Computer Science
2
Replies
55
Views
4K
Back
Top