在C语言中自动向变量追加数字

在C语言中自动向变量追加数字,c,macros,C,Macros,我们的编程任务要求我们将一个文本文件分解成一组较小的文件,文件名为(filename)partx.txt。例如,如果传递给程序的参数是名为stack.txt的文本文件,则输出应为stackpart1.txt、stackpart2.txt等,其中每个文件的最大大小为250字节 达到part_x目标的最佳方式是什么 我学习了如何将宏与##结合使用来实现这一点。这种方法的缺点是什么?有没有更好的方法? 以这种方式生成变量名是一种很好的做法吗?您可以: 按照建议使用宏(编译时)。这涉及到在实现代码时有

我们的编程任务要求我们将一个文本文件分解成一组较小的文件,文件名为
(filename)partx.txt
。例如,如果传递给程序的参数是名为
stack.txt
的文本文件,则输出应为
stackpart1.txt、stackpart2.txt等,其中每个文件的最大大小为250字节

达到part_x目标的最佳方式是什么

我学习了如何将宏与##结合使用来实现这一点。这种方法的缺点是什么?有没有更好的方法? 以这种方式生成变量名是一种很好的做法吗?

您可以:

  • 按照建议使用宏(编译时)。这涉及到在实现代码时有关文件大小(以及子文件的编号)的一些知识
  • 在循环中使用以生成文件名。(运行时)。这可以基于某些用于测量文件大小的算法动态使用
也就是说,最好的方法是:使用
snprintf()

您可以:

  • 按照建议使用宏(编译时)。这涉及到在实现代码时有关文件大小(以及子文件的编号)的一些知识
  • 在循环中使用以生成文件名。(运行时)。这可以基于某些用于测量文件大小的算法动态使用

也就是说,最好的方法是:使用
snprintf()

不要将变量名与其内容混淆;宏和变量名与赋值无关
##
用于在编译时连接要在代码中使用的字符串(典型用法是在宏中以参数化方式构建标识符或一般代码),这是一项相对罕见且非常专门的任务


相反,您要做的是在运行时基于模式生成字符串(=>您将拥有相同的字符串变量,在每次迭代中填充不同的内容);正确的函数是
snprintf

不要将变量名与其内容混淆;宏和变量名与赋值无关
##
用于在编译时连接要在代码中使用的字符串(典型用法是在宏中以参数化方式构建标识符或一般代码),这是一项相对罕见且非常专门的任务


相反,您要做的是在运行时基于模式生成字符串(=>您将拥有相同的字符串变量,在每次迭代中填充不同的内容);正确的函数是
snprintf

它非常简单,我想说:打开一个文件(
fopen
返回一个
文件*
),然后在循环中读取,使用
fread
指定每次迭代读取的最大字节数。考虑到您仍然在使用循环,您可以增加一个简单的int来跟踪区块文件名,使用
snprintf
创建名称,将
fread
读取的字符写入每个文件,然后继续,直到完成

一个基本示例(仍然需要一些工作):

请注意,目前使用此代码并不完全安全。您需要检查
fopen
的返回值(它可以返回
NULL
)。基于
fread
的循环简单地假设,如果其返回值小于块大小,则我们已经到达了源文件的末尾,但情况并非总是如此。您仍然需要自己处理空指针和
ferror
填充。无论哪种方式,都需要研究以下功能:

  • fread
  • fopen
  • fwrite
  • fclose
  • ferror
  • snprintf
应该这样做


更新,只是为了好玩

您可能需要填充区块文件名(chunk\u part0001.txt)的编号。要做到这一点,您可以尝试预测源文件有多大,将其除以256,计算出最终实际将得到多少块,并使用该数量的填充零。如何获取文件大小,但这里有一些我不久前编写的代码:

long file_size = 0,
     factor = 10;
int padding_cnt = 1;//at least 1, ensures correct padding
fseek(src_fp, 0, SEEK_END);//go to end of file
file_size = ftell(src_fp);
file_size /= 256;//divided by chunk size
rewind(src_fp);//return to beginning of file
while(10 <= (file_size/factor))
{
    factor *= 10;
    ++padding_cnt;
}
//padded chunk file names:
snprintf(chunk_name, sizeof chunk_name, "chunk_part%0*d.txt", padding_cnt, chunk_count);
long file_size=0,
系数=10;
int padding_cnt=1//至少1个,确保填充正确
fseek(src_fp,0,SEEK_END)//转到文件末尾
文件大小=ftell(src\u fp);
文件大小/=256//除以块大小
倒带(src_fp)//返回到文件的开头

虽然(10非常简单,但我会说:你打开一个文件(
fopen
返回一个
文件*
)然后,您可以在循环中读取,使用
fread
指定每次迭代中读取的最大字节数。鉴于您仍在使用循环,您可以增加一个简单的int来跟踪区块文件名,使用
snprintf
创建名称,将
fread
读取的字符写入每个文件,然后继续,直到完成为止

一个基本示例(仍然需要一些工作):

请注意,目前使用此代码并不完全安全。您需要检查
fopen
的返回值(它可以并且在某些时候会返回
NULL
)。基于
fread
的循环只是假设,如果其返回值小于块大小,则我们已经到达了源文件的末尾,但情况并非总是如此。您仍然必须自己处理空指针和
ferror
填充。无论哪种方式,要研究的函数是:

  • fread
  • fopen
  • fwrite
  • fclose
  • ferror
  • snprintf
应该这样做


更新,只是为了好玩

您可能需要填充块文件名(chunk\u part0001.txt)的数字。为此,您可以尝试预测源文件的大小,将其除以256到0
long file_size = 0,
     factor = 10;
int padding_cnt = 1;//at least 1, ensures correct padding
fseek(src_fp, 0, SEEK_END);//go to end of file
file_size = ftell(src_fp);
file_size /= 256;//divided by chunk size
rewind(src_fp);//return to beginning of file
while(10 <= (file_size/factor))
{
    factor *= 10;
    ++padding_cnt;
}
//padded chunk file names:
snprintf(chunk_name, sizeof chunk_name, "chunk_part%0*d.txt", padding_cnt, chunk_count);