incrementation produces error

Hi,

I hope you can help me with some (as I think) strange problem. I'm trying to read data out of a comma separated value file and put it into some variables. I have started programming with C and it worked so far, but for further evaluation of the data I skipped to C++ and tried to "translate" the old program to some more C++-like commands. Now I have the following program, shortened in some hopefully unimportant parts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;

#define CHARS 15
#define PATH "D:/"

char t, tt;
int n= 0, nline= 1, ncolumn= 1;

int cellcount()
{   ifstream fcount (PATH"/Assay9-Daten.csv");
    if (!fcount.is_open())
    {   cout << "ERROR - unable to open file" << endl;
        return 1;
    }
    while ((t= fcount.get()) != EOF)
    {   if (t == '\n') nline++;
        if (nline == 1) {if (t == ';') ncolumn++;}
    }
    fcount.close();
}

int main()
{   int line= 0, column= 0, i= 0;
    char cellc[nline][ncolumn][CHARS;
    
    cellcount();

    ifstream fin (PATH"/Assay9-Daten.csv");
    while (fin.good())
    {   switch (tt= fin.get())
        {   case ';': {column++; i= 0; cout << " | "; break;}
            case '\n': {line++; column= 0; i= 0; cout << endl; break;}
            default: {cellc[line][column][i]= tt; cout << cellc[line][column][i]; i++;}
        }
    }
    fin.close();

    [...]
    cout << nline << " -- " << ncolumn << " -- " << endl;
    return 0;

    [...]
}


Unfortunately, this program produces some kind of segmentation fault (or something like this), while compiling without errors or warnings. I was able to point out that the error happens within the default statement of the switch structure. After trying some other thing, I think that it has something to do with the incrementation. It puts the values out until some point where the program just crashes.
The strange thing is that there's a somehow similar while loop in the function 'cellcount' which works well. There are 408 rows and 6 columns that should be read (each cell hat up to 12 characters), but program crashes around line 20 of output.

Do you know what's going on there?
Thanks a lot,

Thommi.
Last edited on
This is already invalid code

1
2
3
    char cellc[nline][ncolumn][CHARS], err[nline][ncolumn][CHARS];
    double celld[nline][ncolumn];
    char *cellerr[nline*ncolumn];


because C++ requires that sizes of arrays were constant expressions at compilation time.
Last edited on
But the C-program had the same declarations and did well also with C++ compiler. C-header files shouldn't change such requirement, do they?

And if I'm wrong with that: can it really be possible that I cannot make an array where the program has to evaluate at first the number of elements?

Thank you.
Last edited on
Variable length arrays exist only in C, although g++ also supports VLAs as an extension.
C++ has a superior alternative: vectors.
And I think the error is the result of the mentioned invalid declarations.
Last edited on
Okay, then I guess I have to proceed somehow in reading my C++ tutorial to inform about vectors.
Maybe I will come back to that topic afterwards.
Thank you both for your help!
Last edited on
Well, after searching for vectors outside of the tutorial, I got it to work. Thanks again. The tutorial only mentioned declaring array with dynamic memory allocation using new, which would probably also work if my understanding of pointers (especially multidimensional ones) would be some better.

To overcome this, can you tell me if the following declaration would have correctly lead to a 2D-array of strings?
1
2
3
4
5
string **cells;
*cells= new string* [nline];
for (i= 0; i<nline; i++)
{   cells[i]= new string [ncolumn];
}

I quess something with the declaration of the dimension sizes would not be working here.

Another problem came up after using vectors: after reading out the cells of my csv-file to a vector of vectors of strings, I tried to convert those strings to double. I did this before with strtod(...) with getting a kind of error value if the string cannot be converted to double (which is important for me). Now if I use an element of my new vector of vectors as first argument of strtod my compiler gives the following error message:
|61|error: cannot convert 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to 'const char*' for argument '1' to 'double strtod(const char*, char**)'|

Since - as I think - this is touching again my bad understanding of pointers, I don't know how to overcome this problem.
Can you help me?

Thank you again,

Thommi.
Last edited on
To get a C string from a std::string, call the member function c_str().
Okay, I already read about this member function but didn't think further about it...
And I guess getting an error variable like in strtod, but without C functions (and without <cstdlib>) would require exception handling for some stringstream functions, right?

However, it works so far. And how about my mentioned dynamic memory array declaration?

Thank you.
And I guess getting an error variable like in strtod, but without C functions (and without <cstdlib>) would require exception handling for some stringstream functions, right?

stringstream doesn't throw exceptions, it sets the stream's fail flag when it fails. You can check that with fail().

And how about my mentioned dynamic memory array declaration?

In line 2, you're derefencing a pointer that does not point to anything valid and you're trying to assign a string** to a string*. You should use a vector of vectors or a wrapper class that uses an one-dimensional vector internally.
I found the solution here: http://www.cplusplus.com/forum/articles/7459
with a nice and easily understandable comparision between both methods (vectors/arrays).
Now I think I understand it a little bit better.

Thank you for your answers.
Topic archived. No new replies allowed.