c/c++ file io

关于c/c++的文件IO整理

FILE create and write

c style

using file descriptor direactly, open, write, close function work together to finish the file operation. Attention that for the file permission part, don’t forget the 0 before 644.

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
//using file descriptor

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>

int main()
{
int fileNumber;
//If the specified file does not exist, it may optionally (if O_CREAT is specified in flags) be created by open().
fileNumber = open("./test2.txt", O_CREAT | O_WRONLY, 0644);
if (fileNumber < 0)
{
printf("Can’t read file using file fn %d\n", fileNumber);
exit(1);
}
//ssize_t write(int fildes, const void *buf, size_t nbytes);
char str[100] = "Writing using File Number\n";
int len = strlen(str);
write(fileNumber, "Writing using File Number\n", len);
close(fileNumber);
return 0;
}

file pointer could be used based on the file descriptor, for the following example, the file descriptor could be transformed into the file pointer point to a FILE struct. On the other hand, the function int fileno(FILE *stream) could be used to tranform a FILE pointer into a file descriptor. Compared with the file descriptor(only a int number) file pointer contains more info about the file.

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
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>

int main()
{
int fileNumber;
//If the specified file does not exist, it may optionally (if O_CREAT is specified in flags) be created by open().
fileNumber = open("./test2.txt", O_CREAT | O_WRONLY, 0644);
if (fileNumber < 0)
{
printf("Can’t read file using file fn %d\n", fileNumber);
exit(1);
}

//ssize_t write(int fildes, const void *buf, size_t nbytes);
char str[100] = "Writing using File Number\n";
int len = strlen(str);
write(fileNumber, "Writing using File Number\n", len);

FILE *filePointer = fdopen(fileNumber, "a");
fprintf(filePointer, "Writing using File Pointer\n");
fclose(filePointer);
close(fileNumber);
return 0;
}

Or we could use fopen to return a file descriptor direactly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//using file pointer

#include <stdio.h>

int main()
{

FILE *filePointer = fopen("./test3.txt", "w");
if (filePointer==NULL){
printf("failed open the file\n");
}
fprintf(filePointer, "Writing using File Pointer\n");
fclose(filePointer);
return 0;
}

compared with open and write, it is much simple to use fopen and fprintf direactly. for the mode of openning file , refer this (https://www.tutorialspoint.com/cprogramming/c_file_io.htm)

c++ style

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//using fstream
#include <iostream>
#include <fstream>
using namespace std;

int main () {
ofstream myfile;
//open a file, if file doesn't exist, create the file
//open is a function of class ofstream
myfile.open ("example.txt");
myfile << "Writing this to a file234.\n";
myfile.close();
return 0;
}

//http://www.cplusplus.com/doc/tutorial/files/

FILE load

read the content of the file into the program, the load operation could be diveided into several types by the granularity, load by specific bytes, load line by line, and load the total files at once.

one important issue is data over flow during file reading.

the first step is always using fopen to return the File pointer. Similar to open/read/write(system call for unix), we could use fopen, fread, fwrite(library with the internal buffer for c language). I think open/read/write are much low level for practical using, in real use case, I prefer to use fopen, fread, fwrite.

  • for fread, the input could be controled by number of bytes,
  • for fgets, the content could be loaded by every line automatically, it will finish reading till the endle or \n.
  • there is another function gets which could also load every line once, but there is no protection for buffer for this function. gets and scanf are not secure way for input operation.

refer this (https://stackoverflow.com/questions/18253413/difference-between-fgets-and-fread) for the difference of two functions.

from the prospect of programming, fgets is much simple to use.(refer this https://blog.csdn.net/lanceleng/article/details/8730192 for more info)

another thing is the difference between scanf and fscanf, scanf could load info from stdin and fscanf could load info from file stream. We could also use freopen("in.txt","r",stdin) to redirect the stream from file into stdin if we want to use scanf instead of the fscanf.

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
#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *pFile;
char mystring[100];

pFile = fopen("test2.txt", "r");
if (pFile == NULL)
{
perror("Error opening file");
exit(1);
}
while (fgets(mystring, 100, pFile) != NULL)
{
printf("%s",mystring);
}
fclose(pFile);
return 0;
}
```

**C++style**

For the following code, ifstream class is used to get the file contents direactly from the file name.

string loadFile(char *filename)
{

ifstream ifs;
ifs.open(filename);
if (ifs.fail())
{
    printf("ifs fail\n");
    exit(1);
}

string content((std::istreambuf_iterator<char>(ifs)),
               (std::istreambuf_iterator<char>()));

`

reference

https://courses.cs.washington.edu/courses/cse373/99au/assignments/fileIO.html

fopen mode

https://www.tutorialspoint.com/cprogramming/c_file_io.htm

推荐文章