Ugh, I still blundered: your file was opened correctly. What's inside?
Ugh, I still blundered: your file was opened correctly. What's inside?
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
What does (!fp) mean ?
It means the file wasn't opened with sucess or does it mean it was opened with sucess ?
fopen returns a null pointer if the file failed to be opened. !fp evaluates to 1 if fp is a null pointer, hence if !fp evaluates to 1, the file failed to be opened.
Perhaps it would be easier to understand if written in this way:
As such, if you want to write it in your way, it should be:Code:fp = fopen("/Users/machd/Desktop/SistemasOperativos2013/GuardaLinhas/merdas.txt", "r"); if (fp) { /* read from the file */ } else { /* report the problem in opening the file */ }
Code:fp = fopen("/Users/machd/Desktop/SistemasOperativos2013/GuardaLinhas/merdas.txt", "r"); if (!fp) { /* report the problem in opening the file */ printf("%s\n", "Failed to open the file."); }
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Hmm, understood.
Thanks so much.
Well, what's inside.
I got this piece of code to read what's inside the text file :
Got no idea why it ain't working.Code:while(!feof(fp)){ fgets(buffer,200,fp); printf("%s",buffer); }
This is what is inside the file :
Code:72 . 16 ./.DS_Store 8 ./a 8 ./lerficheiro.c 8 ./o 24 ./so 8 ./so.c
With proper error checking, it should be more like
fopen() sets errno if it fails (returning NULL), so you can use the above to print the exact reason the open failed.Code:#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> int main(void) { const char *const filename = "merdas.txt"; char buffer[500]; FILE *fp; char *line; fp = fopen(filename, "r"); if (!fp) { fprintf(stderr, "Cannot open '%s': %s.\n", filename, strerror(errno)); return EXIT_FAILURE; } while (1) { line = fgets(buffer, sizeof buffer, fp); if (!line) break; printf("%s", line); } if (ferror(fp) || !feof(fp)) { fprintf(stderr, "Error reading '%s'.\n", filename); return EXIT_FAILURE; } if (fclose(fp)) { fprintf(stderr, "Error closing '%s'.\n", filename); return EXIT_FAILURE; } fprintf(stderr, "File '%s' read successfully.\n", filename); return EXIT_SUCCESS; }
The second-to-last if clause checks why the fgets() call failed (returned NULL). ferror() is true if there was a read error. !feof() is true if the read call did not fail because there was no more input. In other words, the condition can be read as (if there was an error, or we didn't consume all input).
The last if clause closes the stream. It is possible for it to fail in theory, although I haven't seen it in practice. (I do have seen it when writing to a file, when the file happened to be on a remote NFS volume, and the remote server had hardware issues.)
Compile and run it, and show what it outputs.
72 .
16 ./.DS_Store
8 ./a
8 ./lerficheiro.c
8 ./o
24 ./so
8 ./so.c
File '/Users/machd/Desktop/SistemasOperativos2013/GuardaLinhas/merdas.txt' read successfully.
Thanks sir, worked just fine.
I must say I believe I'm the dumbest guy ever as I wasn't calling the function inside main >_>
Now what I want to do is :
I want to read line by line.
After reading the first line,
I should read until the number is over and when this is done I should add the number to the key field in the struct. Then I should ignore all the spaces and when I found a "." I should start reading it to the field info in the struct.
Any ideas on how I should start ?
I'm guessing I should do this by chaining aswell.
The buffer in the example program contains each line read. You can use the line variable to point at the start of the line.
You can use sscanf() to "read" (or convert) the line you've already read. That man page is very detailed, but unfortunately it's a bit confusing to read at first.
For example, try and see what happens if you rewrite the loop in the example program intoA couple of important points you should understand:Code:while (1) { char value[400]; int key; line = fgets(buffer, sizeof buffer, fp); if (!line) break; /* Convert the line read into a key, and a value. */ if (sscanf(line, " %d %399s", &key, value) != 2) { /* Remove the newline at the end of the line. */ line[strcspn(line, "\r\n")] = '\0'; /* Output an error and abort. */ fprintf(stderr, "'%s': Bad data line, '%s'.\n", filename, line); return EXIT_FAILURE; } printf("Key = %d, value = '%s'\n", key, value); }
- The %d conversion converts an int.
The function takes a pointer to an int as a parameter, here &key, where the result will be stored.- The %s conversion copies a string that does not contain whitespace (spaces, tabs, newlines).
The function takes a pointer to a char as a parameter, here value (because it is a char array, it gets converted to a pointer to the first char in the array automatically, just as if you had written &(value[0])), where the string will be copied to. There must be enough room to store the token, and an extra end-of-string mark (NUL byte, \0).- Since we only have room for 400 characters including the end-of-string mark in value, value can contain at most a 399-character string. We must limit the conversion so we won't overrun the buffer.
Fortunately this is very simple: we just include the maximum length before the conversion specifier. So, we actually need to use %399s.
Since tokens end at whitespace, values cannot contain spaces or tabs.
If you want the value to extend to the end of the line, you can use
The %[...] conversion is like the %s conversion, except only characters specified in ... are accepted. You can use ranges; for example 0-9A-Za-z accepts all numbers and letters. If the first character is ^, the meaning is inverted: ^\r\n accepts all characters except CR (\r) or LF (\n).Code:if (sscanf(line, " %d %399[^\r\n]", &key, &value) != 2) {
Well the number part is easily handled by sscanf like so:
Then you can take the information starting from the where character and copy it into the node (denoted by line[where]).Code:int where; if (sscanf(linefromfile, "%d .%n", &node->key, &where) == 1) // Good.
Of course, how well this works depends on how well you can read the lines of the file. fgets() is not a magical solution, but with a big enough size argument it can cover most common line lengths. How well this works also depends on how well I understood what you said.
Well, I think that DeanWinchester at least has learned from this thread that if you ask enough then Nominal Animal will probably write the whole program for you, free of charge. It will probably take a few days to finish and he'll probably get it in bits an pieces, but he'll get there eventually.
It's really amazing, but you have a 1.5 year old thread with the same exact title. One has to wonder if all the spoon-feeding you request here is hindering your ability to progress, or you just aren't getting it at all.. At some point the training wheels have to come off, man.