C++读取文本文件到char*

C++读取文本文件内容到char*中:

#include <iostream>
#include <fstream>
#include <iostream>

const char* readFile(const char* fileName);

int main()
{
	const char* result = readFile("README.md");
	std::cout << result;
}


const char* readFile(const char* fileName) {
	std::ifstream file(fileName);                            // 打开文件
	char* content;
	content = (char*)malloc(sizeof(char) * 40960);           // 假设文件最大为40K,可自定义
	if (content)
	{
		char buff[1024];                                     // 1Kb的缓冲区
		int pt = 0;
		while (file.getline(buff, 1024))                     // 按行读取文件到缓冲区
		{
			for (int i = 0; i < 1024; i++) {
				char tmp = buff[i];
				if (tmp == '\0') {                           // 遇到\0时换行,继续读取下一行
					content[pt] = '\n';
					pt++;
					break;
				}
				content[pt] = tmp;
				pt++;
			}
		}
		content[pt] = '\0';                                  // 读取结束,构建字符串尾
		char* result = (char*)malloc(sizeof(char) * (++pt)); // 申请pt+1个字节的内存空间
		if (!result)
			return NULL;
		for (int i = 0; i < pt; i++) {
			result[i] = content[i];                          // 字符串复制
		}
		return result;
	}
	return NULL;
}

几个问题:

1、getline()会往缓冲区写入数据,并约定在行尾加入\0,原始缓冲区的内存是乱七八糟的值,所以要以\0截取

2、为什么不用std::strcat和std::strcpy而要遍历字符。在C++11中,strcat和strcpy被认为是不安全的,可能会发生内存重叠或溢出,被弃用了,并且相对应的引入了strcat_s和strcpy_s数据结构,这里的数据比较简单且可控,因此采用了这种方法。

3、如果一定要使用strcat_s和strcpy_s,需要设置 __STDC_WANT_LIB_EXT1__ 宏的值为1,且在确保 __STDC_LIB_EXT1__ 宏被定义时才可使用,来自官方的例子:

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    char *src = "Take the test.";
//  src[0] = 'M' ; // this would be undefined behavior
    char dst[strlen(src) + 1]; // +1 to accomodate for the null terminator
    strcpy(dst, src);
    dst[0] = 'M'; // OK
    printf("src = %s\ndst = %s\n", src, dst);
 
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    int r = strcpy_s(dst, sizeof dst, src);
    printf("dst = \"%s\", r = %d\n", dst, r);
    r = strcpy_s(dst, sizeof dst, "Take even more tests.");
    printf("dst = \"%s\", r = %d\n", dst, r);
#endif
}

得到的输出:

src = Take the test.
dst = Make the test.
dst = "Take the test.", r = 0
dst = "", r = 22

具体请参阅C11标准(ISO / IEC 9899:2011):http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

  • 7.24.2.3 strcpy函数(p:363)
  • K.3.7.1.3 strcpy_s函数(p:615-616)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值