将数字添加到文件名
Add numbers to filename
我想将数据存储在不同的文件中。因此我想按如下方式创建文件:data_1.log
、data_2.log
、...、data_N.log
。附录 .log
不是必需的,但会很好。到目前为止,我所有的方法都失败了。这是一个可能接近我需要的示例:
#include <stdio.h>
#include <string.h>
char get_file_name(int k){
int i, j;
char s1[100] = "logs/data_";
char s2[100];
snprintf(s2, 100, "%d", k);
for(i = 0; s1[i] != '[=10=]'; ++i);
for(j = 0; s2[j] != '[=10=]'; ++j, ++i){
s1[i] = s2[j];
}
s1[i] = '[=10=]';
return s1;
}
int main(){
char file_name[100];
for(int k=0; k<10; k++){
// Get data
// ...
// Create filename
strcpy(file_name, get_file_name(k));
printf("%s", file_name);
// fp = fopen(file_name, "w+");
// Write data to file
// print_results_to_file();
// fclose(fp);
}
return 0;
}
目前我收到以下我不理解的错误:
string.c: In function ‘get_file_name’:
string.c:14:12: warning: returning ‘char *’ from a function with return type ‘char’ makes integer from pointer without a cast [-Wint-conversion]
return s1;
^~
string.c:14:12: warning: function returns address of local variable [-Wreturn-local-addr]
string.c: In function ‘main’:
string.c:24:27: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(file_name, get_file_name(k));
^~~~~~~~~~~~~~~~
In file included from string.c:2:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
有没有更简单的方法来创建这样的文件名?真不敢相信没有。
函数 get_file_name
具有 return 类型 char
char get_file_name(int k){
但它 return 是 char *
类型的对象
char s1[100] = "logs/data_";
//...
return s1;
此外,returned 指针指向一个本地数组 s1
,该数组在退出函数后将不存在。
在本次通话中
strcpy(file_name, get_file_name(k));
第二个参数的类型(根据函数 get_file_name
声明为 char
)应为 char *
.
既没有函数 print_results_to_file
声明也没有它的定义。
根据 C 标准,不带参数的函数 main 应声明为
int main( void )
我会按以下方式编写函数 get_file_name
#include <stdio.h>
#include <string.h>
char * get_file_name( char *file_name, size_t n, size_t padding )
{
const char *common_part = "logs/data_";
snprintf( file_name, n, "%s%zu", common_part, padding );
return file_name;
}
int main( void )
{
enum { N = 100 };
char file_name[N];
for ( size_t i = 0; i < 10; i++ ) puts( get_file_name( file_name, N, i ) );
}
程序输出为
logs/data_0
logs/data_1
logs/data_2
logs/data_3
logs/data_4
logs/data_5
logs/data_6
logs/data_7
logs/data_8
logs/data_9
此代码存在各种问题,这里不一一纠正,而是另一种方法。它不是唯一的,但它很简单,应该易于理解和适应:
#include <stdio.h>
void get_file_name(int k, char* buffer, size_t buflen) {
snprintf(buffer, buflen, "logs/data_%d.log", k);
}
int main() {
const size_t BUFLEN = 50;
char file_name[BUFLEN];
for (int i = 0; i < 10; i++) {
get_file_name(i, file_name, BUFLEN);
printf("%s\n", file_name);
// Code for writing to file.
}
}
一些细节:
此函数不是尝试 return(指向)内存,而是传递写入的缓冲区。由调用者确保缓冲区足够大(这里总是如此,但如果实际文件名更长,您应该添加逻辑来检查 snprintf
的 return 值并执行适当的错误处理)。
该函数的实际逻辑只需要调用一次 snprintf
,它已经执行了您需要的所有操作,因此不清楚是否需要单独的函数或有帮助。
上面使用了variable-length数组。如果要确保恒定缓冲区,可以使用 #define
而不是缓冲区长度的 const size_t
变量。不过这里用variable-length数组就可以了,有的编译器甚至会把它转成常量数组
如评论中所述,您 (a) 阅读并理解所用函数的文档,以及 (b) 阅读并理解编译器错误消息,这一点很重要。
你的代码有几个问题,但最大的一个是你试图 return 一个指向来自 get_file_name
.
的局部变量的指针
这是一个很大的禁忌,因为在 get_file_name
中为 char s1[100]
分配的内存在 return
之后立即释放。
其余错误是因为您忘记了 char get_file_name(int k)
中的 *
。
有几种可能的解决方案:
- 传入一个
char
数组供函数填充。
- 使用全局变量(这被认为是一种不好的做法)。
- 动态分配内存。
- 将局部变量设为静态(这有点 hacky,但合法)
你的错误很容易解释:
get_file_name
应该 return 一个 char
但你创建了一个 char[]
和 return 这个(它与 char*
相同)
get_file_name
returns 在函数本身中创建的数组的地址。函数结束后,数组可能会被覆盖。添加数组作为参数或使用 malloc
strcpy
不起作用,因为它需要 char*
(char[]
) 而不是 char
。 get_file_name
return 一个 char
.
print_results_to_file
未定义。您可能需要包含您在程序中使用的其他文件(例如,如果函数是在文件 func.c
中实现的,原型应该位于通过 #include "func.h"
包含的名为 func.h
的文件中。
我想将数据存储在不同的文件中。因此我想按如下方式创建文件:data_1.log
、data_2.log
、...、data_N.log
。附录 .log
不是必需的,但会很好。到目前为止,我所有的方法都失败了。这是一个可能接近我需要的示例:
#include <stdio.h>
#include <string.h>
char get_file_name(int k){
int i, j;
char s1[100] = "logs/data_";
char s2[100];
snprintf(s2, 100, "%d", k);
for(i = 0; s1[i] != '[=10=]'; ++i);
for(j = 0; s2[j] != '[=10=]'; ++j, ++i){
s1[i] = s2[j];
}
s1[i] = '[=10=]';
return s1;
}
int main(){
char file_name[100];
for(int k=0; k<10; k++){
// Get data
// ...
// Create filename
strcpy(file_name, get_file_name(k));
printf("%s", file_name);
// fp = fopen(file_name, "w+");
// Write data to file
// print_results_to_file();
// fclose(fp);
}
return 0;
}
目前我收到以下我不理解的错误:
string.c: In function ‘get_file_name’:
string.c:14:12: warning: returning ‘char *’ from a function with return type ‘char’ makes integer from pointer without a cast [-Wint-conversion]
return s1;
^~
string.c:14:12: warning: function returns address of local variable [-Wreturn-local-addr]
string.c: In function ‘main’:
string.c:24:27: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(file_name, get_file_name(k));
^~~~~~~~~~~~~~~~
In file included from string.c:2:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
有没有更简单的方法来创建这样的文件名?真不敢相信没有。
函数 get_file_name
具有 return 类型 char
char get_file_name(int k){
但它 return 是 char *
char s1[100] = "logs/data_";
//...
return s1;
此外,returned 指针指向一个本地数组 s1
,该数组在退出函数后将不存在。
在本次通话中
strcpy(file_name, get_file_name(k));
第二个参数的类型(根据函数 get_file_name
声明为 char
)应为 char *
.
既没有函数 print_results_to_file
声明也没有它的定义。
根据 C 标准,不带参数的函数 main 应声明为
int main( void )
我会按以下方式编写函数 get_file_name
#include <stdio.h>
#include <string.h>
char * get_file_name( char *file_name, size_t n, size_t padding )
{
const char *common_part = "logs/data_";
snprintf( file_name, n, "%s%zu", common_part, padding );
return file_name;
}
int main( void )
{
enum { N = 100 };
char file_name[N];
for ( size_t i = 0; i < 10; i++ ) puts( get_file_name( file_name, N, i ) );
}
程序输出为
logs/data_0
logs/data_1
logs/data_2
logs/data_3
logs/data_4
logs/data_5
logs/data_6
logs/data_7
logs/data_8
logs/data_9
此代码存在各种问题,这里不一一纠正,而是另一种方法。它不是唯一的,但它很简单,应该易于理解和适应:
#include <stdio.h>
void get_file_name(int k, char* buffer, size_t buflen) {
snprintf(buffer, buflen, "logs/data_%d.log", k);
}
int main() {
const size_t BUFLEN = 50;
char file_name[BUFLEN];
for (int i = 0; i < 10; i++) {
get_file_name(i, file_name, BUFLEN);
printf("%s\n", file_name);
// Code for writing to file.
}
}
一些细节:
此函数不是尝试 return(指向)内存,而是传递写入的缓冲区。由调用者确保缓冲区足够大(这里总是如此,但如果实际文件名更长,您应该添加逻辑来检查
snprintf
的 return 值并执行适当的错误处理)。该函数的实际逻辑只需要调用一次
snprintf
,它已经执行了您需要的所有操作,因此不清楚是否需要单独的函数或有帮助。上面使用了variable-length数组。如果要确保恒定缓冲区,可以使用
#define
而不是缓冲区长度的const size_t
变量。不过这里用variable-length数组就可以了,有的编译器甚至会把它转成常量数组
如评论中所述,您 (a) 阅读并理解所用函数的文档,以及 (b) 阅读并理解编译器错误消息,这一点很重要。
你的代码有几个问题,但最大的一个是你试图 return 一个指向来自 get_file_name
.
这是一个很大的禁忌,因为在 get_file_name
中为 char s1[100]
分配的内存在 return
之后立即释放。
其余错误是因为您忘记了 char get_file_name(int k)
中的 *
。
有几种可能的解决方案:
- 传入一个
char
数组供函数填充。 - 使用全局变量(这被认为是一种不好的做法)。
- 动态分配内存。
- 将局部变量设为静态(这有点 hacky,但合法)
你的错误很容易解释:
get_file_name
应该 return 一个 char
但你创建了一个 char[]
和 return 这个(它与 char*
相同)
get_file_name
returns 在函数本身中创建的数组的地址。函数结束后,数组可能会被覆盖。添加数组作为参数或使用 malloc
strcpy
不起作用,因为它需要 char*
(char[]
) 而不是 char
。 get_file_name
return 一个 char
.
print_results_to_file
未定义。您可能需要包含您在程序中使用的其他文件(例如,如果函数是在文件 func.c
中实现的,原型应该位于通过 #include "func.h"
包含的名为 func.h
的文件中。