0

I got a problem using strings. So I had the idea of writing a program, that multiplicates two parenthesis, since I had some with 10 variables each. I put a parenthesis in a .txt file and wanted to read it and just print into another .txt file. I am not sure if it has problems with the specific signs. So here is my txt that I read

2*x_P*x_N - x_P^2 + d_P - 2*x_N*x_Q + x_Q^2 - d_Q

and here is what it actually prints

2*x_--x_P^++d_P-2*x_++x_Q^--

as You can see it is completely wrong. In addition I get an error after executing, but it still prints it into the .txt. So here is my code:

#include <stdio.h>
#include <string>
using namespace std;
int main()
{
    int i;
    const int size = 11;
    string array[ size ];
    FILE * file_read;
    file_read = fopen( "alt.txt", "r" );
    for( i = 0; i < size; i++ ) //Read
    {
        fscanf( file_read, "%s", &array[ i ] );
    }
    fclose( file_read );
    FILE * file_write;
    file_write = fopen( "neu.txt", "w" );
    for( i = 0; i < size; i++ ) //Write
    {
        fprintf( file_write, "%s", &array[ i ] );
    }
    fclose( file_write );   printf("test");

    return 1;
}

Thanks for suggestions. You can put suggestions made with iostream as well.

FrontMobe
  • 136
  • 7
  • Are you just trying to copy the file? Try http://stackoverflow.com/questions/10195343/copy-a-file-in-an-sane-safe-and-efficient-way – Adrian May Apr 07 '15 at 13:39

1 Answers1

2

You are mixing C++ and C forms of file input:

When you write:

    fscanf( file_read, "%s", &array[ i ] );

the C standard library expects that you provide a pointer to a buffer in which the string read in the file will be stored in form of a C string, that is an array of null terminated characters.

Unfortunately, you provide a pointer to a C++ string. So this will result in undefined behaviour (most probably memory corruption).

Solution 1

If you want to keep using the C standard library file i/o, you have to use an interim buffer:

char mystring[1024];     //for storing the C string
...
        fscanf( file_read, "%1023s", mystring );
        array[ i ] = string(mystring);   // now make it a C++ string

Please note that the format is slightly changed, in order to avoid risks of buffer overflow in case the file contains a string that is larger than your buffer.

Solution 2

If you learn C++ (looking at your C++ tag and the string header), I'd strongly suggest that you have a look at fstream in the C++ library. It's designed to work very well with strings.

Here how it could look like:

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main()
{
    const int size = 11;
    string array[ size ];
    ifstream file_read( "alt.txt");
    for(int i = 0; i < size && file_read >> array[ i ]; i++ ) //Read
        ;
    file_read.close();
    ofstream file_write("neu.txt");
    for(int i = 0; i < size; i++ ) //Write
        file_write << array[ i ] <<" "; // with space separator 
    file_write.close();
    cout << "test"<<endl;

    return 0;
} 

And of course, the next thing you should consider, would be to replace classic arrays with vectors (you don't have to define their size in advance).

Christophe
  • 54,708
  • 5
  • 52
  • 107
  • @FrontMobe If you want to use scanf() you have to use an array of char. But I'd much more recommend to use strings with c++ streams. – Christophe Apr 07 '15 at 14:52
  • Well first of all thanks a lot for the detailed answer. I learned c in school and just got some c++ tutorials in the web. So I have struggles with the syntax. Can You explain me this ` for(int i = 0; i < size && file_read >> array[ i ]; i++ ) //Read ` Because you don't do anything in this loop ( I can't really see where ) and if I wanted to save every 2nd string as a different variable. To make 1st a variable, then a +-*/. How can I do this with this loop? Would have done with i%2==0. But what to put into the loop? Thanks again – FrontMobe Apr 07 '15 at 19:15
  • Sure: the usage for C++ streams is to loop on reading (in C you loop on eof). The syntax `file_read>>array[i]` returns a stream, and used in a condition, a stream yields true if read was successful. Here a small tuto: http://www.cplusplus.com/doc/tutorial/files/ and here a SO on stream looping: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – Christophe Apr 07 '15 at 20:58