Click here to Skip to main content
15,879,535 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am new in C. I am using C with QT-4. I am trying to write the text file having two colums .
Here is my text file that is space separated

C++
hi	Name
hi	Grade
DDD	Class
EEE	Grade2
BBB	Class3
ky	Grade3
DDD	Class4
EEE	Grade4


Here is my code
C++
int i, n=2;

char str[50],Name[50],Class[50],Grade[50],var1[50],var2[50];
FILE *fptr;


FORM Loading but
not Updating



I am writing above of text file(having space separated 2-column) with the value i get from three QLineEdits text fields replacing text three respective rows for which string match.

What I have tried:

Here is code that i am trying but not working
C++
void newForm::Update(){    
    fptr = fopen("/root/Desktop/simple.txt", "r+");
    char buf[100];        
    #define  VFMT " %29[^ , ]";
    strcpy(Name,widget.lineEdit_1->text().toUtf8());
    strcpy(Class,widget.lineEdit_2->text().toUtf8());
    strcpy(Grade,widget.lineEdit_3->text().toUtf8());
    while(fgets(buf,sizeof buf,fptr) != NULL){
       int n;
       if(3 == sscanf(buf,VFMT " " VFMT " " VFMT "%s", Name "%n",Class"%n",Grade"%n",&n) && buf[n] =='\0'){
            if(fprintf(fptr,VFMT,Name,Class,Grade)<0)
		if (fptr == NULL)
			{
				printf("Could not open file");
			}
		   for(int i=0;i<5;i++) 
		   {
				
			if( strcmp(var2,"Name") == 0)     
			 {
				//out<<std::setw(10)<<Name;
				fprintf(fptr,"\n%s",Name);           
			 }

			if( strcmp(var2,"Class") == 0)
			 {       
				fprintf(fptr,"\n%s",Class);
			 }

			if( strcmp(var2,"Grade") == 0)
			 {
				fprintf(fptr,"\n%s",Grade);
			 }


        }else
            break;
    
    }
    
}

How i write the values of value of these three row having key Name ,Class,Grade using above code that is not working?
How to parse this txt file for writing ?

Note: I have successfully done the reading
Posted
Updated 25-Dec-22 19:54pm
v8

You are trying to write to the file while you read from it: that only works if the data lines are all exactly the same length, and you seek to the right position each time you want to read or write: mixing reads and writes in a normal text file is a bad idea!

This may help: That's not a database, dude![^]
 
Share this answer
 
First there are few problems with your code. Before addressing those, here are a few other things I would do. First, define a type for the strings you are using. :
C
const int StrSize = 49;
typedef char textStr[ StrSize + 1 ];
The +1 is used so you don't have to subtract 1 to get the size of the buffer minus a spot the null character. Second, I would use primarily local variables declared within the function. You will see this in the code.

About that code, it doesn't make sense to me why you update three variables from three widgets and then overwrite those values with data from the file. Also, why is i looping 5 times and doing the same thing with the same data each time? That also doesn't make sense.

Before I get into the revised code I want to make one small point about outputting data. I always try to leave the cursor at the front of a line (position 0) when ever possible. That makes it easier because you always know where it is when you start and you can reset it every time by placing the newline character at the end of the line. The revisions will do this.

So here is revised code with the for loop on i omitted :
C
#define  VFMT " %29[^ , ]";

void newForm::Update(){
    FILE * fptr = fopen("/root/Desktop/simple.txt", "r+");
    if (fptr == NULL)
    {
        printf("Could not open file");
        return;
    }

    textStr str, name, class, grade, var1, var2;

    char buf[100] = { 0 };

    // here is the -1 I mentioned previously for the null character

    while(fgets( buf, sizeof( buf ) - 1, fptr ) != NULL){
        int n;
        if(3 == sscanf(buf, VFMT " " VFMT " " VFMT "%s", name"%n", class"%n", grade"%n", &n ) && buf[n] =='\0'){
             const char * text = nullptr;	

             // where is var2 set ????

             if( stricmp( var2,"Name") == 0)    // case insensitive comparison
                 text = name;
             else if( stricmp( var2,"Class") == 0)
                 text = class;
             else if( stricmp( var2,"Grade") == 0)
                 text = grade;
             else
             {
                 fprintf( stderr, "error - unrecognized item : '%s'\n", var2 );
                 break;
             }

             // output value

             fprintf( fptr," %s\n", text );   // add a separating space
        } else
             break;
    }
    fclose( fptr );
}
This doesn't do exactly what you want because I can't make sense of what's going here. To use fprintf to generate a fixed-width output , 3 wide, you can do this :
C
fprintf( fptr, "%3s", stringValue );   // for right-justified text
fprintf( fptr, "%-3s", stringValue );  // for left-justified text
Best of luck with it.
 
Share this answer
 
Comments
Member 8840306 26-Dec-22 10:27am    
if(3 == sscanf(buf, VFMT " " VFMT " " VFMT "%s",name"%n",class"%n",grade"%n",&n) && buf[n] == '\0')


It is giving this error

newForm.cpp.cc:126: error: expected ‘)’ before ‘;’ token
newForm.cpp.cc:126: error: expected ‘)’ before ‘;’ token
Rick York 26-Dec-22 15:07pm    
See if something was lost in translation. Copy and paste what you had for that line and then change the variable names as I made them and see what happens.

I noticed a potential problem just now. I named a variable 'class' and that could be a problem. You might want to change it to clas with one 's' to be safe.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900