我正在努力通过c File从文本文件中获取字符串。我打算使用文本大小来获取行。我创建了一个简单的文本文件;
a s
da
它的7个字节。我认为文件大小应该是6个字节,因为它有5个字符和一个新行。我已经对它进行了研究并认为它有2个
'\n'
char值。我的第一个问题是为什么文本为每一行添加2个新行。
然后我使用fscanf函数来获取字符串,但这次它给了我
这是我的代码:
#include <iostream>
#include <windows.h>
#include <stdio.h>
using namespace std;
int main()
{
//Declaring char arrays for every bits//
char a[1], b[1] , c[1] , d[1] , e[1] , f[1] , g[1] , h[7];
//Streaming the text file//
FILE *file;
file=fopen("conversations.txt","r");
fseek (file, 0, SEEK_END);
int size=ftell (file);
printf ("Size of myfile.txt: %ld bytes.%c",size , 10);
//Appending char value of first pointed bit//
fseek ( file , 0 , SEEK_SET );
fscanf(file, "%1c",a);
cout << a[0] << "<-a||";
fseek ( file , 1 , SEEK_SET );
fscanf(file, "%1c",b);
cout << b[0]<< "<-b||";
fseek ( file , 2 , SEEK_SET );
fscanf(file, "%1c",c);
cout << c[0]<< "<-c||";
fseek ( file , 3 , SEEK_SET );
fscanf(file, "%1c",d);
cout << d[0]<< "<-d||";
fseek ( file , 4, SEEK_SET );
fscanf(file, "%1c",e);
cout << e[0]<< "<-e||";
fseek ( file , 5 , SEEK_SET );
fscanf(file, "%1c",f);
cout <<f[0]<< "<-f||";
fseek ( file , 6 , SEEK_SET );
fscanf(file, "%1c",g);
cout << g[0]<< "<-g||";
//Getting bits of chars
cout << endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = a[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
cout<<endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = b[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
cout<<endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = c[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
cout<<endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = d[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
cout<<endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = e[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
cout<<endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = f[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
cout<<endl<<endl;
for (int i = 0; i < 8; ++i) {
bool is_set = g[0] & (1 << i);
cout << "Bit " << i << ": " << is_set << '\n';
}
//Appending all bytes to one char array//
fseek ( file , 0 , SEEK_SET );
fscanf( file, "%7c",h);
for(int i = 0 ; i < 7 ; i++ )
{
cout << h[i];
}
cout << endl << endl;
//Getting bits of chars
for (int i = 0; i < 8; ++i) {
bool is_set = h[0] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
cout << endl << endl;
for (int i = 0; i < 8; ++i) {
bool is_set = h[1] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
cout << endl << endl;
for (int i = 0; i < 8; ++i) {
bool is_set = h[2] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
cout << endl << endl;
for (int i = 0; i < 8; ++i) {
bool is_set = h[3] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
cout << endl << endl;
for (int i = 0; i < 8; ++i) {
bool is_set = h[4] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
cout << endl << endl;
for (int i = 0; i < 8; ++i) {
bool is_set = h[5] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
cout << endl << endl;
for (int i = 0; i < 8; ++i) {
bool is_set = h[6] & (1 << i);
std::cout << "Bit " << i << ": " << is_set << '\n';
}
return 0;
}
答案 0 :(得分:3)
您无法使用ftell()
来确定文本文件的大小。
根据C Standard, 7.21.9.4 ftell
函数:
ftell
函数获取文件位置的当前值stream
指向的流的指示符。对于二进制文件 stream,该值是来自的字符数 文件的开头。 对于文本流,其文件位置 指标包含fseek
可使用的未指定信息 用于将流的文件位置指示符返回到的函数 它在ftell
电话时的位置;区别 两个这样的返回值之间不一定有意义 衡量写入或读取的字符数。
答案 1 :(得分:1)
Windows(和MS-DOS)使用两个字节的序列0x0D 0x0A来表示文本文件中的新行。因此,文本中的每个新行都会在文本文件中生成两个字节。 fscanf
和其他C和C ++文本输入函数(以及输出函数)理解它们所针对的系统的行约定:在输出时,字符'\n'
生成适当的序列以启动新的在Windows上为0x0D 0x0A,在典型的Unix系统上为0x0A,在较旧的Mac上为0x0D。在输入时,函数只是反转该过程。所以在Windows上,表示一行结尾的两个字节被读作单个字符'\n'
,代表一个新行。
Windows文件中的两个字节有时被懒惰地称为\r\n
,但由于'\n'
表示换行符,因此将"\r\n"
写入文件将产生0x0D 0x0D 0x0A。最好将文件中的那些字节想象成它们:CR和LF的ASCII代码。它是两者的组合,将输出位置移动到行的开头(CR用于回车),然后将其向下移动到下一行(换行的LF)。
答案 2 :(得分:1)
OP正在尝试逐字节查看文件,但以“文本”模式打开文件
file=fopen("conversations.txt","r");
在文本模式下,可能会出现有关行和文件结尾的各种翻译。要逐字节读取文件并将其打印为true值,请以二进制模式打开文件。
file=fopen("conversations.txt","rb");
使用二进制模式和fscanf()
很狡猾,最好使用fread()
。
在Windows中,在 text 模式下处理文件时,"\r\n"
序列通常会更改为'\n'
。单独的"\n"
序列仍为'\n'
。这就是OP看到2 '\n'
并且代码尝试在选择偏移处以 text 模式读取文件的原因。