1

我正在尝试读取 txt 文件的全部内容,而不是逐行读取,而是全部包含

并在 xcode 中的文本字段内的屏幕上打印它

我正在使用 obj-c 和 c++ lang 的混合:

while(fgets(buff, sizeof(buff), in)!=NULL){
        cout << buff;  // this print the whole output in the console


         NSString * string = [ NSString stringWithUTF8String:buff ] ;

         [Data setStringValue:string]; // but this line only print last line inside the textfield instead of printing it all
    }

我正在尝试打印文件的全部内容,例如:

  1. 某物...
  2. 某物...
  3. ETC...

但它只是将最后一行打印到文本字段,请帮助我

4

3 回答 3

2

您是否有理由不使用 Obj-C 来读取文件?这很简单:

NSData *d = [NSData dataWithContentsOfFile:filename];
NSString *s = [[[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding] autorelease];
[Data setStringValue:s];

编辑:要使用你现在拥有的代码,我会尝试这样的事情:

while(fgets(buff, sizeof(buff), in)!=NULL){
  NSMutableString *s = [[Data stringValue] mutableCopy];
  [s appendString:[NSString stringWithUTF8String:buff]];
  [Data setStringValue:s];
 }
于 2012-12-21T21:39:01.030 回答
1

读取文件,将内容作为 C++ 字符串返回:

  // open the file
  std::ifstream is; 
  is.open(fn.c_str(), std::ios::binary);

  // put the content in a C++ string
  std::string str((std::istreambuf_iterator<char>(is)),
                   std::istreambuf_iterator<char>());

在您的代码中,您使用的是 C api(FILE*来自 cstdio)。在 C 中,代码更复杂:

char * buffer = 0; // to be filled with the entire content of the file
long length;
FILE * f = fopen (filename, "rb");

if (f) // if the file was correctly opened
{
  fseek (f, 0, SEEK_END);  // seek to the end
  length = ftell (f);      // get the length of the file
  fseek (f, 0, SEEK_SET);  // seek back to the beginning
  buffer = malloc (length); // allocate a buffer of the correct size
  if (buffer)               // if allocation succeed
  {
    fread (buffer, 1, length, f);  // read 'length' octets
  }
  fclose (f); // close the file
}
于 2012-12-21T21:36:58.143 回答
0

要回答为什么您的解决方案不起作用的问题:

[Data setStringValue:string]; // but this line only print last line inside the textfield instead of printing it all

假设它Data引用一个文本字段,setStringValue:用您传入的字符串替换该字段的全部内容。您的循环一次读取并设置一行,因此在任何给定时间,string都是文件中的一行。

只有当您没有在主线程上执行任何其他操作时,才会告诉视图显示,因此您的循环(假设您没有在另一个线程或队列上运行它)不会一次打印一行。您读取每一行并用该行替换文本字段的内容,因此当您的循环完成时,该字段将保留您设置的最后一个内容stringValue- 文件中的最后一行。

一次性吞下整个文件是可行的,但仍然存在一些问题:

  • 文本字段不适用于显示多行。无论您如何阅读文件,您仍然将其内容放在不是为此类内容设计的地方。
  • 如果文件足够大,读取它会花费大量时间。如果您在主线程上执行此操作,那么在此期间,应用程序将被挂起。

一个适当的解决方案是:

  1. 使用文本视图,而不是文本字段。文本视图是为处理任意行数的文本而构建的,当您在 nib 中创建一个文本视图时,它会免费包含在滚动视图中。
  2. 一次读取文件一行或其他有限大小的块,但不是在一个forwhile循环中。使用 NSFileHandle 或dispatch_source,它们中的任何一个都会在读取文件的另一块时调用您提供的块。
  3. Append each chunk to the text view's storage instead of replacing the entire text with it.
  4. Show a progress indicator when you start reading, then hide it when you finish reading. For extra credit, make it a determinate progress bar, showing the user how far you've gotten through the file.
于 2012-12-22T02:58:55.817 回答