Hi All,
Following code gives me an error when I use text field in CSV file instead of float or integer fields.

matrix_points[cnt][4] = atoi(line);
May be the problem with above line. Please see the below code

char matrix_points[6][8];



std::ifstream input_file("C:/NDA/NissanNewApplication/Dev/CommonErrorManager/Src/ErrorMessageList.csv");
int cnt(0);
printf("initial valie of cnt = %d\n",cnt);
char buffer[256];
char line[255];



input_file.clear();
input_file.seekg(0);


while(!(input_file.eof()))
{
input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][0] = line;
//printf(" %s", line);


input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][1] = atoi(line);
//printf(" %s", line);



input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][2] = atoi(line);
//printf(" %s", line);


input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][3] = atoi(line);
//printf(" %s", line);


input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][4] = atoi(line);
//printf(" %s", line);


input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][5] = atoi(line);
//printf(" %s", line);


input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][6] = atoi(line);
//printf(" %s", line);


input_file.getline(line, sizeof(buffer), ',');
matrix_points[cnt][7] = atoi(line);
//printf(" %s", line);
cnt++;
}


for (int i=0; i<cnt; i++){


printf("%s", matrix_points[0]);
printf("  %s", matrix_points[1]);
printf("  %s", matrix_points[2]);
printf("  %s", matrix_points[3]);
printf("  %s", matrix_points[4]);
printf("  %s", matrix_points[5]);
printf("  %s", matrix_points[6]);
printf("  %s\n", matrix_points[7]);
}

Recommended Answers

All 19 Replies

>>Following code gives me an error when I use text field in CSV file instead of float or integer fields

what compiler? post the errors. The compiler should give you warnings that it is converting int to char and may lose data.

what does the csv file look like -- can you post the first two or three lines? Are the values between -127 and 126 because that is the range of signed char. If the csv file contains larger numbers then you will have to redeclare the matrix as a 2d array of ints, not chars

int matrix_points[6][8];

and the while loop is incorrect. use of eof() is unpredictable.

// while(!(input_file.eof()))
//{
while( input_file.getline(line, sizeof(line), ',') > 0)
{
   // blabla
}

>> printf("%s", matrix_points[0]);
all these lines are incorrect -- %s expects a null-terminated string, and what you are passing is just one character. They should look like this

printf("%s", matrix_points[i]);

This assumes that the array is null-terminated strings. If not, then %s will not work -- probably crash your program. In that case, change %s to %c as your original post

printf("%c", matrix_points[i][0]);

Finally, you can use loops to make the program more efficient. You can replace all those getline()s with just this one.

int r = 0, c = 0;
while( input_file.getline(line, sizeof(line), ',') > 0)
{
   matrix_points[r][c] = (char)atoi(line);
   ++c;
   if( c == 8)
   {
        r++;
        c = 0;
   }
}

Hi Dragon,
This is how the csv file looks

ECU ID FuncID TstID TstStatus ResType ResCode codeTxt deftText
* * * * * * Default Default
ECU_MODEL_KWP_ECCS 4 WS-2-1 * * * 1 Emergency stop
ECU_MODEL_KWP_ABS 3 AT-2-01 * * * 2 Stop test
...
...
As of now I have 6 rows and 8 columns. In future rows may increase and column might also change. So how can we make it dynamic. But first I want my static one to work. Would appreciate your support in this regard.

Narender

Its a VC++ compiler and gives the following message

error C2440: '=' : cannot convert from 'char [255]' to 'char'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast

>>Following code gives me an error when I use text field in CSV file instead of float or integer fields

what compiler? post the errors. The compiler should give you warnings that it is converting int to char and may lose data.

what does the csv file look like -- can you post the first two or three lines? Are the values between -127 and 126 because that is the range of signed char. If the csv file contains larger numbers then you will have to redeclare the matrix as a 2d array of ints, not chars

int matrix_points[6][8];

and the while loop is incorrect. use of eof() is unpredictable.

// while(!(input_file.eof()))
//{
while( input_file.getline(line, sizeof(line), ',') > 0)
{
   // blabla
}

>> printf("%s", matrix_points[0]);
all these lines are incorrect -- %s expects a null-terminated string, and what you are passing is just one character. They should look like this

printf("%s", matrix_points[i]);

This assumes that the array is null-terminated strings. If not, then %s will not work -- probably crash your program. In that case, change %s to %c as your original post

printf("%c", matrix_points[i][0]);

Finally, you can use loops to make the program more efficient. You can replace all those getline()s with just this one.

int r = 0, c = 0;
while( input_file.getline(line, sizeof(line), ',') > 0)
{
   matrix_points[r][c] = (char)atoi(line);
   ++c;
   if( c == 8)
   {
        r++;
        c = 0;
   }
}

This is the format

ECU ID Function ID Test ID Test Status Response Type Response Code codeText defaultText
* * * * * * Default Default
ECU_MODEL_KWP_ECCS 4 WS-2-1 * * * 1 Emergency stop
ECU_MODEL_KWP_ABS 3 AT-2-01 * * * 2 Stop test
ECU_MODEL_CAN_ABS 4 WS-2-1 * * * 3 Adjustment finished
ECU_MODEL_CAN_LDW 4 WS-1 * * * 4 Stop

Ah, I see.
It's that new style of CSV file without any comma's in it :rolleyes:
Perhaps the fields are separated with a tab character instead.

> char matrix_points[6][8];
Perhaps
std::string matrix_points[6][8];
would be better for storing things.

I am facing a problem while assigning the line value to two dimensional array.
So how should I assign the value of line variable to the two dimensional array as follows

Basically I want to read all the values in the matrix. Based on these values I have to conditionally replace the values in my application. That is for a given row I want to find the value of particular field in the row and then extract the the value of other field in the same row using the matrix(2-D array). Here is my

int matrix_points[6][8];


std::ifstream input_file("C:/NDA/NissanNewApplication/Dev/CommonErrorManager/Src/ErrorMessageList.csv");


char line[255];


input_file.clear();
input_file.seekg(0);
int r = 0, c = 0;


while( input_file.getline(line, sizeof(line), ','))
{
matrix_points[r][c] = (char)atoi(line);
++c;
if( c == 8)
{
r++;
c = 0;
}
}


//Retrieving Value


for (int i=0; i<r; i++)
for(int j=0; j<c; j++)
{
printf("%s", matrix_points);
}

Error comes when I assign the value of line to matrix array and when I try to display the value of this matrix with specific dimension. E.g matrix_points[1][7]

So basically the problem is : storing the value in matrix_points and extracting the values

No error is displayed but I don’t get the expected output.

Its obvious from the fle contents that atoi() won't work because the file contains a mixture of text and numbers. And since that is NOT a comma-separated file attempting to read up to the comma will fail. As Salem mentioned the columns must be separated by tabs or just simply spaces.

here is a way to do it without any knowledge of the number of words on a line. matrix_points must be defined as a 2d array of strings -- you have it declared as a 2d array of characters. You can't store an entire string in just one character.

const int ItemsPerRow = 8;
typedef std::vector<string> C;
int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<C> matrix_points;
	C words;
	std::ifstream input_file("C:/NDA/NissanNewApplication/Dev/CommonErrorManager/Src/ErrorMessageList.csv");
	int c = 0;
	std::string line;
	while( getline(input_file,line) )
	{
		// now bust the line up into individual words
		while(line != "")
		{
			int pos = line.find(' ');
			if(pos > 0)
			{
				words.push_back(line.substr(0,pos));
				line = line.substr(pos+1);
			}
			else
			{
				words.push_back(line);
				line = "";
			}
		}
		matrix_points.push_back(words);
		words.erase(words.begin(),words.end());
	}
	return 0;
}

Actually yesterday I just copied the content from csv file as it is and therefore looked to be tab/space separated file. Following is the correct format
ECU ID,Function ID,Test ID,Test Status,Response Type,Response Code,codeText,defaultText
*,*,*,*,*,*,Default,Default
ECU_MODEL_KWP_ECCS,4,WS-2-1,*,*,*,1,Emergency stop
ECU_MODEL_KWP_ABS,3,AT-2-01,*,*,*,2,Stop test
ECU_MODEL_CAN_ABS,4,WS-2-1,*,*,*,3,Adjustment finished
ECU_MODEL_CAN_LDW,4,WS-1,*,*,*,4,Stop

Here how do I know the end of line.
I want to read all the value in 2D array and then extract conditionally in the for loop.


Hi Dragon,
This is how the csv file looks

ECU ID FuncID TstID TstStatus ResType ResCode codeTxt deftText
* * * * * * Default Default
ECU_MODEL_KWP_ECCS 4 WS-2-1 * * * 1 Emergency stop
ECU_MODEL_KWP_ABS 3 AT-2-01 * * * 2 Stop test
...
...
As of now I have 6 rows and 8 columns. In future rows may increase and column might also change. So how can we make it dynamic. But first I want my static one to work. Would appreciate your support in this regard.

Narender

Its a VC++ compiler and gives the following message

error C2440: '=' : cannot convert from 'char [255]' to 'char'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast

The code I posted will still work, just replace the space in find() with a comma

int pos = line.find(',');

This(following) is the code I am using which is almost same as yours. Certain c functions are not working in VC++ like push_back, substr etc. Still output is always the first field, i.e. ECU ID in the format above.
Can you please send me the code more in the line of VC++(if not C++ is also OK)

QString linecol;

while(input_file.getline(line, sizeof(line), '\n'))  // to read  lines
{
    while(line != "")
    {
        linecol = line;
        int pos = linecol.find(',');
        field = linecol.left(pos);
        if(pos > 0)
        {

            linecol = linecol.left(pos);  // substr function does not work in VC++. 
            matrix_points[r][c] = linecol;
            printf(matrix_points[r][c]);
            linecol = linecol.left(pos+1);
            ++c;
        }
        else
        {
            matrix_points[r][c] = line;
            linecol = "";
            c = 0;
            r++;
        }           

    }

}

Thanks & Regards,
Narender

>> VC++
That is the name of a specific compiler, not c programming language. Of course it supports c++, vector and push_back. You are writing a c++ program, if you want to use vector c++ class as I illustrated you have to include <vector> header file.

>>QString linecol
QString is a non-standard c++ class that M$ apparently developed for their compilers. I haven't used managed c++. the strings I posted are std::string from <string> header file, and maybe that is why you couldn't get it to work.

>> matrix_points[r][c] = line;

I mentioned this before -- you can't do this because matric_points is a 2d array of characters, not a 2d array of pointers

char *matrix_points[255][255]; // 2d array of pointers

matrix_points[r][c] = new char[strlen(line)+1];
strcpy(matrix_points[r][c], line);
while(input_file.getline(line, sizeof(line), '\n')) // to read lines
{
while(line != "")

how is line declared? if it is a char array, then the code above will not work. If it is QString or std::string it still will not work. You are mixing c and c++ -- attempting to use c++ techniques on C string, or attempting to use C techniques on C++ string class. But I don't know which it is because you didn't post enough code.

Hi,
Yeah line is character array. This is how the following code looks like. Can you please find the area with mistakes and correct it.

QString matrix_points[6][8];
char line[255];
std::ifstream input_file("C:/NDA/NissanNewApplication/Dev/CommonErrorManager/Src/ErrorMessageList.csv");

input_file.clear();
input_file.seekg(0);

int r = 0, c = 0;

QString linecol, field;

while(input_file.getline(line, sizeof(line), '\n'))  // to read  lines
{
    while(line != "")
    {
        linecol = line;
        //linecol = linecol.stripWhiteSpace(); 
        int pos = linecol.find(',');
        field = linecol.left(pos);
        if(pos > 0)
        {           
            linecol = linecol.left(pos);  // substr function does not work in VC++. 
            matrix_points[r][c] = linecol;
            printf(matrix_points[r][c]);
            linecol = linecol.left(pos+1);
            ++c;
        }
        else
        {
            matrix_points[r][c] = line;
            linecol = "";
            c = 0;
            r++;
        }           
    }
}
while(input_file.getline(line, sizeof(line), '\n')) // to read lines
{

linecol = line;
while(linecol != "")
{

int pos = linecol.find(',');
field = linecol.left(pos);
,,,

std::string.substr(...) is similar to QString's mid method.
http://doc.trolltech.com/3.3/qstring.html

Hi Dragon,
Thanks for the reply. It works. Now the problem comes when I assign the matrix_points, which is of type QString to a variable in my application which is of ACE_WString Type, it gives a problem. What kind of typecasting method can we apply to overcome it?

Thanks & Regards,
Narender

I don't know why you are using those odd-ball, non-standard c++ classes, maybe the university requires them? But anyway, looks like ACE_WString has a constructor that takes const char*, so just pass the right QString method that makes that conversion for you. You'll have to look it up.

QString str = "Hello World";
ACE_WString wstring(str.??());

This is what my whole code looks like. I am unable to locate the constructor which would help store into my codeText variable(ACE_WString) the value of matrix_points(QString). As you see the paramter in the function of my application requires me to pass ACE_WString type. Basically I want to assign QString type value to ACE_WString variable.

Follwoing is the error

C:\NDA\NissanNewApplication\Dev\CommonErrorManager\Src\CCommonErrorManager.cpp(193) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class QString' (or there is no acceptable conversion)


int CCommonErrorManager::requestErrorHandling(ErrorEvent& ev, ACE_WString& codeText, ACE_WString& defaultText, int& functionID,ACE_WString& testID, int& testStat)
{

    QString matrix_points[6][8];
    //std::ifstream input_file("C:/NDA/NissanNewApplication/Dev/CommonErrorManager/Src/ErrorMessageList.csv");
    std::ifstream input_file("../../Src/ErrorMessageList.csv");

  char line[255];
input_file.clear();
  input_file.seekg(0);

int r = 0, c = 0, colcnt = 0;
QString linecol, field;

while(input_file.getline(line, sizeof(line), '\n'))  // to read  lines
{
    linecol = line; 
    while(linecol != "")
    {           
        //linecol = linecol.stripWhiteSpace(); 
        int pos = linecol.find(',');            
        if(pos > 0)
        {

            //linecol = linecol.left(pos);  // substr function does not work in VC++. 
            matrix_points[r][c] = linecol.mid(0,pos);
            //printf(matrix_points[r][c]);
            //printf(" ");
            linecol = linecol.mid(pos+1);
            c++;
        }
        else
        {
            matrix_points[r][c] = linecol;
            //printf(matrix_points[r][c]);
            linecol = "";
            colcnt = c;
            c = 0;
            r++;
            printf("\n");
        }                   
    }
}

//Retrieving Value
ACE_WString wStr = codeText;
ACE_TString tStr = ACE_Wide_To_Ascii(wStr.c_str()).char_rep();

   for (int i=0; i<r; i++)             
     if(matrix_points[i][0] == "ECU_MODEL_KWP_ABS")
       {
            //printf(matrix_points[i][3]+" " );
            //printf(matrix_points[i][6]+" " );
            //printf(matrix_points[i][7] + "\n");

         [QUOTE]codeText = matrix_points[i][6];[/QUOTE]
         //codeText (const char *matrix_points[i][6], ACE_Allocator *alloc = 0);

       }


    //Initializing the output parameters codeText & defaultText. Both of these need to be searched in the database.
    //codeText = L"";
    defaultText = L"";

    /*
    Acquiring Response Code
    ev.getEvent() -> Response code such as 21h,23h
    */
    int rcode;
    rcode = ev.getEvent();      



        /* ev.getType -> Error Type */

        if(ev.getType() == ErrorEvent::Unknown)   
        {           
            LOGI(ACE_TEXT("Error Type:[Unknown]\n"));
            /* Channel_Error_Notification -> No Response */
            if(ev.getNewState() == ICommManager::CHANNEL_ERROR_NOTIFICATION)
            {               
                LOGI(ACE_TEXT("Channel Error Notification....[No Response]"));
                m_pLCP->reLink();
                //m_pLCP->ReTry();
                return 2;
            }
            else if((ev.getNewState() == ICommManager::NACK_COMMAND) || (ev.getNewState() == ICommManager::NACK_EPI)) 
                {
                    switch(rcode)           {   

                    LOGI(ACE_TEXT("Determining Response Code"));            

                    /* Negative Response  21h and 23h */
                    case 0x21 : 
                    case 0x23 :                     
                            LOGI1(ACE_TEXT("The Response Code is [%x]"),rcode);
                            //ev.getSource() -> For ECUID.
                            if(ev.getSource() == "ECU_MODEL_CAN_SMKEY") //tStr<-->"ECU_MODEL_CAN_SMKEY"
                                {                                       
                                    LOGI(ACE_TEXT("Checking ECU Id....ECU_MODEL_CAN_SMKEY"));
                                    LOGI(ACE_TEXT("[ReLink] and [ReTry()] are called"));
                                    m_pLCP->reLink();                                   
                                }
                            else
                                {                                       
                                    LOGI(ACE_TEXT("Only [ReTry()] is called")); 
                                    m_pLCP->retry();
                                }              
                        return 2;
                        break;
                        /* Negative Response 78h */
                        case 0x78: 
                                LOGI(ACE_TEXT("Negative Response Code : [78h]"));                               
                                return 1;
                                break;
                        default:                    
                            LOGI(ACE_TEXT("Response Code other than 21h,23h,78h"));
                                if(ev.getSource() == "ECU_MODEL_CAN_SMKEY" && counter == 0) //tStr<-->"ECU_MODEL_CAN_SMKEY"
                                    {                                           
                                        LOGI(ACE_TEXT("ECU Id: [ECU_MODEL_CAN_SMKEY]"));
                                        counter = counter + 1;
                                        m_pLCP->reLink();                                       
                                        return 2;
                                    }
                                    else    
                                    {                                       
                                        codeText = L"Default";
                                        defaultText = L"Default";
                                        LOGI(ACE_TEXT("Displaying Error in GUI"));
                                        /* set the counter to 0 */
                                        counter = 0;
                                        /* Callback Function */
                                        //m_pCB->showErrorScreen(); 

                                        return 3;
                                    }                   
                            break;
                    }                   // end of switch
                }                       // end of else if of getNewState()=CHANNEL_ERROR_NOTIFICATION
            else                        // else of getNewState()=NACK_COMMAND OR NACK_EPI
            {               
                codeText = L"Default";
                defaultText = L"Default";
                LOGI(ACE_TEXT("Unknown Error is  encountered."));               
                return 3;                                               
            }

        }                               // if getType()

        else                            // Else of getType()
        {               
            codeText = L"Default";
            defaultText = L"Default";       
            LOGI(ACE_TEXT("A problem has occured at hardware level"));              
            return 3;
        }   
    //return 3;

}                                       //  end of Function

Here is the version of ACE_WString whose second constructor takes char*. I have no way of knowing if that's the same one you are using.

QString has two methods that you may be interested in -- ascii() that returns char*, and unicode() that appears to make the ascii to unicode conversion for you.

QString str = "Hello";
ACE_WString w(str.ascii());

I'm just sort of guessing about the above because I don't have either of those classes.

Hi Dragon,
Thank you. Actually I am able to manipulate the values from the csv file based on the row,column concept. I have now need to manipulate the values based on the header names. Concept being same as last, I would like to query based on column names.

Thanks & Regards,
Narender

Your dilema seems vague. I assume you have developed a 2 dimensional table of values like tableName[rowIndex][colIndex] and each column has a name/header/identifier. I further assume you want to be able to find a given column identified by it's name/header/identifier and be able to access the elements of the column to manipulate them in some fashion. If that's correct, then you can view the headers to be a row of data just like a row of values making up the body of the table itself and use a loop to search for the header/identifier you want. To do that you can hold the row index stable and vary the column index. Then to access all the values in the column you hold the column index stable and vary the row index.

Hi Lerner,
Thanks! So far I have done the same. My next step is to match the value till couple of columns in a row and if 2 rows are almost similar the value for the row which matches more closer should be displayed.

A glimpse of my code

for (int i=0; i<r; i++)
 {
    if( matrix_points[i][0] == ACE_Wide_To_Ascii(wEcuId.c_str()).char_rep()) 	   
    {
     printf("\nEntered");
     printf(matrix_points[i][1]);
    if(atoi(matrix_points[i][1]) == functionID)  		 
    {
     printf("Entereted functionID\n");
     if(matrix_points[i][2] == ACE_Wide_To_Ascii(testID.c_str()).char_rep()) // Comparing TestId in Excel file with the input TestId
     {	
       printf("Entered testID\n");
      if(atoi(matrix_points[i][3]) == testStat)  // Comparing TestStatus in Excel file with the input TestStatus
    {
     printf("Entered testStatus\n");
    if(atoi(matrix_points[i][4]) == ev.getNewState())  //Comparing ResponseType in Excel file with ErrorEvent's ResponseType
     {
      printf("Entered ResponseType\n");
     if(matrix_points[i][5] == ev.getEvent())  //Comparing ResponseCode in Excel file with ErrorEvent's ResponseCode
     {
      printf("Entered ResponseCode\n");
      qStrCT = matrix_points[i][6];
      printf(qStrCT);
     ACE_WString wStrCT ((const ACE_WCHAR_T *) qStrCT.unicode(), qStrCT.length());
     ACE_TString tStrCT = ACE_Wide_To_Ascii(wStrCT.c_str()).char_rep();
     ct = wStrCT;

      //Retrieving Defaulttext
     qStrDT = matrix_points[i][7];
     printf(qStrDT);
     ACE_WString wStrDT ((const ACE_WCHAR_T *) qStrDT.unicode(), qStrDT.length());
     ACE_TString tStrDT = ACE_Wide_To_Ascii(wStrDT.c_str()).char_rep();
     dt = wStrDT;			
   //LOGI1(ACE_TEXT("Veena:matrix_points[i][7] change to ACE_WSTRING.[%s]"),ACE_Wide_To_Ascii(wStr.c_str()).char_rep());
  }
  else
 {
      qStrCT = matrix_points[i][6];
      printf(qStrCT);
     ACE_WString wStrCT ((const ACE_WCHAR_T *) qStrCT.unicode(), qStrCT.length());
     ACE_TString tStrCT = ACE_Wide_To_Ascii(wStrCT.c_str()).char_rep();
     ct = wStrCT;

      //Retrieving Defaulttext
     qStrDT = matrix_points[i][7];
     printf(qStrDT);
     ACE_WString wStrDT ((const ACE_WCHAR_T *) qStrDT.unicode(), qStrDT.length());
     ACE_TString tStrDT = ACE_Wide_To_Ascii(wStrDT.c_str()).char_rep();
     dt = wStrDT;			
   //LOGI1(ACE_TEXT("Veena:matrix_points[i][7] change to ACE_WSTRING.[%s]"),ACE_Wide_To_Ascii(wStr.c_str()).char_rep());
      }
     }
    }
   }			 
  }
 }
}

Thanks & Regards

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.