Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » File I/O

This thread is locked; no one can reply to it. rss feed Print
 1   2 
File I/O
ma3stro
Member #15,329
October 2013

I couldn't figure out how to solve these problems:

1. Getting values from a text file with fscanf, resetting file content, then writing down the new values using fprintf.(the new values should start at the top of the file - rewind() function did not work)

2. How can I print a USTR format to a text file?

Edgar Reynaldo
Member #8,592
May 2007
avatar

Once you're done reading the file, close it, and then either delete it or open it in write only mode. That will reset the file contents. Otherwise, you can only overwrite or append, but not truncate.

And what do you mean rewind didn't work? Post code, and the text file it is supposed to be working on if necessary.

Audric
Member #907
January 2001

For 1), you need something like ftruncate() to reset the (disk) size of a file that is already open in "w+" mode. If it's not available on your platform, you can still use the universal method of :
- open the file in "r" mode,
- read what you need,
- close it,
- open the same file in "w" mode this time.
- write what you need
- close

Aikei_c
Member #14,871
January 2013
avatar

For 2, there are allegro functions which convert ALLEGR0_USTR to c string.

ma3stro
Member #15,329
October 2013

I tried what you told me but it doesn't seem to work on this:

.
.
.

if(code == Bus[5].code)
file1 = fopen("list6.txt", "a+");

for(int j=0; j<32; j++)
fscanf(file1, "%d %c\n", &Seat[j].no, &Seat[j].type);

fclose(file1);

.
.
.

The reason I can't open file in "r" mode is beacuse I'm using the struct values and they're just two members of the struct. And if I use "a+" mode when I reopen the file it starts writing at the end.

It's perfectly reading, when I use the code above. I don't now what to do at the writing part. Whenever I use the "rewind(file1)", program crashes.

Evert
Member #794
November 2000
avatar

Quote:

The reason I can't open file in "r" mode is beacuse I'm using the struct values and they're just two members of the struct.

I have no idea what you're trying to say here.

If you intend to read stuff from a file (as you do with fscanf), open the file with "r". If you intend to write stuff to the file (with fprintf, say), open it with "w" (or "a" if you want to append to the end of the file). If you want to be able to do both, add "+" to the string (note that there's a difference between "r+" and "w+", at least according to the man page; I've never used either).

Quote:

Whenever I use the "rewind(file1)", program crashes.

Just to make sure: you didn't close the file first (with fclose()), did you?

ma3stro
Member #15,329
October 2013

I should be reading "Bus[].no" and "Bus[].type" from the file but there are other members in struct Bus. At first I tried to use "fwrite()" but it writes down the whole struct members and I don't need that happen.

If I open the file in "r" mode it will always read the first line. I'm opening it in "a+" so I can read all the "Bus[1].type, Bus[2].type ..." in a for loop.

Program reads the file correctly, there's no problem at this point. But when it comes to writing, it appends new values to the end of the file.

And I used the rewind() function before closing the file but I got a fatal error.

Gabriel Campos
Member #12,034
June 2010
avatar

Double check the loop of your program. And post some code, so we can help!

Edgar Reynaldo
Member #8,592
May 2007
avatar

ma3stro said:

If I open the file in "r" mode it will always read the first line.

What? You can seek with fseek and fsetpos. But you have to know where in the file you should seek to.

Quote:

I'm opening it in "a+" so I can read all the "Bus[1].type, Bus[2].type ..." in a for loop.

Open it in "r+". That is the read/write mode. If you want to append to the end, use fseek(myfile , 0 , SEEK_END); to move to the end of the file.

rewind shouldn't crash unless you've passed it an invalid FILE*.

Audric
Member #907
January 2001

The file appears to be text ("list6.txt", fscanf() with %d format), so there is no guarantee that the written strings are as long as the previous ones.
I expect trouble if the file is not explicitly truncated. (specifically : if you rewrite only 200 bytes of a 220byte file, the last 20 ones will still be there)

ma3stro
Member #15,329
October 2013

Thank you all for your help. The file reading & writing parts are working just fine. (I used fseek() function)

I haven't found a solution for the 2nd question yet. I had a look at the manual but couldn't figure out which one to use. There is "al_ustr_append_cstr()" function but not the opposite one.

In my project I'm using:

.
.
ALLEGRO_USTR *date= al_ustr_new("");
char *Date;
.
.

I'm getting date from user then print it on the screen. Now I need to assign "date" to "Date" in order to write it on the file. I tried "al_ustr_insert_cstr(date, 0, Date);" but got an error. What am I doing wrong?

Edgar Reynaldo
Member #8,592
May 2007
avatar

ma3stro
Member #15,329
October 2013

#SelectExpand
1ALLEGRO_USTR *date= al_ustr_new(""); 2ALLEGRO_USTR *name= al_ustr_new(""); 3ALLEGRO_USTR *tel = al_ustr_new(""); 4 5char *departure; 6char *arrival; 7char *cost; 8char *time; 9char *bus_code; 10char *gender; 11const char *Date; 12const char *Tel; 13const char *Name; 14. 15. 16. 17Date= al_cstr(date) 18Name= al_cstr(name); 19Tel = al_cstr(tel); 20. 21. 22. 23if(mouse[B1]) 24{ 25 for(int i= 0; i < 32; i++) 26 if(state.x >= Seat[i].x && (state.x <= Seat[i].x + 30) && state.y >= Seat[i].y && (state.y <= Seat[i].y + 30)) 27 { 28 if(Seat[i].type == 'E') 29 al_draw_filled_rectangle(Seat[i].x, Seat[i].y, (Seat[i].x + 30)(Seat[i].y + 30), al_map_rgb(200,200,200)); 30 31 file2 = fopen("passengers.txt", "a+"); 32 33 fprintf(file2, "%s %s %s %s %s %s %s %s %d\n",Name, Tel, gender, Date, time, departure, arrival, bus_code, i+1); 34 35 fclose(file2); 36 37 if(gender == "Male") 38 Seat[i].type = 'M'; 39 else if(gender == "Female") 40 Seat[i].type = 'W'; 41 42 } 43}

Program crashes when it comes to "fprintf()" line. Is there any incompatiblity between CString, const char* and '%s' ?

taronĀ 
Member #10,584
January 2009
avatar

if(gender == "Male")
      Seat[i].type = 'M';
    else if(gender == "Female")
      Seat[i].type = 'W';

This won't work, you're comparing the pointers, not the values they point to.
Use strcmp or strncmp to compare two C strings.

 file2 = fopen("passengers.txt", "a+");

    fprintf(file2, "%s  %s  %s  %s  %s  %s  %s  %s  %d\n",Name, Tel, gender, Date, time, departure, arrival, bus_code, i+1); 
                
    fclose(file2);

Open the file once, write all the data you need, then close the file.
Don't repeatedly open and close the file every iteration.

ma3stro said:

Program crashes when it comes to "fprintf()" line. Is there any incompatiblity between CString, const char* and '%s' ?

Are you sure none of your strings NULL? Or maybe you don't have write access to the passengers.txt file.

ma3stro
Member #15,329
October 2013

taron said:

if(gender == "Male")
Seat[i].type = 'M';
else if(gender == "Female")
Seat[i].type = 'W';

This won't work, you're comparing the pointers, not the values they point to.
Use strcmp or strncmp to compare two C strings.

I use ChooseGender() function before the code above. It process "char *gender" value whether user choose male or female. (e.g. If user clicks male button "gender" will be "Male"). Does that cause a problem?

taron said:

Are you sure none of your strings NULL? Or maybe you don't have write access to the passengers.txt file.

I moved "fopen()" function somwhere else it didn't cause an error.

taron said:

Open the file once, write all the data you need, then close the file.
Don't repeatedly open and close the file every iteration.

Thanks, that's more efficient but still have problem at "fprintf()" line.

Aikei_c
Member #14,871
January 2013
avatar

Did you change the ALLEGRO_USTR* after converting it to const char*? If you did, the pointer to const char* became invalid after that.
How does it crash? What does the compiler say?
EDIT: you don't even need to make this strange thing with declaring two different variables for one string.
If you want to pass ustr to fprintf, you just do this:

file = fopen("file.txt", "w");
ALLEGRO_USTR* uString = al_ustr_new("Hi!");
frintf(file,"%s",al_cstr(uString));

ma3stro
Member #15,329
October 2013

Aikei_c said:

Did you change the ALLEGRO_USTR* after converting it to const char*? If you did, the pointer to const char* became invalid after that.
How does it crash? What does the compiler say?

No, I did not change it. And the error is:

Unhandled exception at 0x55b913af (msvcr100d.dll) in Ticket_Automation.exe: 0xC0000005: Access violation reading location 0x000001b3.

Aikei_c said:

EDIT: you don't even need to make this strange thing with declaring two different variables for one string.
If you want to pass ustr to fprintf, you just do this:

file = fopen("file.txt", "a");
ALLEGRO_USTR* uString = al_ustr_new("Hi!");
frintf(file,"%s",al_cstr(uString));

Ok. I will try that.

LennyLen
Member #5,313
December 2004
avatar

Another way you could check what is crashing is to just initially fprintf a string literal such as "Hello World" and make sure that works fine. Then add your other variables until you work out which one is causing the crash. That might give you a hint as to where the problem lies.

ma3stro
Member #15,329
October 2013

Aikei_c said:

file = fopen("file.txt", "w");
ALLEGRO_USTR* uString = al_ustr_new("Hi!");
frintf(file,"%s",al_cstr(uString));

That didn't work either.

I changed this,

fprintf(file2, "%s %s %s %s %s %s %s %s %d\n",Name, Tel, gender, Date, time, departure, arrival, bus_code, i+1);

to this:

fprintf(file2, "%d\n" i+1);

and there weren't any problems at all. So it's the strings that cause the error.

LennyLen
Member #5,313
December 2004
avatar

Does this work:

fprintf(file2, "%s\n", al_cstr(al_ustr_new("Hello World!")));

ma3stro
Member #15,329
October 2013

LennyLen said:

Does this work:

fprintf(file2, "%s\n", al_cstr(al_ustr_new("Hello World!")));

Yes, it does.

LennyLen
Member #5,313
December 2004
avatar

Then the problem is with your ALLEGRO_USTR values, somewhere in the code you haven't shown us.

ma3stro
Member #15,329
October 2013

This is how I use one of the ALLEGRO_USTR variables:

#SelectExpand
1ALLEGRO_USTR *date= al_ustr_new(""); 2int pos = (int)al_ustr_size(date); 3. 4. 5if(!done) // If user hits enter done will be true 6{ if(STATE == DATE) 7 if(events.keyboard.unichar >= 32) 8 { 9 pos += al_ustr_append_chr(date, events.keyboard.unichar); 10 } 11 else if(events.keyboard.keycode == ALLEGRO_KEY_BACKSPACE) 12 { 13 if(al_ustr_prev(date, &pos)) 14 al_ustr_truncate(date, pos); 15 } 16. 17. 18. 19if(STATE == DATE) 20 { 21 al_draw_ustr(font, al_map_rgb(0,0,0), 260, 21, 0, date); 22 } 23. 24. 25. 26if(mouse[B1]) 27 { 28 file2 = fopen("passengers.txt", "a+"); 29 30 for(int i= 0; i < 32; i++) 31 if(state.x >= Seat[i].x && (state.x <= Seat[i].x + 30) && state.y >= Seat[i].y && (state.y <= Seat[i].y + 30)) 32 { 33 if(Seat[i].type == 'E') 34 al_draw_filled_rectangle(Seat[i].x, Seat[i].y, (Seat[i].x + 30)(Seat[i].y + 30), al_map_rgb(200,200,200)); 35 36 37 fprintf(file2, "%s %s %s %s %s %s %s %s %d\n",al_cstr(name),al_cstr(tel), gender, al_cstr(date), time, departure, arrival, bus_code, i+1); 38 39 40 if(gender == "Male") 41 Seat[i].type = 'M'; 42 else if(gender == "Female") 43 Seat[i].type = 'W'; 44 45 } 46 fclose(file2); 47 } 48. 49. 50. 51al_ustr_free(date);

Aikei_c
Member #14,871
January 2013
avatar

Use just one argument: al_cstr(name). Does it work? If not, try to understand, why. If it doesn't add another argument. Does it work?..
Keep on until you identify your problem.

ma3stro
Member #15,329
October 2013

I tried all the parameters one by one and found that "gender" value is the problem. The others are working fine.

taron said:

if(gender == "Male")
Seat[i].type = 'M';
else if(gender == "Female")
Seat[i].type = 'W';
This won't work, you're comparing the pointers, not the values they point to.
Use strcmp or strncmp to compare two C strings.

I think this is where things have gone wrong.

For strcmp(), do I have to create another string variable ( e.g. char *str = "Male" ) and compare those two(gender and str)?

 1   2 


Go to: