2013-08-23 97 views
6

我试图将整个.txt文件复制到char数组中。我的代码有效,但它留下了空白。因此,举例来说,如果我的.txt文件上写着“我爱派”,我把它复制到myArray的,如果我使用for循环清点我的阵列我得到“ILikePie”如何将.txt文件复制到C++中的char数组中

这里是我的代码

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

int main() 
{ 
    int arraysize = 100000; 
    char myArray[arraysize]; 
    char current_char; 
    int num_characters = 0; 
    int i = 0; 

    ifstream myfile ("FileReadExample.cpp"); 

    if (myfile.is_open()) 
     { 
      while (!myfile.eof()) 
      { 
       myfile >> myArray[i]; 
       i++; 
       num_characters ++; 
      }  

for (int i = 0; i <= num_characters; i++) 
     { 

     cout << myArray[i]; 
     } 

     system("pause"); 
    } 

有什么建议么? :/

+0

ARRAYSIZE应该是const。 – Rapptz

+0

使用'!myfile.eof()'不正确。即使你想阅读单词,而不是所有的字符,你都会在不验证成功的情况下使用myfile >> myArray [i]'的结果,这是不正确的。如果你想阅读所有的字符,那么'while(myfile。get(myArray [i]))++我;'会工作(但你仍然需要边界检查)。但Nemanja的回答远远优于。 –

回答

27

随着

myfile >> myArray[i]; 

你是哪个字跳绳导致空间的读取文件字。

你可以阅读整个文件写入字符串与

std::ifstream in("FileReadExample.cpp"); 
std::string contents((std::istreambuf_iterator<char>(in)), 
    std::istreambuf_iterator<char>()); 

然后你就可以使用contents.c_str()获得字符数组。

这是如何工作的

std::string具有范围构造函数,拷贝字符的范围[第一序列,最后)注意,它不会复制去年,以相同的顺序:

template <class InputIterator> 
    string (InputIterator first, InputIterator last); 

std::istreambuf_iterator迭代器是输入迭代器,它从流缓冲区中读取连续的元素。

std::istreambuf_iterator<char>(in) 

将为我们ifstream in(文件的开头)创建迭代器,如果你不传递任何参数构造函数,它将创建最终的流迭代器(最后一个位置):

默认构建的std :: istreambuf_iterator被称为流结束迭代器。当一个有效的std :: istreambuf_iterator到达基础流的末尾时,它就等于流结束迭代器。解引用或增加它会进一步调用未定义的行为。

所以,这将复制所有字符,从文件中的第一个开始,直到下一个字符是流结束。

+0

当然,这是正确的答案,但有两个值得指出的细节:首先,如果您想要准确查看文件中的字节,则应该以二进制模式打开它,并确保文件已被填充C语言环境;否则,可能会发生各种翻译。其次,如果文件包含空字符,'contents.c_str()'不是要走的路。更一般地说,在这种情况下,我会使用'contents.data()'(但我没有看到任何理由不直接在字符串上工作)。 –

+0

@JamesKanze,谢谢你的建议。我没有使用二进制模式,我建议'c_str',因为我认为OP使用ASCII txt文件。但是,感谢您的评论,因为这是我(和其他人)学习新内容的最佳方式(比如“C”语言环境 - 我不知道它是什么,所以我会查找它)。 –

+1

我不清楚OP是否想要字符串中文件的确切字节,或者他是否想要字符串的文本表示。我的意见是指他想要确切字节的情况;你的代码完全和书面一样,对于文件中文本的内部表示来说是很好的(假设它是文本---但除此之外,'std :: vector '会比字符串更有意义 –

8

使用下面的代码片段:

FILE *f = fopen("textfile.txt", "rb"); 
fseek(f, 0, SEEK_END); 
long fsize = ftell(f); 
fseek(f, 0, SEEK_SET); 

char *string = (char *)malloc(fsize + 1); 
fread(string, fsize, 1, f); 
fclose(f); 

string[fsize] = 0; 
+0

只需修复它,添加在fopen()调用中,标志'b' –

+1

'void *'不能直接转换成'char *'(在malloc行上) –

1

,如果你一定要使用字符数组,并尽可能少的改动你的代码的简单解决方案。下面的代码片段将包含所有空格和换行符,直到文件结束。

 while (!myfile.eof()) 
     { 
      myfile.get(myArray[i]); 
      i++; 
      num_characters ++; 
     } 
+0

这是性能差的定义,很好的演示,实用性很差因为逐字节的读取确实对磁盘造成了税收 –

+0

感谢您的反馈意见,您能为未来的读者提供更好的解决方案吗? – Blake

+0

您想说有可能是穷人,还是穷人?还有,速度差还是复杂性差?我对硬件层不太了解,但我认为编译器会做一些展开/矢量化处理,这样可以使性能相当(特别是因为数据只与成对相关)。作为一般规则,我使用'单线程'方法可用于循环,但如果我关心*速度*,我还会担心幕后虚拟方法的处罚等。 –

1

一个更简单的方法是使用get()成员函数:

while(!myfile.eof() && i < arraysize) 
{ 
    myfile.get(array[i]); //reading single character from file to array 
    i++; 
} 
相关问题